前スレ続き 1000 名前:デフォルトの名無しさん[sage] 投稿日:2009/06/30(火) 15:17:35 char **ppCharx[] = {ppChar1, ppChar2, ppChar3}; ↓ char **ppCharx[3] = {ppChar1, ppChar2, ppChar3}; これでだめなの?
#include <stdio.h>
int main(void)
{
char *ppChar1[] = {"abc", "def", "ghi", NULL};
char *ppChar2[] = {"jkl", "mno", NULL};
char *ppChar3[] = {NULL};
char ***pppChar, **ppChary;
char **ppChar[3] = {ppChar1, ppChar2, ppChar3};
for (pppChar = ppChar; *pppChar != NULL; pppChar++) {
for (ppChary = *pppChar; *ppChary != NULL; ppChary++)
printf("%s ", *ppChary);
printf("\n");
}
return 0;
}
エラー E2063 strstr2.c 11: 不正な初期化(関数 main )
>>2 []でも[3]でも同じエラーです
char **ppChar[3] = {&ppChar1, &ppChar2, &ppChar3};
>>4 エラー E2063 strstr2.c 11: 不正な初期化(関数 main )
警告 W8075 strstr2.c 11: 問題のあるポインタの変換(関数 main )
警告 W8075 strstr2.c 11: 問題のあるポインタの変換(関数 main )
char **ppChar[3] = {&ppChar1[0], &ppChar2[0], &ppChar3[0]};
>>6 エラー E2063 strstr2.c 11: 不正な初期化(関数 main )
根本的に何やってもだめだと思いますよ
E2063 不正な初期化 コンパイルエラー 初期化は,次のいずれかによって行わなければなりません。 定数式 グローバルな extern あるいは static 変数のアドレスに定数を加えた(あるいは引いた)もの
つまりmainの中でするなということ?
>>2 >>4 >>6 本質的に判っていないのに無理に回答しなくてもいいと思います。
>>5 そのコンパイラは何? 手元のgccではc89準拠モードでもc++準拠モードでもc99準拠モードでもエラーにならないのだが。
いやローカル変数のアドレスを使って他のローカル変数の初期化を するなという事
13 :
10 :2009/06/30(火) 15:47:39
訂正。 件のコードをc89準拠で-pedanticオプションつけたら警告が出た。 曰く、initializer element is not computable at load timeということなので、 古いcではダメと言うことらしい。
>>10 CodeGear C++ 6.1.3(最新版)
確かにgcc4.4.0だと通りますね
こりゃコンパイラのバグかな?
バグじゃないようですね C89では正しい動作のようでした 安心しました
古いのは何で認めてないんだろ
>>16 というか記憶では今まで出来た試しがないのでエラーが出て
当然だと思っていた
18 :
10 :2009/06/30(火) 15:58:54
// 自分自身ではstaticに置くし、vcなんて使わんから気づかんかった。正直すまんかった。 #include <stdio.h> int main() { static char * firstStrings[] = {"abc", "def", "ghi", NULL}; static char * secondStrings[] = {"jkl", "mno", NULL}; char ** stringArrays[] = {firstStrings, secondStrings, NULL}; int i; for (i = 0; stringArrays[i] != NULL; ++i) { int j; for (j = 0; stringArrays[i][j] != NULL; ++j) { int k; for (k = 0; stringArrays[i][j][k] != '\0'; ++k) { putchar(stringArrays[i][j][k]); }}} { char *** p; for (p = stringArrays; * p != NULL; ++p) { char ** q; for (q = * p; * q != NULL; ++q) { char * r; for (r = * q; * r != '\0'; ++r) { putchar(* r); }}}} return 0; }
#include <stdio.h> int main(void) { char *ppChar1[] = { "abc", "def", "ghi", NULL }; char *ppChar2[] = { "jkl", "mno", NULL }; char *ppChar3[] = { NULL }; char **ppChar[] = { ppChar1, ppChar2, ppChar3, NULL }; char ***pppChar, **ppCharx; for ( pppChar = ppChar; *pppChar != NULL; pppChar++ ) { for ( ppCharx = *pppChar; *ppCharx != NULL; ppCharx++ ) { printf( "%s ", *ppCharx ); } printf("\n"); } return 0; } ふとぅーに動きますよ? エラーもでないし。んー質問の意図がわからにゅ。
>>19 だからね、古いc(c89)ではエラーになるのよ。
具体的には、vc++のcコンパイラはc89準拠でしかないからエラーになるってこと。わかった?
>>20 VC2008++だけど、エラーでないよ?
あ、VC++2008だね。ちなみにstandard sp1。 Expressとかではエラーでるのかな?
昨日の '0' <= c && c <= '9' の話。 Cの原典K&Rには、こう書いてあったと言う話があったけど、 じゃあと思って、C++の原典『プログラミング言語C++』を パラパラと見たら、0 <= x && x <= 10 というのがあった。 一緒に x >= 0 && x <= 10 という例もあったけど。
>>22 試してないけど、Cとしてコンパイルしつつ、拡張を無効にしたらエラーになるかもしれないね。
エラーにすることがどうしてもできない場合はちょっとがっかりするね
(intを32ビットとして) int n = -2147483648; じゃなくて int n = -2147483647-1; って書かないといけない理由は何ですか
26 :
デフォルトの名無しさん :2009/06/30(火) 21:40:53
言語拡張を無効にする(/Za)でエラー。
28 :
デフォルトの名無しさん :2009/06/30(火) 21:45:15
>>25 標準Cライブラリの実装本に書いてあったけど、話が細かすぎる。
とりあえず、-2147483648 なんて定数を直接使うのが間違っている。
#include <limits.h> の INT_MIN を使えばよい。
>>28 いや、そのINT_MINがこうやって#defineされてるだろ
理由を昔聞いたのに思い出せなくて気持ち悪いんだ
そんな事は無い 処理系依存
printf("%p",$hoge); %pとはなんでしょうか?
それC言語じゃないからその言語のスレで聞け Cのprintfではポインタ用のフォーマットだが同じとは限らん
>>29 要するに一の補数系か二の補数系かっていう違いじゃないの?
-1してるって事は二の補数系だから一の補数系からの移植って
可能性も高いね
>>26 おぉ、なった!
char **ppChar[] = { ppChar1, ppChar2, ppChar3, NULL };
これができるのは独自拡張のおかげなんだね。
んー勉強になる。
2147483648 という数値はオーバーフローするから記述できない ってことか
intに収まらなけりゃunsigned intになるだけだから問題ない
というわけで、-2147483648はlong型だから、INT_MINとしてふさわしくない。
俺の持ってるdinkumwareのヘッダーにも #define LONG_MIN (-2147483647L-1) /* minimum signed long value */ と書いてあった 考えると不思議だな
40 :
デフォルトの名無しさん :2009/07/01(水) 00:26:06
配列の中の最大の数を求める関数を作ったはずなんだけど、物凄い大きな値が返される‥。 どなたかわかりませんか? int max_number(int array[]) { int max; int c = 0; max = array[0]; for(c = 0;; ++c){ if(array[c] == '\0') break; if(array[c] >= max) max = array[c]; } return (max); }
>>40 配列の中身の最後が 0 になっていないと思う
42 :
デフォルトの名無しさん :2009/07/01(水) 00:29:41
>41さん あっ‥‥!文字列と勘違いしてたってことですかね!?
配列のサイズも引数にしてそこまでfor文で回すようにした方が安全 あと'\0'が終わりを意味するのはC言語での文字列のお約束事
>43 それは文字の話であって数字として扱う場合は0もありえるのでだめでしょ
俺の理解力が足りないからなんだと思うが
>>44 の言いたいことが分からない
'\0'の値は0だよということを
>>40 に言えば済んだ話だよな
たった2行すらもまともに読めないアホが、 人になにかを教えられると思えるのが2chのいいところだな。
48 :
デフォルトの名無しさん :2009/07/01(水) 04:58:08
#include <stdio.h> #include <stdlib.h> int main(void) { int *p1; if((p1 = malloc(sizeof(int))) != NULL) { *p1=10; printf("p1の内容は%d",*p1); } else { printf("メモリを確保できませんでした。"); } return 0; } エラーが出ます。何かおかしいでしょうか。 (7) : error C2440: '=' : 'void *' から 'int *' に変換できません。
Cとしてコンパイルしろ
初心者の僕は、最初にどのようなソフトを作る事を目標にすればよいのでしょうか?
>>48 p1 = (int *)malloc
C++ではキャストしないといけない
Cだとしなくてもいい
>>51 いずれにしても、(char*)はないな。
Cなら必要ないし、C++ならreinterpret_castを使うべきだ。
54 :
デフォルトの名無しさん :2009/07/01(水) 09:57:00
そもそもc++でmallocはないだろ。 何故newをつかわないの?
>>54 C++を使ってCコード書いてもいいじゃん
>>53 スレチだけどstatic_castじゃないの?
えっ
>>56 static_castを使ってコンパイル通るかやってみ
>>59 だから実際にコンパイルしてみろと言っている
#include <iostream> #include <cstdlib> int main() { char* p = static_cast<char*>(std::malloc(sizeof(char) * 10)); } 普通に通るけど?
>>60 いま手元にVCしかなくて
帰ったらgccでも試してみるよ
通るのが普通だと思ってた
void*を他のポインタに変換するのは問題なさそうだね 関数ポインタとかだったらreinterpret_castじゃないとエラー出そうだけど
通らないはずがない。 % cat > a.cpp #include <iostream> #include <cstdlib> int main() { char* p = static_cast<char*>(std::malloc(sizeof(char) * 10)); } % g++ -Wall a.cpp a.cpp: In function `int main()': a.cpp:6: 警告: unused variable 'p'
66 :
デフォルトの名無しさん :2009/07/01(水) 12:26:42
なんか普通に通ってるよね。 ひょっとしてCだとstatic_castは通らないと言いたいのかも?
MSDNのコラム読んだらvoid*からの変換はreinterpret_castが推奨になってるな static_castは危険だからなるべく使うなってことらしい 出来るだけstatic_castを使うようにしてた orz スレチすまんかった
>>51 ありがとうございました。
ほかの方も勉強になります。
69 :
デフォルトの名無しさん :2009/07/01(水) 16:07:28
bmp画像でこう、○ッキーみたいに丸が3つある画像を作りたいんですけど どうしても丸が右上4分の1の扇形になってしまいます。 ここが違うのだと思うのですがぱっと見違うところはありますでしょうか。 ここだけ見せられても困るかもしれないですが…。 void circle(int x0,int y0,int r0,int r,int g,int b) { int i,j; for(i=y0;i<=MS-1;i++) { for(j=x0;j<=MS-1;j++) { if(((j-x0)*(j-x0))+((i-y0)*(i-y0))<=r0*r0) { bmp[i][j][0]=b; bmp[i][j][1]=g; bmp[i][j][2]=r; } } } }
インデントのないソースは見てもらえないことになったらしいぞ
ベッキーの穴が3つ見えるエロ画像だと!? なんでループ変数にi,jを使って解り難くするのか、は置いといても >if(((j-x0)*(j-x0))+((i-y0)*(i-y0))<=r0*r0) こんなことするから何処が原点だか解らなくなるんだろ。
72 :
デフォルトの名無しさん :2009/07/01(水) 16:35:32
>>70 そうなんですか!
>>71 ちょww
括弧ばっかでわかりづらいですか…。
>>69 円内かどうかの判定部分に関して:
i, j の範囲が 円中心に対して正のほうしか振っていないから当然 1/4の扇にしかならない
代入用の範囲 と 円判定の範囲(+渡された半径との関係) とをどうしたいのか整理せよ
A) 被代入側の空間 (0..N , 0..M) B) 中心 x0, y0 半径 r を囲む矩形 (x0-r..x0+r, y0-r..y0+r) この2つの矩形の重なっている部分に対して 円内判定すればよい
円を描く場合は座標系を理解してないとなあ 扇しかかけてないってことは誰かが言ってるように原点を中心にX,Yを正にしかみてない X・・・正 Y・・・正 X・・・正 Y・・・負 X・・・負 Y・・・正 X・・・負 Y・・・負 この4つを組み合わせて初めて円になる
>>69 適当に答える
for(i=1-MS;i<=MS-1;i++)
{
for(j=1-MS;j<=MS-1;j++)
にすればいいんじゃない
ん? i, j って投影後の座標空間なのか? (0..MS-1, 0..MS-1) 全表示空間を総なめして 円内かどうかの判定してるなら 中心基準での座標系は x' = i-x0, y' = j-y0 になって、結果その記述であってるが… bmp[][] の周辺から実際に可視化する作業の過程で間違ってないか?
int lo = max(x0 - r0, 0); int hi = min(x0 + r0, MS -1); for (i = lo; i <= hi; ++i)
79 :
デフォルトの名無しさん :2009/07/01(水) 17:04:25
正の部分しか表せていなかったから扇になってしまったのですか。
なぜなのか謎だったのでわかってよかったです。
ありがとうございました。
>>76 やってみたらできました。ありがとうございます!
>>79 それはそれで 頭の中が整理できていないから 後々変なことを引き起こすかもよ。
x0, y0, r と 内部のループの i,j の関係は?
修正後のコードだと i,j は円を中心にした座標を意味したことになるので、ぶっちゃけx0,y0 の存在が無駄になる
i,j と bmp[][] の関係は?
今の修正後のコードだと 負の値渡るけど?
>>67 reinterpret_castよりもstatic_castの方が危険ってなんでなんだろうね
83 :
82 :2009/07/01(水) 18:32:59
あれえ! 暗黙の型変換が行えない場合でも半ば強制的にキャストを行う場合にreinterpret_castだと思ってた俺バカス さ、、あちこち書き直すかorz
reinterpret_castならポインタを読み替えるだけだけど static_castで変な型変換されたらマズイじゃないか
氏名(char型配列)、住所(char型配列)、年齢(int型)を要素に持つ構造体配列をリスト構造で繋ぎたいと思っています。 動作としては単方向リストで、 list->name list->adr list->age をキーボードからscanfで入力し、最後を list->next = (str) calloc(1, sizeof(str)) として、先頭アドレスを返す。 続けて入力するのであれば、list=list->nextをした上で最初から繰り返すといった具合です。 プログラム自体は完成していて、ageまでは入力できました。 しかし、callocを行うと既に入力されている変数がバグってしまいます。 例:calloc直前までnameには「ABC DEF」と入っていたが、calloc直後にprintfすると、中身はゴミになっている。 デバッガーで見てみても、callocを境に正常に入力された値が"Old Value"扱いとなっており、 "New Value"に意味不明な文字列が代入されているのが見れました。 list->next = (str) calloc(1, sizeof(str)) をしただけなら直接的に弄ったのはlist構造体のnextだけで、nameやadrは弄っていないと思っていたのですが、 違うのでしょうか? これを回避するにはどうしたらよいのでしょうか? 本当に、この一文を前後に入力した値がぶっ壊れていて、どうして?といった疑問で一杯です・・・。 宜しくお願いします。
strって構造体の名称?
キャストの仕方を見ていると str って構造体のポインタ じゃねーかな? sizeof(str) は 結局 sizeof(void *) と同じ意で ポインタを保持するための大きさ でしかなく 構造体の本体の器のサイズを得るのは sizeof(構造体名) とでもしないとまずいのでは?
(str) calloc(1, sizeof(str)) あやしい。 (str *) calloc(1, sizeof(str)) じゃないとすると、 typdef struct foo *str; されている可能性が高い。
× list->next = (str) calloc(1, sizeof(str)) ○ list->next = (str) calloc(1, sizeof(*list->next)) ポインタと実体の違いがわかっていない状態で calloc, malloc 使用した線形リストはヤバイね
strはtypedef struct str* str; をした上で名称でした。 link->next=(struct str*) calloc(1,sizeof(struct str*)); となっていると思います。 ヘッダファイルを分けていたため、typedefしたことを忘れていました・・・申し訳ありません。
typedef struct str* STR; とかわかりやしのにしろ
92 :
デフォルトの名無しさん :2009/07/01(水) 19:20:41
>91 どのようにわかりやすいのか、理解できない
link->next=(struct str*) calloc(1,sizeof(struct str)); こうだ 元のままだと構造体をさすポインタを確保しててそもそもやろうとしてることになってない
>>92 元と同じ名前にするなってことだろ
元を連想しやすい別名にしろと
reinterpret_castはビットを再解釈するだけなのだ。 static_castはビットを型にあわせて書き換えるのだ。 だから、void*の機能を考えるとreinterpret_castの方が自然なのだ。
でもやっぱりstatic_castを使うべきだと思うのだ。 static_castは環境やコンパイラによって異なる可能性のあるビット列を ちゃんと環境に合うように変換する。何も「仮定」しない。 コンパイラが決められたルールを守ってビット列を変換する。 void*を経由した型変換でもやっぱりstatic_castを使うべきだと思っちゃうのだ。
ちなみに、詳しくはC++ Coding Standards p.177
>>96 経由じゃなくて元からvoid *の場合は?例えばmallocの戻り値。
C言語に限らない話になってしまうのですが質問があります。 フリーソフトなどを公開しているHPで、WindowsXP Visual Studio2005でコンパイル Windows2000 Visual Stdio2005でコンパイルと書いた ものが存在したのですが、同じVisual Studio2005でもOSが違えばコンパイル後の実行バイナリは違った物が作成されるのでしょうか? また、もし違ったものが作成されるのであれば、Windows2000,XP,Vistaなどで使う場合使うOSを同じ環境でコンパイルされた物の方が良いのでしょうか?
同じOSでコンパイルしても、時刻とかが入るから同じバイナリにはならない。 で、質問の答えだけど、コンパイルした環境以外で動くことは保証されない。 ただし、Windowsや一般のOSの場合、後方互換性を持つ場合が多いので 一番古いOS(Win2K)でコンパイルすれば、それ以降のOSで動くことは多い。
>>98 void*と他のポインタ型は相互変換が規格で保障されているので、
規格に合致したC++コンパイラなら、どちらを使っても結果は必ずいっしょ。
一緒でないとウンコ。そして、それでもやはりstatic_cast。
最近のコンパイラはかなり最適化してくれるのね。 レジスタ変数とかを用いて処理速度を比べたりしたけど、あんまり違いが出なかったorz
>>99 2000とXPではモジュールの検索順が違うので、システムにあるものとローカルにあるCRTのバージョンが違ったりすると、リンカが違うバイナリを作成する。
それでも別に問題なく動作はするがな。
>>103 PC向けだとそこまで気を使う必要はないと思うけど・・・
>>100 ,103,104
ありがとうございます。
皆さんに色々と情報を頂けたので少し自分で調べてみたいと思います。
また、からないことが出てくるとは思いますが、そのときはよろしくお願いします。
>>103 レジスタ割り当ての最適化なんてのはコンパイラ設計の初歩中の初歩なので、
コンパイラは人間が指定したレジスタ割り当てなんて採用しません。
知識として覚えるのは悪くないと思う ループの最適化やレジスタ周りは覚えておいて損はない
#include <stdio.h> double power(double dx, int no) { double tmp = 1.0; while (no-- > 0) tmp *= dx; return(tmp); } int main(void) { int n; double x; printf("実数を入力してください:"); scanf("%1f", &x); printf("整数を入力してください:"); scanf("%d", &n); printf("%.2fの%d乗は%.2fです。\n", x, n, power(x, n)); return(0); } これを実行しても0.00の4096乗は0.00とかなるんだが どこが間違ってるのか全く分かんない。 関数難しいよ
%1f
>>109 1とl(エルの小文字)を見間違えたんだね
×%1f ○%lf だな
ありがとう助かった しかしなんて恥ずかしいミスだw
恥をかいたら恥をかかないようにしようと思うから、それが成長に繋がるよ。
しかしまあ 2chでのミスって、 実生活には何の影響もないから 実質的には恥じゃないよな。 逆に言えば空気読まないこと言って たたかれたとしても 別に忘れ去ってしまえるわけで、 それが2chのいいところであり悪いところ。 ・・・っとどうでもいい話を書いてしまった。
えっ
STLのことで質問があるのですがqueueやstackを使っていて、 そのコンテナの中身を全削除したいときってどうすればよいのでしょうか? clear()がないらしいですが、代わりの方法ってあるのでしょうか? ループでpop()をするのは効率が悪いように思うのですが、clear()が用意されていない理由がわかりません。
スレ違い
_*_*_*_ __*_*__ ___*___ と数字を入力すると表示されるプログラムをfor文で作りたいのですが、 左右の三角形で分けて表示するプログラムはどのようにすればいいのでしょうか? "_"の部分は空白で表示したいと思っています。上の図は数字を3と入力した時の例です。
int i, j, n; scanf("%d", &n); for(i=0; i<n; i++) { for(j=0; j<i; j++) putchar(' '); for(j=n; j>i; j--) printf(" *"); putchar('\n'); }
意味がわからん>左右の三角形で分けて
>>122 _*_* _*_
__*_ *__
___* ___
にしたかったのですが、そのまま
_*_*_*_
__*_*__
___*___
と表示されるように組むほうが楽のようですね。
>>121 を入れてみたらずっと*が流れてしまいます・・・。
たとえば5段はこれでいいのか? _*_*_*_*_*_ __*_*_*_*__ ___*_*_*___ ____*_*____ _____*_____ 中を空白にしたいとか言われるとめんどくさい _*_*_*_*_*_ __*_____*__ ___*___*___ ____*_*____ _____*_____
1行を左と中と右にわけて考えればいいんじゃね 左空白: 空白が1個ずつ増えていく 中の星: ”*_”の2文字の繰り返し。その2文字の表示回数が減っていく 右空白: 基本的に左と同じ、ただし空白が1個少ない
for(i = 0; i < n; ++i) { for(j = 0; j < n * 2; ++j) putchar((i+j)%2 ? i <= j ? n * 2 - i >= j ? '*' : ' ' : ' ' : ' '); putchar('\n'); }
マクロのputcharの引数に、そんな複雑なものを入れるのは、よろしくない作法。
うるせえ
putchar()って関数じゃなくてマクロなの?
>>130 #define putchar(c) putc(c, stdout)
(putchar)(c)と呼んどけ。
それはきもい
>>131 putcも普通はマクロ。
明示的に関数を使いたかったら、fputc(c, stdout) とする
C99なら(putchar)(c)でいいお
なんだかんだといって、標準ライブラリはマクロ多用してんだよね。
マクロだけでプログラミングできるの?
マクロも最終的には関数なりに置き換えられる
これをマクローリン展開という
テイラー展開は?ねえテイラー展開は?
143 :
デフォルトの名無しさん :2009/07/04(土) 23:46:04
質問です。 111,222,333 のような、カンマ区切りの1000万行のcsvデータを読み込み、 配列に格納するのに、最も早い方法を教えてください。 私は while ((fgets(buff,100,fp)) != NULL){ sscanf_s(buff,"%d,%d,%d",&x,&y,&z); xx[i]=x; yy[i]=y; zz[i]=z; i++; } としています。 宜しくお願いします。
前提・条件がよくわからんがとりあえず sscanf(buff, "%d,%d,%d", &xx[i], &yy[i], &zz[i]);
printf, scanf系はとにかく遅い
桁数が3桁ずつ固定なら、whileの中身を
xx[i] = atoi(buff);
yy[i] = atoi(buff+4);
zz[i] = atoi(buff+8);
++i;
とでもした方が速い
>>143 本気で質問してるなら環境とか入力フォーマットもっと詳しく書け
146 :
デフォルトの名無しさん :2009/07/05(日) 06:32:03
>>144 >>145 すいません、本気です。大学でサンプリング512Hz、24時間、7項目、
合計22,118,400行のデータを測定しています。
使用環境はvc2008 MFCpro SDI です。データは6桁で最初1項目が整数、
残り5項目が実数で、カンマ区切りのcsvファイルです。
整数,実数,実数,実数,実数,実数,実数
このうち使用したいのが、1項目と、4,5,6項目目です。
データは4パケットひとかたまりです。
0,0,0,0,0,0,0
0,1,1,0,0,0,1
0,2,2,0,0,0,2
0,3,3,0,0,0,3
1,4,4,1,1,1,4
1,5,5,1,1,1,5
1,6,6,1,1,1,6
1,7,7,1,1,1,7
2,8,8,2,2,2,8
2,9,9,2,2,2,9
2,10,10,2,2,2,10
2,11,11,2,2,2,11
試したのは、行数を取得してから配列に格納する方法です。アドバイス宜しくお願いします。
147 :
デフォルトの名無しさん :2009/07/05(日) 06:33:56
FILE *fp; int pake0,pake2,i=0,lineCount=0; float x,y,z,*xp,*yp,*zp; char buff[100],filename[9]="test.csv"; if ((fp = fopen(filename,"r")) == NULL){return;} while ((fgets(buff,100,fp)) != NULL){ //行数のカウント sscanf_s (buff,"%d,%*f,%*f,%*f,%*f,%*f,%*f,",pake1); if(pake1 != pake0){ pake0 = pake1; lineCount++;} fclose(fp); px = (float *)malloc(sizeof(float) * lineCount); //メモリ確保 py = (float *)malloc(sizeof(float) * lineCount); pz = (float *)malloc(sizeof(float) * lineCount); if ((fp = fopen(filename,"r")) == NULL){return;} while ((fgets(buff,100,fp)) != NULL){ //ファイルの読み込み sscanf_s (buff,"%d,%*f,%*f,%f,%f,%f,%*f",pake1,&x,&y,&z); if(pake1 != pake0){ pake0 = pake1; px[i] = x; py[i] = y; pz[i] = z; i++; }} fclose(fp);
あほか。誰も動的メモリの獲得方法なんか聞いてないだろうが
って本人か。
テキストファイルを読む以上、多少のオーバーヘッドは仕方ない。
scanfにしても自分で文字列操作するよりは、たいてい速い。
やるなら
>>144 ぐらい。
そのソースなら、まずは2回読まないようにするのがいい
最大サイズが予想できるなら lineCount を定数にしてもいいし、
溢れそうなときに reallocで倍々に増やす方法もある。
全部読み込んでからじゃないとデータ処理できない内容なの?
そのテキストを誰が作っていつ読み込む必要があるのか知らんが どっかのタイミングで必要なデータだけテキスト解析の必要ないバイナリにでも変換しておくのがいいんじゃないか
152 :
デフォルトの名無しさん :2009/07/05(日) 10:28:06
>>146 はじめからバイナリ(配列格納形式)にして一度に読めよ・
昔はsetvbuf()でバッファを大きくするだけで速くなった。 今でも有効かどうかは知らんけど。
154 :
デフォルトの名無しさん :2009/07/05(日) 11:52:01
>>146 読み込み部分をいくら弄っても、ファイルIOがボトルネックになっててあまり変わらないんじゃないかな。
SSDやRAMディスクなど、速いディスクに置くのが手っ取り早いとおもう。
あとはデータを複数台に分散させて処理とかかな。
エスパーwww
156 :
デフォルトの名無しさん :2009/07/05(日) 17:31:43
Strtok(string," \n")で文字列を抽出しているのですが、どうも最後の改行が残っているようです。 どうしたらいいですか?
157 :
デフォルトの名無しさん :2009/07/05(日) 17:41:32
質問を変えます! 文字列の最後に何か入ってますよね? あれってどうやったら認識しないように出来ますか? if(string[n]!=0){ みたいにして、文字ごとに操作をしているのですが、最後の文字を認識してしまうのです。
最後に入ってるのって'\0'のこと? それならそのコードでも別にいいようにおもうよ。 とは別に何か入ってるというのなら、改行コードがCRLFなんかね。
159 :
デフォルトの名無しさん :2009/07/05(日) 17:47:23
すいません、やっぱり改行を認識しているようです。
160 :
デフォルトの名無しさん :2009/07/05(日) 17:48:58
>>158 ありがとうございます。
やはり改行コードに問題があるんですね。
CRLFとはどういうことでしょうか?
ちょっとぐぐってみたところ、改行末だけじゃなく、
改行した後の頭にも何か文字が入っている方式、みたいな感じでしょうか?
161 :
デフォルトの名無しさん :2009/07/05(日) 17:50:49
CRLFで調べたらできました! CRLFっていうのは改行コードが二文字で出来てる奴のことを言うのですね。 ありがとうございました。
「改行コード」と呼ばれるものは歴史的な理由から環境ごとに異なってて WindowsだとCR+LF UNIX、LinuxなんかLF macだとCR というかんじ。 C言語だとCRが\rで表せて、LFが\nで表せるので、\nだけしか気にしていないと、\rが残るというお話。
あ、解決してたスマソ おつおめ
164 :
デフォルトの名無しさん :2009/07/05(日) 17:54:21
ありがとうございます。環境によって違うというわけでしたか。 うちはWindowsなので納得です。
ファイルの読み出しのときにバイナリドーモで呼び出すとCRLFに気を使わなくちゃいけないけど テキストモードで呼び出すなら\nに変換されるから問題ナッシングのはずよ。
正直どうやったらC言語扱えるようになりますかね?
文字が読めたら
混在してたらどうなんの?
爆発します。 そういうときはバイナリモードで読み込んで自前で処理するしかないわね。 C言語の場合、テキストモードとバイナリモードの違いは 単に'\n'を環境向けに書き換えるか書き換えないかだけだから。
>単に'\n'を環境向けに書き換えるか書き換えないかだけだから。 文字コードのEOFの扱いとかちょこちょこと違った気がする。 どうだっけ?
172 :
デフォルトの名無しさん :2009/07/05(日) 22:50:38
//
// 2007/3/15
// Lesson1: マップの作成と描画、キー入力とキャラの移動
// Movie:
http://fatalita.sakura.ne.jp/TubeRPG/ // HP:
http://fatalita.sakura.ne.jp/ //
#include <stdio.h>
#include <stdlib.h>
#define KEY_UP 'u'
#define KEY_DOWN 'd'
#define KEY_RIGHT 'r'
#define KEY_LEFT 'l'
#define MAP_SIZE_Y 10
#define MAP_SIZE_X 10
int x = 3, y = 4;
int map[100][100] = {
{1,1,1,1,1,1,1},
{1,0,0,3,0,0,1},
{1,0,0,0,0,0,1},
{1,0,2,0,2,0,1},
{1,0,0,0,0,0,1},
{1,1,1,1,1,1,1},
} ;
173 :
デフォルトの名無しさん :2009/07/05(日) 22:55:44
void DrawMap(){ int i,j; for ( j = 0; j < MAP_SIZE_Y; j++ ) { for ( i = 0; i < MAP_SIZE_X; i++ ) { if ( j == y && i == x ){ printf("勇"); } else { switch ( map[j][i] ){ default:printf(" "); break; case 1: printf("■"); break; case 2: printf("兵"); break; case 3: printf("王"); break; } } } printf("\n"); } }
>>172 長いソースならテキストでどこかにそのまま上げて
リンク貼った方がいいよ
175 :
デフォルトの名無しさん :2009/07/05(日) 22:59:30
void GetKey(){ switch ( getchar() ){ case KEY_UP: y--; break; //UP case KEY_DOWN: y++; break; //DOWN case KEY_LEFT: x--; break; //LEFT case KEY_RIGHT: x++; break; //RIGHT } } int main(void){ while (1) { system("clear"); puts("上:u, 右:r, 下:d, 左:l"); DrawMap(); GetKey(); } return 0; } 連発すまそ このRPGで階段にのぼったりする判定を作りたいんだけど。 なかなかうまくいかない。 どうすればいいかな? map[3][2]==jとかやっても無理っぽいんだが。 壁にぶつかったときそれ以上すすませないとか。
176 :
デフォルトの名無しさん :2009/07/05(日) 23:11:30
>>175 ゲームプログラマになる前に云々っていう本でもろ同じような題材扱ってたから、
それ読んだ方がいいと思うよ。
177 :
174 :2009/07/05(日) 23:13:49
その辺のロジックはやったことあるので回答してもいいんだけど 元のテキストであげてくれ インデント直したりとメンドクサイw
178 :
デフォルトの名無しさん :2009/07/05(日) 23:20:40
#include <stdio.h> void f(double x,double y,double z); double x,y,z; int main(void){ y=2.0; z=4.0; f(x,y,z); printf("%f",x); return 0; } void f(double x,double y,double z){ x=y*z; } 例えば↑のように main内で計算だけ(戻り値なしの)関数を呼び出して行いたいですけど ↑の記述だと0.000000となってしまいます どこがおかしいんでしょうか?
>>179 たとえば
f(x,y,z);
↓
x = f(y,z);
void f(double x,double y,double z){
x=y*z;
}
↓
double f(double y,double z){
return y*z;
}
とか
f(x,y,z);
↓
f(&x,y,z);
void f(double x,double y,double z){
x=y*z;
}
↓
void f(double* x,double y,double z){
*x = y * z;
}
>>175 GetKeyの中で勇者をとっとと移動してるけど、そこで壁かどうか判定すればいいよ
GetKeyの中でやるもんでも無いように思うけど。
ソースも自分でテキストに起こせないとか宿題スレ行け
>>179 つまり、名前の隠蔽だよ。
同じ名前を使うと、内側のスコープの名前によって
外側のスコープの名前は隠蔽される。
int x = 4;
{
int x = 2;
}
これが許されるのは内と外のxが別の変数とみなされるから。
結局何で叩かれたかわかってないままいなくなったか
>178 懐かしいな おじさんが昔4行程度しかないポケコンで作ってたRPGのままだわ
おじさんポケコンってなんですか?
昔、カシオのPB-110というポケコン持ってた もっぱらベーマガのリストを打ってただけだけど
ぐぐれw からかわれてるんだよ
ポケモンフラッシュ食らわせるぞ
でも今のゲームもグラフィックを除けば基本は
>>178 から進化してないんだよな
198 :
デフォルトの名無しさん :2009/07/06(月) 00:36:12
printf等の関数は、コンパイル時にEXEにそのまま組み込まれるのですか?
そういえば、Windows CEで動くCコンパイラとかってあるのかね。
>>198 スタティックリンクなら組み込まれる
ダイナミックリンクなら組み込まれない
201 :
デフォルトの名無しさん :2009/07/06(月) 00:45:38
>>200 スタティックリンクであった場合、バイナリを解析することでprintf関数が組み込まれている
ということを知ることはできますか?
ああ、なるほど。他人の書いたソースコードを無断で利用して それを実行コードから判別されないか知りたいのね? それなら判別できるし、訴訟を起こされるよ。 どっかのシューティングゲームみたいに。
ICOもやらかしてたな オプソのコードつかって
205 :
デフォルトの名無しさん :2009/07/06(月) 00:51:19
すいません プログラミング言語Cの演習1-12がよくわからないので質問させてください ab cd efのように入力した単語をスペースやタブなら改行して ab cd ef と出力させたいのですがうまくいきません。
206 :
デフォルトの名無しさん :2009/07/06(月) 00:52:40
コードは #include <stdio.h> int main(void) { int c; while((c = getchar()) != EOF){ if((c != ' ') || (c != '\t' )) putchar(c); else putchar('\n'); } return 0; } です。 これを実行すると ab cd ef ab cd ef のようになってしまいます どこが駄目なんでしょうか?
if((c != ' ') && (c != '\t' ))
209 :
デフォルトの名無しさん :2009/07/06(月) 01:06:00
>>207 ありがとうございます。
なぜ' 'では駄目なのでしょうか?
>>208 ありがとうございます!
完璧にうごきました
ですが、なぜボクのコードではうまくいかないのかわかりません
よろしければおしえてください
論理演算子の使い方が間違えているのでしょうか?
210 :
デフォルトの名無しさん :2009/07/06(月) 01:09:42
かつ と または の違い・・・ こんがらがってきた
if((c != ' ') || (c != '\t' )) をへんかんすると if(!((c == ' ') && (c == '\t' ))) となります CがスペースとTABに同時になることはありませんよね?
213 :
デフォルトの名無しさん :2009/07/06(月) 01:14:25
>>211 ありがとうございます。
理解できました。
これはプログラミング以前の問題でしたね
すいません
214 :
デフォルトの名無しさん :2009/07/06(月) 01:16:30
>>212 よく理解できました
本当にありがとうございます
ド・モルガンの定理じゃなくド・モルガンの法則だったかも
皆さんはエディタに何を使われているのですか? よろしければお教えください
エクセル
メモ帳
>>217-219 ありがとうございます
>>217 コンパイラはbolandなのですが
このエディタから直接呼び出したり出来るでしょうか?
次の条件を満たすプログラムを作りたいのですが どのようにすればいいのでしょうか? 1.コマンドプロンプトを表示する 2.キーボードからコマンドを文字列として入力する 3.入力した文字列を調べる 4.forkして子プロセスを作る 5.子プロセスで、3. で調べたコマンドを exec する 6.親プロセスは子プロセスの終了を待って、1. に戻る 使用環境はVineLinux4.2です。
>>221 その手順通りにすればいいのでは?
見たところ、抜けてるような手順はないし。
>>222 ありがとうございます。
execやforkの使い方が全く分からないのですが
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char comm[64];
//execvpを使ってGNOME端末を起動する
execvp("gnome-terminal");
//commandを入力する
printf("command> ");
scanf("%s", comm);
こうやって書いていってちゃんとexec出来ているのでしょうか?
forkしろよ。
手順通りに進めた方がいいと思うよ
forkはなあ…コードは簡単だけど、 その意味というか動作を理解するのが大変だったよ プロセスが複製されるって何?! しかも親と子が同じ位置から動作を続けるって何?! みたいな
プロセスを複製するなんて妙なアイデア誰が考えたんだろうな
228 :
デフォルトの名無しさん :2009/07/06(月) 12:47:09
ユーザーが値を入力する処理のとき、まず配列を多めに作っておきますが、 値が入力されたときに、その都度変数が作られるという処理は効率がよくないのでしょうか?
確かに最初見たときは面食らったな 単純だけど気持ち悪いんだよねw
>>228 一般論としては
あらかじめ配列確保⇒ ×メモリ効率 ○実行効率
そのつど配列を確保⇒ ○メモリ効率 ×実行効率
じゃね。まあ好きなようにすればいい
232 :
デフォルトの名無しさん :2009/07/06(月) 14:00:20
CGIについての質問です。
どうぞ。
234 :
デフォルトの名無しさん :2009/07/06(月) 15:39:09
ファイルロックをするとき、flockを使うのが一般的だと思うけど fopenしたファイルを操作している傍らで低レベル入出力を操作するのは どうにも美しくないと思うんだけど、どうなの? あとロックファイルが別に必要というのも美しくない。 fopenに歯痛ロックと共有ロックのオプションがあっても良かったと思うんだけど。
そのとおりだね MSのVCには _fsopen() なんてのがあるらしいな
>>234 どんな環境を想定して言っているのか知らぬけど
> ファイルロックをするとき、flockを使うのが一般的だと思うけど
入門書のレベルではね
> fopenしたファイルを操作している傍らで低レベル入出力を操作するのは
> どうにも美しくないと思うんだけど、どうなの?
> あとロックファイルが別に必要というのも美しくない。
> fopenに歯痛ロックと共有ロックのオプションがあっても良かったと思うんだけど。
Cで書かれた実用的なプログラムに美しさを求めてはいけない
美しいコードが必要ならスクリプト言語でも使ってろ
因みにオナニーするときは部屋のロックを掛けとけよ
美しいとか宗教論はどうでもいいけど 排他ロック付きfopen()があれば便利じゃん
先生!!俺はまりました!! for(i=1;i<1001;i+=2 for(j=1;j<(i/2);i+=2){ if(!(i%j)) break; . . . まさか i%1 が0なんて聞いてないんですが… どうすればこういう類のもの覚えられるんですか?
>>238 整数(正)を1で割ったあまりは常に0だろ
まあ j の値が増えなくて無限ループするところだったからよかったじゃないか。
がんばって素数を数えるんだ
243 :
デフォルトの名無しさん :2009/07/06(月) 23:12:50
LSIC試食版でこれ実行すると、配列7番目から変な値がすでに入っているんですが何ででしょうか? #include<stdio.h> #include<stdlib.h> main() { int nedan[17] ; /*nedan配列は0から16まで*/ int i ; for (i=0; i<17; i++) { printf("配列%d番目 %dの値を入力 \n",i,nedan[i]); scanf("%d",&nedan[i]); printf("配列%d番目の値は%dです \n",i,nedan[i]); } }
>>243 初期化していない局所変数に何かを期待しているのか?
初期化してないしそれにstdlibいるのか
>>244 初期化してないとこういう値が入ってるんですね。
そういえばそんな感じのことを聞いた覚えがあります。
>>245 参考にしていた書籍にはatoiを使って整数を取得する方法があったので、その名残です。
配列の要素に値を代入する方法を調べていたらscanfを見つけたのでそっちにしました。
回答どうもありがとうございました。
>>246 初期化してないと値は不定
今回のはたまたまであって今度実行したらまた変わる可能性は十分ある
>>246 >初期化してないとこういう値が入ってるんですね。
いや、正確に言えば入ってすらいない。
未定義の動作になる。
未定義の動作とは・・・めんどくさいから誰か教えてあげて。
249 :
248 :2009/07/06(月) 23:39:04
お皿を買って洗わずに使うのは非常に恐ろしいことだと、そういうことです。
俺、購入直後の食器類は煮沸消毒する
>>251 煮沸消毒をする鍋を煮沸消毒せねば・・・
ところで無限ループって怖くね?
食器を洗う時間を仕事に当てたと計算してみると紙皿を買ったほうが経済的という事実に私は気づいた。あれは高校二年の、草木の強く香る初夏ことであった
>>252 鍋も一緒に煮沸消毒されね?
マルチスレッドじゃね?
つまらん話題は伸びるな
じゃあ、つまる質問を。 freeの引数はvoid*型ですが、 じゃあだれがmalloc(calloc,realloc)した領域のサイズを管理しているのでしょうか。 くやしいです。
>>256 環境によるんじゃない?
malloc/freeともに中は環境に合わせて書き直されてるはずだし
とある環境のAPIが優秀なら単なるラッパーになってるだけかもしれないし
確保した領域を少しオーバーしたりアンダーしたアドレスをゼロに書き換えてみなよ わかるから
確保された領域の近くにその領域の終わりを指すポインタなり、ターミネータなりがおいてあって それをfree関数のランタイムコードが調べてるってことですかね。すごいな、考えた人。 やっぱりC言語はすごい。世界征服まであとちょっとだ。
printf("配列%d番目 %dの値を入力 \n",i,nedan[i]); ここでnedan[i]を表示してるけど初期化はされてないといわれてるんだけど理解してない?
264 :
デフォルトの名無しさん :2009/07/07(火) 09:12:06
>>260 そんなものはわからない。
Linuxとかだと、1mallocあたり4KBくらいずつ確保される。
(大きさによって確保の単位は変わる)
だからアドレス例外は4K+1B目じゃないと発生しない。
システムコールbrkとライブラリ関数mallocの違いを勉強しような
ヒープとかスタックとかレジスタの違いはなんなの? ヒープ→動的確保→遅い スタック→静的確保→早い レジスタ→よくわからん→すごい早い みたいなイメージなんだけどさ
>>266 微妙に間違っている。
そのキーワードでぐぐってみることをお勧め。
まぁ、Cがどうこうって話じゃないからスレ違いだね。
ヒープ:malloc()などで確保して使うメモリ領域。 スタック:自動変数の置かれる領域。 レジスタ:最適化によっていろいろ置かれるCPU内の領域。 スタックでも動的確保はできるし、そもそもヒープの振る舞いはOS次第。 まして、速度はCPU次第でヒープが遅いとは一概には言えず。 # 確保処理にコストが発生すると言えば言えなくはないが、大抵は無視できる程度。 レジスタの割り当てはコンパイラが最適化に従って勝手に行なうので、通常は意識する必要なし。 逆に最適化を禁止してしまうと(register宣言を無視してでも)スタックの使用が強制される場合もあり。 # そうでなければ、自動変数のアクセスにブレークポイントを置くことができない。
結構レジスタは意識するよ アーキテクチャから見えるレジスタだけでなく 物理レジスタのリネーミングまで考慮するのが一般的なCプログラマ
入門編で阿呆を垂れ流すのが勘弁。
271 :
デフォルトの名無しさん :2009/07/07(火) 21:01:06
Linuxネットワークプログラミング関係の書籍があまりに高く分厚いのですが、・・・ 何故ですか?
2000ページで15000円とかすんのかな
TCP/IPスタックを実装するところから始めてるとか
>>271 高いのは翻訳本ってことが原因かも。
分厚いのはしょうがない。薄い本より厚い本のほうがいいよ。
読みたいのは全部大学から借りてコピーするから値段意識したこと無いわ
友人から借りパクするのが法的にも安全
>>275 お金ができたら是非本を買ってくれ
良書だと思うものだけでいいから
よーしパパ次のボーナスでドラゴンブックの新版買っちゃうぞ
そういえば、ドラゴンブック買ったまま読んでなかったわ。
280 :
デフォルトの名無しさん :2009/07/07(火) 23:18:51
このスレに偉大なお方、団子さまはいますか?
団子はビット演算とこにいる印象だけど
C言語でCGIを作成しています。 クエリーパラメータを埋め込む際にパラメータが不要にエンコードされない、かつサイズをなるべく短くするために、 任意長のバイナリデータ(0x00含む)を62進(0-9a-zA-Z)で構成される文字列を作成する関数を作成したい。 (64進は何かしらの記号が入ってしまうため、避けます) ネットで検索しても多倍長整数が用意された環境のものでの変換は見つかりますが、 多倍長整数を使わない変換だと64進数など2^n進数のみの情報しか見つかりませんでした。 エンコード、デコード関数の合計のステップ数を400程度以内としたいため多倍長整数は導入しない方針としたいです。 最大64bit整数型まで使える環境です。 上記を満たすロジックの考え方のヒントが思いつく方は教えてください。(あくまでC言語でお願いします) こちらが考えている方法は、 エンコードは8バイトごとに11バイトのデータに変換していく方法です(データサイズは1.375倍)。 中身は余り(%)と商(/)を求めていくループを作成という一般的な?方法です。 8バイト未満となった場合は、適当に特殊処理を行います。
Base64でええやん
Base64は何かしらの記号なりが2文字分必要です。 その2文字がどのような実装でもエンコードされなければよいですが、 例えば、「_」(アンダースコア)などでもURLエンコードするブラウザがあります(AndroidのWebkit)。 不要にURLエンコードがクライアント側でされないようにしたいです。 (ブラウザによりURLエンコードされうる可能性を除外したいため、 0-9a-zA-Zのみであれば大丈夫だろうという判断をしています)
こまけえことはきにするな
プログラムからしても10進数のも62進数を扱うのも一緒なんだけどな あとBCDなんてのもあるし参考にしてみなよ
つーか、Base64が使えるならここで聞かないです。 すみませんが、Base62でお願いします。
さきほどBCDを確認しましたが、 演算子の%と/を使うかまたは、ビットのみの操作で出来る実装だと思いました。 演算子の%と/を使えるようにするためには整数型に変換する必要があると思っています。 ビット操作のみで62進化の方法は私には分かりません。
うるせえ馬鹿
多倍長整数を10進文字列に変換するのと同じアルゴリズムで出来るだろ。
BCDのヒント与えてわからないようではキツイよ 今要求してるのは2進化62進数でしょ?
>>292 そういうことでしょ
>エンコードは8バイトごとに11バイトのデータに変換していく方法です
0〜61つまり0〜63を一桁分にしてパックするかアンパックするかでしょ(1桁のうち2使わないだけで)
BCDが4ビットを10進数の一桁にしてるのに対して今回の仕様は 6ビットを62進数の一桁にするだけでしょ?
1.375倍ってなんかでかくね? それならBase64でよくね?
296 :
282 :2009/07/08(水) 01:29:57
>>294 2^6は64なので6ビットを62進数の一桁にするのは不可能かと。
>>291 2進化62進数とは、2進数を用いて62進を表すという意味だと解釈しています。
それではないと思っています。
任意のバイナリ(バイトで言うと256進)を62進文字列に変換したいのです。
ああ、サイズが問題なんじゃなくて、記号が入るのがいやなのか
298 :
282 :2009/07/08(水) 01:32:54
>>295 Base64より使用される文字が少なくなるため、
少し長くなってしまうのは仕方ないと考えています。
ZIPで潰して64かけろよ
要するにBase64のエンコードに使う最後の2が記号なのが納得いかないのか じゃあ自分でBase32でも作れば?Base16とか
そういや昔、バイナリデータを掲示板でやりとりするために生まれた形式が あったなぁと調べたが分からなかった。
302 :
282 :2009/07/08(水) 01:40:39
>>299 ありがとうございます。
クエリーパラメータで入れられるぐらいのサイズ(HTTPでは2000程度)なので、
車庫ファイルのサイズがバカにならないと考えています。
なので、Base62を作りたいと言ってるんでしょう。
0-9a-zA-Zで64進数にすりゃいいじゃん 0=0,1=1,...,W=58,X=59,YY=60,YYY=61,YYYY=62,Z=63みたいな
これダメだな Y0=60,Y1=61,Y2=62で
>>303 Base62の根拠はBase64のエンコードで使う62=+ 63=/を避けたいってことなんでしょ?
だから使える文字があまるようにBase32にすればいい桁増えるけど
Base32でいいなら最初からそうしてるだろうに
圧縮率最高で速度がBase64と同じBase62を作りたいってか 虫が良すぎる どれか一つ諦めろ
>>308 無理だよ
Base64の仕様をみたほうがいい
2進数や16進数での切りの悪い62進数という時点で
別にそんなもん求めてなくね? 速度が〜とか言ってないし、圧縮率もBase64に劣ることも認識してるし
>>310 無理だよね。
Base64の仕様を見る限り、切りの悪い10進数なんて表現できるわけがないよね。
そこまで記号に怯える理由もわからん 0-9a-zA-ZだってURLエンコードしようと思えば出来るし、何かの弾みでされるかもしれないが それは不正データとして弾いちゃっていいの?
8バイト(64bit)を Base64エンコードした場合のバイト数は11 Base32エンコードした場合のバイト数は13 誤差だと思うけど 記号を嫌う以上はこのくらいの増分は覚悟しないと
>>311 でもBase32にして符号長を伸ばすことも
普通に割り算と余りでBase62を作る遅い方法も許せないんだろ?
両方に並々ならぬこだわりがあるんじゃないの
>>314 ヒマだから的はずれのレスにつっこんでるだけだよ
自演と思いたければどうぞ?
誰も自演だなんていってないのに、なんでそんなこと言い出すの?謎すぎる
.と-とかならまず問題ないと思うんだけどな
320 :
282 :2009/07/08(水) 01:55:04
>>307 「サイズをなるべく短くするために」を実現するためにBase62なのです。
速度はあまり求めていません。
Base64と同じ仕様である必要はありません。
>>313 弾いてよいとさせて下さい。
>>315 それなら自作版のBase62を作ります。それぐらいバイト数に対する要求度も高いです。
>>316 282に書いたのは割り算と余りでBase62を作る方法ですが、気に入らないのは、あくまで圧縮率で
速度ではありませんでした。
>>316 > 普通に割り算と余りでBase62を作る遅い方法も許せない
というのは書いてなくね
>>282 8バイトごとに剰余リセットしていいなら簡単じゃないか。
64bit整数があるならそれ使えばいいし、
ないなら32bit整数のペアで表せばいい。
>>320 割り算と余りより圧縮率上げようとするならBase62じゃなくなるぞ
新しい圧縮フォーマットを作る話になる
>>323 割り算と余りより圧縮率上げよう、なんて書いてなくね?
>>323 それでいいとおっしゃってるw
好きなようにやらせればいいんでないの。
わざわざ変換前の数字を62進で計算したあとエンコードとかw
シフト演算もろくに使えないのに
>>324 いや、ここにきて
>割り算と余りでBase62を作る方法ですが、気に入らないのは、あくまで圧縮率
と書いてるぜ
誤読も何も他の読み方があるのか
>>320 どこで悩んでるのかわかんないんだけど。
2進化62進数でいいの?それとも、62進数がいいの?
>329 やりたい方向としてはBase64なんだけど62に収めるという独自仕様らしいよ
Base32の圧縮率が気に入らなかったってことか? そうならすまんかった。
333 :
デフォルトの名無しさん :2009/07/08(水) 02:05:39
エスパー禁止
334 :
282 :2009/07/08(水) 02:08:12
>>329 8バイトごとに11バイトのデータに変換するなんてベタで無駄のある処理をしてしまうより、
もっとスマートな方法がないかを模索したかったのです。
ご意見ありがとうございます。
まとめると、多倍長整数を使わない場合は、
2^n進数ならスマートに出来るけども、
2^n進数以外ではスマートにならないし、一般的な方法もあまりないということでしょうかね。
>>334 です
62進数の場合は割り算などを駆使して分解したあとエンコードするしかないかと
>>334 元のバイト列を一つのでっかい整数だと思って62進数に変換すりゃいいじゃん
ああ、それで多倍長整数とか言ってたのか?
そんなもんなくても変換できるぞ
割り算の筆算と同じだから
>>334 多倍長整数なんてなくても、普通に62で割って余りを伝搬させて行くだけでしょ。簡単じゃん。
char src[XXXX]="元データのバイト列"; char dst[XXXX*4]; //バッファ int main(){ int j=0; for(int i = 0; i < XXXX; ++i){ int tmp = tmp*62 + src[i]; dst[j] = tmp % 62; tmp /= 62; j++ if(tmp >= 62){ dst[j] = tmp % 62; tmp /= 62; j++ } } while(tmp > 0){ dst[j] = tmp % 62; tmp /= 62; j++ } } テキトーだからきっと間違ってる
割り算や余りってどのくらいのペナなんだろうな Base64と同じでビット単位で区切ったあと 62,63の場合は・・というif文入れれる方法もあるけど
URLエンコードされるのが嫌なら、+と-の代わりにスラッシュとピリオドでも使えばいいじゃない。 これならきっとURLエンコードされないって。 クエリ文字列は2chのread.cgiみたいにパス風の文字列にしてさ。
341 :
282 :2009/07/08(水) 02:30:35
>>336 >>337 組み込みの演算子ではなく、自作の割り算を作ればよいということですね。
その辺はよく知らなかったため、調べてみたいと思います。
>>338 なんか、ソース自体は自分が考えていたよりスマートですね。
想定する動作になるか確認するのに少し時間が必要です。
これが
>>336 >>337 さんが言っている方法ですかね。
>>338 自己レス
肝心の所で大間違いしてた
>int tmp = tmp*62 + src[i];
tmp = tmp*256 + src[i];
あとtmpは要main直後宣言(=0)
>>341 この程度の部品関数ならそんなに時間かからねえってw
8バイトごとにって uint64 n; n = src[i] << 8*7 | src[i+1] << 8*6 | … を62で割ったりする話だと思ってた。
345 :
282 :2009/07/08(水) 04:22:41
>>342 srcが"\x61"のときと、
srcが"\x23\x01"とでdstに入る内容が同じになるようです。
もー寝る!
346 :
デフォルトの名無しさん :2009/07/08(水) 04:30:52
255文字に、可変ビットを割り当てておけよ。 たとえば、tがよく出るなら、3bitくらいにするとか。
>>339 以前割られる数aと割る数bと商を入れるポインタと余りを入れるポインタを渡して
a/bとa%bの計算をして結果をポインタに入れる関数を作ってどんな最適化がされるかな?と
やってみた事があるんだけど、割り算の計算が完了した時点で2つのレジスタに商と余りと
計算ができているのにポインタに詰め込む段階で片方のレジスタの値しか書き込まず
もう一度割り算をしてやっぱり片方のレジスタの値を書き込むだけみたいな
Cで書いた通りに実行されていて泣いたw
348 :
デフォルトの名無しさん :2009/07/08(水) 10:22:41
#include <stdio.h> typedef int (*tenarray)[10]; int main(void){ int i,j; char d[] ={ 'a','b','c','d','e', 'A','B','C','D','E', '1','2','3','4','5'}; char (*c)[5] = (tenarray)d; for(i = 0; i < 3; i++){ for(j = 0; j < 5; j++){ } printf("%c",c[i][j]); } printf("\n"); return 0; }
349 :
デフォルトの名無しさん :2009/07/08(水) 10:27:22
gcc -o ni ni.c ni.c: In function ‘main’: ni.c:11: 警告: initialization from incompatible pointer type ./ni A1 教材のプログラムなんですが上手く実行できません。 期待される実行結果は abcde ABCDE 12345 です。
>>349 写し間違えているか
教材を作った奴が分かっていないか
うまくいかないことを教えようとしているか
どれだろうね
>>349 キミが何をしたいのかいまいち不明だが、
その結果を期待するだけなら
typedef int (*tenarray)[10]; → typedef char (*tenarray)[5];
と、for文のとこは
for(i = 0; i < 3; i++){
for(j = 0; j < 5; j++){
printf("%c",c[i][j]);
}
printf("\n");
}
だろう?
元がこれで、別な何かをやりたくて改変してるように見えるが・・・
tenarrayへのキャストはおいておいて、 ふたつある printf の行の位置が間違っている。 両方とも } の上の行(ループの内側)に移動すればいい。
354 :
デフォルトの名無しさん :2009/07/08(水) 10:39:59
>>351 教材を忠実に写しています。
351のプログラムは質問する前にやってみましたができません。
教科書はポインタで一次元配列を二次元配列に変換できることを説明しています。
>>354 まず変数cの領域が足りてないから
c[1] とかにアクセスしちゃだめだ
356 :
デフォルトの名無しさん :2009/07/08(水) 10:43:06
>>354 そのやってみてできなかったことをかけよ。
こっちは実際にやってみてできることを確認した上で答えてるんだが。
358 :
デフォルトの名無しさん :2009/07/08(水) 10:46:11
>>357 すみません。
エラーは出ませんが実行結果は同じです。
359 :
355 :2009/07/08(水) 10:47:03
>>361 は自分の馬鹿さにいつ気がつくのだろうなw
363 :
デフォルトの名無しさん :2009/07/08(水) 12:08:23
>>362 はつっこみがイカシテルなw
すいません、質問があります。
1〜100000000まで100000000行のデータがあります。
いきなり最後の100000000という整数を読み込むことは出来ますか?
一列目にパケットNOがついているCSVデータの行数を取得するのに、
最後の数字から最初の数字の差分を出したいです。
一行一行カウントしていくのは時間がかかり過ぎます。
宜しくお願いします。
fseekでファイルの最後から1000バイト(適当)くらい前に移動してそこから終わりまで読み込み、 最後のひとつ前の改行から整数をひとつ読めばいいかと
365 :
デフォルトの名無しさん :2009/07/08(水) 12:36:48
>>364 ありがとうございます!
解決しました!
return s[i] - t[i]; とはどういう意味ですか?詳しくお願いします。
(配列 s と 配列 t があります) i番目の要素での値 s[i] から (同じ位置での) t[i] を引いた値を戻します
369 :
デフォルトの名無しさん :2009/07/08(水) 13:07:26
>>368 ありがとうございます。理解できました。
370 :
デフォルトの名無しさん :2009/07/08(水) 14:01:03
>>348 です。
ただ単にprintfの位置がずれているだけでした。
>>348 のプログラムはprintfのところ意外はちゃんと教科書を写したものですが
他のところは教科書のミス印刷でした。
371 :
、 :2009/07/08(水) 14:50:47
教えて下さい。 ある変数のポインタを特定数だけ進めたいです。 char A; A = A + 40; 上記だと左のオペランドが、左辺値になってませんというエラーがでます。
ポインタは進まないだろうけど、その計算はできると思うがね。 Aってリテラル参照してるchar*だったりしないか?
373 :
デフォルトの名無しさん :2009/07/08(水) 15:02:16
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(void){ 6 char *p; 7 8 p = calloc(1,20); 9 strcpy(p,"今日はいい天気だ"); 10 11 p = realloc(p,40); 12 strcat(p,"公園にいこう\n"); 13 printf(p); 14 free(p); 15 return 0; 16 }
374 :
、 :2009/07/08(水) 15:02:31
返信ありがとうございます。Aはchar型の配列です。というかこれじゃポインタは進められないのですか?進めたり戻したりの操作を行いたいのですが。
質問するならまともな例文書いて来い
376 :
デフォルトの名無しさん :2009/07/08(水) 15:10:30
./re *** glibc detected *** ./re: realloc(): invalid next size: 0x08b88008 *** ======= Backtrace: ========= /lib/libc.so.6[0x8ec6ff] /lib/libc.so.6(realloc+0x1a7)[0x8ee3f7] /lib/libc.so.6[0x8ee741] /lib/libc.so.6(realloc+0x3c)[0x8ee28c] ./re[0x80484c0] /lib/libc.so.6(__libc_start_main+0xe0)[0x897390] ./re[0x80483a1]
基本型と配列型の違いについて教科書を100回くらい読み直す必要がありそうだねぇ。 配列とポインタも「ほとんど同義」ではあるけど、「同じ」ではないよ。 っていうか、別物。
あと質問者は最初の発言の番号を名前欄に入れて解決するまでそれを通してくれ。 IDもでない板で名無しで発言されてもなあ
379 :
デフォルトの名無しさん :2009/07/08(水) 15:13:42
======= Memory map: ======== 00110000-00111000 r-xp 00110000 00:00 0 [vdso] 00833000-0083e000 r-xp 00000000 fd:00 2493341 /lib/libgcc_s-4.1.2-20070925.so.1 0083e000-0083f000 rwxp 0000a000 fd:00 2493341 /lib/libgcc_s-4.1.2-20070925.so.1 00862000-0087d000 r-xp 00000000 fd:00 2493316 /lib/ld-2.7.so 0087d000-0087e000 r-xp 0001a000 fd:00 2493316 /lib/ld-2.7.so 0087e000-0087f000 rwxp 0001b000 fd:00 2493316 /lib/ld-2.7.so 00881000-009d4000 r-xp 00000000 fd:00 2493317 /lib/libc-2.7.so 009d4000-009d6000 r-xp 00153000 fd:00 2493317 /lib/libc-2.7.so 009d6000-009d7000 rwxp 00155000 fd:00 2493317 /lib/libc-2.7.so 009d7000-009da000 rwxp 009d7000 00:00 0 08048000-08049000 r-xp 00000000 fd:00 2064664 /home/BA08126/cennshuu/re 08049000-0804a000 rw-p 00000000 fd:00 2064664 /home/BA08126/cennshuu/re 08b88000-08ba9000 rw-p 08b88000 00:00 0 b7e00000-b7e21000 rw-p b7e00000 00:00 0 b7e21000-b7f00000 ---p b7e21000 00:00 0 b7faf000-b7fb1000 rw-p b7faf000 00:00 0 bfdac000-bfdc1000 rw-p bffea000 00:00 0 [stack] アボートしました となり期待した実行結果が得られません。9行めの今日はいい天気だのところを他の文章にすると 上手くいくみたいなんです。
>>379 printf("%d", strlen("今日はいい天気だ") );
を確認
20以上ならアウト
382 :
373 :2009/07/08(水) 15:22:20
383 :
373 :2009/07/08(水) 15:28:47
>>381 24でアウトでした。
strlenは文字数を数える関数ですがなんで24になったのかが不思議です。
>>374 別にポインタを進めたければ進めればいいよ。
>>371 のAはcharなので40足すことは可能
>>374 のAはchar配列なので代入不可能
どちらにしてもポインタを進めたり戻したりしようとしてない
>>383 strlenはバイト数を数える
1文字に何バイト使うかは文字コードセットでまちまちだ
UTF-8なら、日本語は1文字3バイトとして数えればだいたいあってる
>>383 は3バイト×8文字で24だったわけね
mallocで確保した領域って、プログラム終了時に解放されないの? OSがプロセスごとにメモリー割り振って、プロセス終了したら 勝手に解放するもんだと思ってるんだけど。
そりゃOS次第
ふつう、解放されるよ 他プロセスと共有されているようなメモリ(mallocしたあとに forkして、かつ、copy-on-writeのシステムの場合とか)は 解放されないかもしれないよ
>>388 突然その話をするということは解放されなかったということ?
>>391 少し修正してプログラム走らせたびに、無駄なメモリ食ってんのかな
と思ったり。それだったら、厳格にメモリ管理しないといけないなって
大した理由もなくゴメン
WinAPIとかでcreateしたやつは終了時に解放されるの?
>>394 今、軽く目通したけど面白かった
読む前は、見事にjavaとかのD言語のGCっていいねって思ってましたw
次の人が流すはずだから、うんこは流さなくて良い。
誰かが気づいて修正してくれることを祈って書かない
doubleは、x86とかの32bitデータバスでもアドレスが8の倍数になるみたいですが、なぜなんでしょうか? 64bitバスならば、8バイト境界をまたぐ可能性があるから、アドレスは8の倍数にならないといけないとはわかるのですが、32bitバスなら、いずれにしても4バイト境界をまたぐ必要がありますよね ならアライメントは4の倍数でも不都合が無いような気がします
>>398 コンパイラのオプションでアライメントは変更できるよ
動作は遅くなるけど
x86って確か昔の互換を残してるのでアライメントを究極に無視した詰め込みもできるでしょ ここまでメモリ増えた状態でそこまで詰めてどうするんだろうとか思うけど
int a[10][10]は int sub(int **a)として渡せるはずですが何故か セグメンテーションとか言われて落ちます
>>403 int sub(int (*a)[10]) でないと渡せぬぞよ
>>404 そうなのですか?大学の先生は大丈夫と言っていたのですが
そんな嘘教えるやつの授業受けるなよ
大学の先生のやりかたは、続きがあるんじゃないか?
>>407 続きは無いのですが、渡せると言ってました。
渡すだけなら大丈夫だ
>>410 アクセスすると落ちてしまうのですが
どうしてですか?
コードを晒せ
なんだかよくわからないけど大学名晒せばいいんじゃない?
>>398 蛇足だけどx86ってPentiumの時代からデータバスは64ビットだよ。
灯大ですけど?
ハーバードですけど?
都の西北早稲田の隣ですけど?
大学名と教授名と口座名を晒すべきだな。
スイス銀行に振り込んでくれ
>>403 nt sub(int **a)
で、a[1][2]をどうサクセスするんだろうか?
でも、int main(int argc, char **argv)のargvはアクセス出来るよ。 これは、main関数の呼び出し元側で、 引数の数分の文字列への先頭ポインタを配列にしているから。 逆に、int sub(int **a)でアクセスさせようとしたいなら、 int [10]へのポインタを個数分配列にすればいけると思う。
取りあえず大学の先生が無能だということはわかった こんないい加減だから卒業生にうらまr・・・ケフンケフン
学生の理解力が妖しいとか
>>421 char **argv
はcharの2次元配列ではない。
>>424 引数の数分の文字列への先頭ポインタを配列にしているから
int a[10][10]は100個のintデータが並んでいる int **aはint*が並んでるだけ
まあ、Cで混乱しやすいところだけどね。 2次元配列と、ポインタの配列の違いは。
でも冷静に考えれば型がわからないとどうしようも無い仕様になってるのに int a[10][10] を int sub(int **a) で渡せると思う方がどうかしてる
原始時代の教科書K&Rですら ポインタの配列と二次元配列について わざわざ一項ずつ割いて説明しているのだから 初心者向けの本しかかけない日本人による最新の教科書なら それこそびっしり、微にいり細にいり書いてあるじゃろ。 教科書をちゃんと読め、としか。
ポインタについて解説はぶきすぎの 入門書が多すぎます 関数のポインタとか スタックとか ぜんぜん説明してくれてないじゃないですか!!
初心者ほどポインタをつかいたがるけど 初心者こそポインタを使わないで済ませるコーディングを勉強すべき
C++に移行すれば複雑なポインタは減るよ。 ポインタ自体はむしろ増えるけど、ほとんど参照レベル1ですむ。
見かけの数が減ると
ポインタ使わない方がいいのけ?
どんな初心者でもポインタ使わないほうがいいとか必ずしも言えないだろ。 だが、おまえは使うな
cをやめてrubyお勧め
437 :
、 :2009/07/09(木) 16:19:16
教えて欲しいのですが、数値Aが偶数なら何もしない。数値Aが奇数なら文字列の後ろに数値Aが偶数になるようNullをつける。 このような制御文を入れたいのですが偶数か奇数かの判定の仕方がわかりません。よろしくお願いします。
if ( A % 2 ) { /* 奇数なら */ } else { /* 偶数なら */ };
439 :
437 :2009/07/09(木) 16:35:07
>>438 ありがとうございます。
上手くいきました。
440 :
デフォルトの名無しさん :2009/07/09(木) 17:52:19
パスカルの三角形を出力するのに #include <stdio.h> #define N 10 int main(void){ int i, j = 1, x, y; int d[N][N]={}; /* 三角形を作成 */ for (i = 1 ; i < N ; i++){ d[i][0] = 1; while (j <= i - 1){ d[i][j] = d[i-1][j-1] + d[i-1][j]; j ++; } } /* 三角形の表示 */ for (y = 0; y < N; y++) { for (x = 0; x < N-y; x++) printf(" "); for (x = 0; x < y; x++) printf("%3d ", d[x][y]); printf("\n"); } return 0; } と書きましたが、すべての要素がゼロになってしまいます。 なぜでしょうか?教えてください。
適当だけど、jの初期化が抜けてるのでは
printf("%3d ", d[y][x]);
>>440 > /* 三角形を作成 */
> for (i = 1 ; i < N ; i++){
ここを抜けた後のdの値
d = {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 1, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 1, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 1, 0},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 1}}
もう一度良く見直してご覧
440は、なぜか宿題スレに行ってしまいました
(#^ω^)
>>440 別のスレに回答しておいた。
出力結果のサンプルはこんな感じ。
1
1 1
1 2 1
1 3 3 1
448 :
282 :2009/07/10(金) 03:28:23
蒸し返して申し訳ないのですが、Base62の話で、
>>336 とか
>>338 とか見てて思ったんだが、
単なる数値とみなすと、0扱いのもだと、最悪0バイトの出力になったりする。
デコードを可能にするため、事前に入力バイトから出力バイトが決定されるようになってるか、
頭にバイト数情報をつけないといけないと思ってる。
あと、単純に文字列を数値とみなすやり方だと、62進変換の過程で、
入力バッファと同じ大きさのバッファが必要になってしまうと思ってる。割る処理で割ったデータを残すため。
これも避けたい。仮にバッファを取ってしまうのを許すとして、デコードのまともに動く実装が?の状態。
>>299 >>346 さんのご指摘にあるようなZIPとかの出現コードの偏りによる圧縮は考えない場合、
エンコード時の理論値最高圧縮は2^5.95 ≒ 62。8/5.95≒1.344倍ぐらいになると思っていて、
今の1.375よりもう少し詰められるはずですが、内部バッファの確保が許されないと無理でしょうかね?
とりあえず、自作版のBase62は
http://codepad.org/tj6adTYMにアップしといた 。
449 :
初心者No1 :2009/07/10(金) 13:38:43
テトリスのソースを引っ張ってきて自分で中身を改造してるのですが 次に出現するブロックの予告部分がうまくできません。 srand((unsigned)time(NULL)); //現在時刻を取得? block_type = rand() % 18; //取得した時刻をブロックの種類で割った余りで出現ブロックの決定? と、解読もままならない状態なのですが・・・ これの次点で来るブロックがわかる方法ってありますか? 取得した現在時刻に1を足すなど、がむしゃらにやっては見たもののうまくいかないので わかる方がいらっしゃいましたら教えてください。 質問の仕方も悪いのですが、よろしくお願いします。
連投すいません。 sage忘れました
>>451 ソースがひどい長いので、どこかにうpすればいいんでしょうけど
そのやり方がよくわからないので・・・
454 :
449 :2009/07/10(金) 13:58:07
printfでなんか法則性ないか探してみましたけど そもそも乱数取得なのに次に来るのがわかること自体すでに乱数じゃないかなと思った・・・w どうもすいませんでしたー。 スルーでお願いします
>>454 int myrand(int chk_next_flag)
{
static int pool;
int ret;
if(chk_next_flag) return pool;
ret=pool;
pool=rand();
return ret;
}
>>448 8->11じゃ、62で割りきれんからとでんでもになるんじゃ?
457 :
449 :2009/07/10(金) 14:47:44
>>455 すいません・・・まったく意味がわからないです。
いっそのこと予告しているのを次に落とすブロックにしちゃえばいいやと思ったら
自己解決できちゃいました・・・(==;
>>451 >>455 ありがとうございました。
>>457 >>455 のは その予告をうまく分離できるように細工したコードだと思うよ
通常の利用シーンでは myarand(0) で呼び出し
予告値を得るときには myarand(1) で呼び出し
a〜bの乱数とかいった場合には (double)rand()%RAND_MAX*(b-a)+a とかやったほうがいいの?それともがんばってもそんなに変わらないかな?
>>459 最近の乱数発生器は大抵かわらない。
と思ってたらカルドセプトなんとかっていうゲームが罠にはまってたな。
最近のってrand関数の実装が変わったりしてるの?
>>460 あれは、普通に標準関数の乱数を使っておけばよかったのに、
自作したり変に工夫したりして自爆したんじゃないかと思う。
>>461 Lagged-Fibonacci を採用する実装が増えたとか (又聞き)。
個人的には MT の実数版を使ってるけど。
printf("%s", static_func()); char* static_func() { static char* p; char s1[20] = "foo"; char *s2 = "bar"; p = strcat(s1, s2); return p; } printf()すると「1234イ」とか出ます。 puts()だとちゃんと表示されるんですが、何故ででしょうか。
そのソースでputsは「1234」と出ると言うのかい?
466 :
464 :2009/07/10(金) 22:13:53
間違えた。 printf()の場合 「foobイ」 puts()の場合 「foobar」
>>464 char s1とchar *s2 が関数 static_func()を抜けた時点で消滅しているので
未定義動作です
468 :
464 :2009/07/10(金) 22:21:13
>>467 なるほど。ポインタを返しても参照先のs1、s2が消えるからおかしくなるんですね。
puts()で表示されるのは何故なんでしょうか。
>>468 それも未定義動作のうちです
putsで表示されるかもしれませんし、HDDがフォーマットされるかもしれません
470 :
464 :2009/07/10(金) 22:25:48
>>469 ありがとうございましたー
もう少しこの辺り勉強します
もう少し推測を入れてもいいのならば、puts()とprintf()はスタックに積む 引数の数が違います "恐らく"ローカル変数s1、s2はスタック上に取られているので、puts()と printf()で破壊される文字数が異なるのだと思います しかしそれはそれとしてこのような事はしないようにしましょう
>>469 HDDが〜ってよくきくけどほんとにそんなことが起こったことがあるの?
俺はないが、結果がどうなるか言語仕様としては定まってないので どういう動作をしたとしても言語仕様的には間違ってないって意味だろ
>>472 エキスパートCプログラミングに、大昔のIBM-PCのモニタから
発火させる方法が書かれていた
つまりIBM-PCの時代は未定義動作を起こすと本当に火事
になる可能性があったんだよ
バッファオーバーランなんてまさにウイルスが未定義動作を利用してHDDを破壊する例だな
それは実装ミスでは?
>>474 ちょっと前のウィルスにはBIOSを破壊したり
ものすごい勢いでディスプレイの解像度を切り替えたり
ハードディスクのブートエリアに潜入して
低レベルフォーマット以外を拒否ったり
そういう破滅的なものもあったけど
今はないねぇ。
だから、モトローラ系のユーザースタックとシステムスタックとを別に持つアーキテクチャにしなければ、となんど主張したことか。
>>477 すぐバレるからじゃないの?
トロイの木馬形式にすると発病まで時間がかかるから
その間に感染を拡げるし
>>477 そりゃ、きんたまウィルスのような人生を破壊するウィルスのほうが優れているのでは?自殺者もでるくらいだし。
簡単だけどものすごいアイデアのウイルスってないかなぁ
簡単ですごいアイデアだったといえばLove Letterウィルスがすごかったね。 賢明に「I Love you」と書かれていると、人はなぜか開いてみたくなる。 意味不明な内容のメールに添付ファイルがついていると、人はなぜか開いてみたくなる。 タスクバーに目玉のアイコンが表示されると、人はなぜかクリックしたくなる。 「押してはだめだ」と書かれたダイアログが表示されると、人はなぜか押してみたくなる。 で、発病^^
>>482 そうねえ。
知らない人からのメールの添付ファイルに疑いを持たない時代だったからね
敵を倒すとハードディスク内のファイルが削除されていくゲーム
なにそのゲーム怖い
>>467 s1とs2はpにコピーされてるので関係ないだろ
問題はpの領域が確保されてないこと
static char p[256];とかなら255バイトまでなら問題ない
間違えた strcpy( )じゃなかった
>>488 言い切れないんじゃないかな
関数無いで新しい領域を確保して第一引数と第二引数のコピーを作るとも作らないとも書いてない
strcpyの解説をいくつか見てみたけど、第一引数はコピーされないで元のままみたいな感じだよ
つまり
>>467 のいう方向で考えた方がいい
原本というかANSI?の規格をみたわけじゃないので言い切れない部分もあるけど
内部でコピーするなら第一引数もconst付きでいいはずだしなあ
何低レベル回答しているんだ。 strcpy()もstrcat()も第一引き数が格納先になるんだからs1をロストする時点でダメ以外の回答は有り得ないじゃないか。
しまった、>488みたいなstrcat()を根底から理解できていないレスからの一連の流れなんだから当然ギャグなんだよな。 KYですまん。
C言語で一番多いミスは文字列周りというのがよくわかるやりとりですね
僕はポインタちゃん!
列挙型の#defineの欠点を教えてください。
498 :
デフォルトの名無しさん :2009/07/11(土) 16:32:08
すいません助けてください・・・ 例えば画像ファイル(HEIGHT × WIDTH)があって それにラベリングがしてあるとします そのラベリング値がpointのときの面積を計算しているのですが たまに止まってしまいます・・・ 毎回ではないですが、入力画像(顔の撮影)によって セグメンテーション違反によって止まってしまします・・・・ double mensize(unsigned char (*image)[WIDTH],int point){ int i,j; double total; total=0.0; for(i=0;i<HEIGHT;i++){ for(j=0;j<WIDTH;j++){ //printf("%d ",image[i][j]); if(image[i][j] == point){ total++; } } } printf("total = %f \n",total); if(total==0.0)return 0.0; return total; } なぜでしょうか? total++がたくさん実行されるとダメとか そんなのは・・・ありませんよね?汗 ちなみに止まるときはコメントアウトしてるところを消して どの値で止まるか見てるのですが、なんとも中途半端なところで よろしくおねいがいします
imageがちゃんと構築されてないんじゃないの?
mensize()には、とくに間違いないんじゃないかなあ ↓これで全ピクセルがカウントされるてHEIGHT*WIDTHが表示されるし・・・ void main() { unsigned char image[HEIGHT][WIDTH] = {0}; mensize(image, 0); }
imageが糞でかいのにスタックに乗ってるとか
502 :
501 :2009/07/11(土) 16:55:44
HEIGHTとWIDTHのサイズは? mensize関数に渡してる第一引数に渡す二次元配列はどのように確保してる?
効率悪いなぁ。なんでdoubleなんだ?
>>448 >単なる数値とみなすと、0扱いのもだと、最悪0バイトの出力になったりする。
Base64でも一緒な
>あと、単純に文字列を数値とみなすやり方だと、62進変換の過程で、
>入力バッファと同じ大きさのバッファが必要になってしまうと思ってる。割る処理で割ったデータを残すため。
余りさえ伝播すればいいから1バイトで十分
507 :
デフォルトの名無しさん :2009/07/12(日) 02:09:28
4ビットあれば十分だなw
3ビットと言わない優しさ
問題は固さだと思うんだ
a = 0x00000001; b = *a とした場合aの前の「*」とはどういう意味で、bはどうなるのですか?
*は間接演算子 bがどうなるかは未定義
何でもかんでも未定義にしたがるやつだなー
というかコンパイルエラーだろ ポインタにキャストしてないし
514 :
デフォルトの名無しさん :2009/07/12(日) 10:54:55
そもそも奇数アドレスが
というかaとbの型すらわからないのにエスパーしてどうするの
0x00000001をキャストなしに代入できるんだから整数型か浮動小数点型か列挙型だな
bが何なのか分からん以上答えようがない。
警告は出るけど、代入はできるだろ
519 :
デフォルトの名無しさん :2009/07/12(日) 12:10:15
奇数アドレスでエラーにならないって事は char型じゃね? 多分 char *a; char b; だと思うけど b = *a は ; が無いからエラーかな
本当に色々なことに目をつむり、質問者の意図を予想して考えると 「「*」とはどういう意味で、bはどうなるのですか」 という質問に対しては、*は間接演算子で、bに0x00000001というメモリアドレスが さす内容が入りますよ、となるんではないでしょうか
違います
アドレス値⇔整数の相互変換は保障されてるけど 整数をキャストなしにアドレス値とみなすことは 保障されていないんじゃなかったか?
だからエスパーするなって
524 :
デフォルトの名無しさん :2009/07/12(日) 12:39:37
525 :
デフォルトの名無しさん :2009/07/12(日) 13:40:23
>>502 unsigned char image_out[HEIGHT][WIDTH];
です
ワロタ >HEIGHTとWIDTHのサイズは? も聞かれてるのに まあスタックオーバーフローだろうな
>>525 HEIGHTがいくつかということも聞かれてるようだよ
rw、両方ともパーミッションが立ってないファイルの有無確認って、どーやるの?
ファイルの有無はそのディレクトリのxで
ってstatとかのこと聞いてるのかな?
てst
532 :
デフォルトの名無しさん :2009/07/12(日) 18:32:58
バッファオーバーフローを起こすプログラムきぼん
gets
規格の「未定義」というのは、必ずしもやってはいけないものばかりではなくて、 特定の環境向けのプログラム(特にOS等)なら、大いに使っていいものもある。 つまり、環境依存ってことね。 だから、前提になる環境も含めて質問すればよい。
>>535 未定義の解釈、ちょっと違くねぇか?
処理系定義と未定義の違いは
>>535 さんは理解してる?
まあ入門スレだからいいけど。
でも、整数型に十分な大きさがあれば、ポインタと整数の変換は処理系定義だったよね?
質問です。 C言語は型の大きさ(sizeof演算値)が、例えば整数なら short <= int <= long という大小関係のみで、具体値が仕様として決まっていないのでしょうか。 こうなっている理由などについて教えてください。
だって速い方がいいもの
君、まずは仕様書を読みなさい
>>538 それぞれの環境で最速最適なものを取りたいから。
int を最適なサイズにあわせる処理系が多いと思います。
だったはずなんだが最近はLP64だのLLP64だの ちゃんと作ってないプログラムのケツを拭く様な仕様に
>>538 具体的に大きさを決めてしまうと、環境によってはそれを実現するために多大なコストが必要になるから。
<質問>列挙型の#defineの欠点ってなんでしょう?
日本語で分かりやすく
546 :
544 :2009/07/12(日) 22:13:44
ではわかりやすく 列挙型の#defineを定義しない場合に得られる利点はなんでしょうか?
日本語で分かりやすく
列挙型の#defineって何
enum {hoge}; #define fuga hoge
何その阿呆なコード。
enum {hoge}; enum {fuga}; とやるよりメモリを節約できます
>>544 知識がどこか狂っとる。
#define fuga hoge
ってもういくら何でも重症患者w
#define fuga(fugo) enum fugo {fugo##_hoge, fugo##_hage, fugo##_hige} fuga(ponyo);
554 :
544 :2009/07/12(日) 22:45:49
大学の先生が書いた問題そのまんまなんですけどね・・・
宿題なら自分で考えろよw
その先生は偽者です
557 :
544 :2009/07/12(日) 22:48:00
たしかに内容おかしいですよね
この間もintの二次元配列を変な型で関数に渡そうしてどうのこうのって質問があったのも 大学教師から聞いたとかだったなw どこの大学だよww ゴミ教師
>>551 残念ながら、enumシンボルを定義しただけではメモリ空間を消費しないのだよ。
つまり、>549みたいな阿呆なことを書いても全く「メモリ節約」なんて効果はないわけだ。
どこの大学だよ
大学名と教官の名前さらせよ。
俺の大学、教科書が「Cの絵本」なんだけど・・・
565 :
544 :2009/07/12(日) 23:11:21
どうも、ありがとうございました。 なんとかやってみます。
列挙型の#define #defineをいっぱい列挙するようなやり方のことじゃないか?
Cで悩みたくなければアセンブラもやれ
>>563 プリプロセッサのメモリのことも考えてあげてー!
571 :
デフォルトの名無しさん :2009/07/13(月) 13:29:17
>>526 WIDTH 640 HEIGHT 480です すいません
printf("%d ",image[i][j]); これ、 printf("%p ",&image[i][j]); とかにして落ちるときどうなってるか見たいな。
573 :
デフォルトの名無しさん :2009/07/13(月) 14:40:01
ここはアセンブリの質問もおk?
ぎりぎりおk
640x480=307200 スタックに取るにしてはでかいかもな
メンドクサイので unsigned char image_out[HEIGHT][WIDTH]; を static unsigned char image_out[HEIGHT][WIDTH]; としておけ
578 :
デフォルトの名無しさん :2009/07/13(月) 15:59:05
なぁっつがくっるかっらぁ♪
strtokで二連続以上の半角スペースまでを取りたいのですが、どうすればいいのでしょうか? どうあがいても一つのみの半角スペースまでの文字列を取ってきてしまいます。 先生がそうする方法がある、というようなことを言っていたのですが・・・。 調べても見つからないので。
ないよ。勿論、自前で処理すればできるけど。
多重ループから一気に抜け出す方法ってgotoくらいしかない?
組み方にもよるけどbreakだとネスト一つだしなあ。 多重ループが小さな関数内の物ならreturnで抜けるという方法もあるけど 結局は前後のロジック次第じゃないかな?
そっか!関数化してreturnで抜けちゃえばいいのか!thx!!!!!
VS2008でCとC++の混在したソフトを作っています。 本体はC++のWin32プロジェクトで、そこからCの関数を呼んでいます。 Cの中でprintfを使った場合、その出力はどこへ行くのでしょう? IDEの出力ウィンドウとコマンドプロンプトは見たのですが、 どちらにも何も表示されませんでした。
>>584 C++ で開いた標準出力。
C++ がウィンドウアプリなら、標準出力は開いていないかも知れず
その場合はどこにも出力されない。
>>585 わかりました。ありがとうございました。
char buf[BUFSIZE]に fgets(buf, BUFSIZE, stdin)で標準入力からの文字列をbufに格納して、bufの文字数をstrlen(buf)で取得 printf("%s", buf)でLength: x と表示させたいんだけど Length: xの部分をどう書いてbufに代入すればいいんでしょうか?
文面通りにうけとるなら、なんでそんな無駄な事を?
>>587 printf("Length %d\n", strlen(buf))
ではいけないのか?
改行コードも文字数に含まれるけど
いま、ポインタの参照渡しについて勉強したのですが、 参照渡しというのは、変数のアドレスが指すところを直接書き換えてしまえ、 という考え方ですよね? 関数の戻り値で結果を返すのではなく、 関数のなかで、アドレスの中身を書き換えてしまう、 そういうものですよね?
あえて混乱させる答えを書くと C言語は全て値渡しです あなたの言う「参照渡し」は 正確にはポインタを値渡ししているだけです
>>591 うぬ〜。良く分からんですたい(^^;
でも、参照渡しの考え方をちょっとでも知れただけで、俄然C言語に興味がわきました。
プログラミングはJavaで始めたので、これはいい機会と思ってC言語の勉強をします。
ならばCの前にアセンブラを覚えるがいい
>>592 ポインタもアセンブラでみるとメモリ上に配置されてるエリアにすぎませんから
住所を値渡ししてるんだよ
なるほど、住所ってことは自分が住んでる場所ってことですね。 わかりやすいです。 最近の言語でポインタが使えないのも、個人情報保護との 類似で考えると分かりやすいですね。
アクセス制御なんとか汁 static書くの疲れるお
そこで無名namespaceですよ
599 :
687 :2009/07/13(月) 22:01:08
2つのターミナル使ったプロセス間通信でユーザーが標準入力にowata サーバー側がLength: x をbufに格納してwrite()でユーザーに送信 ユーザー側がprintf("%s",buf)で文字数表示ってやりたかったんです
Length: x を buf に 格納 する 必要がまったく無いじゃねえか
>>596 最近の言語は参照型とかあるから個人情報保護的なアレはまた違う
>>599 sprintf(buf, "Length: %d", strlen(buf));
ということ?
603 :
282 :2009/07/14(火) 01:49:37
>>504 どんなBase64の実装か知らないけど、手元のBase64じゃ、入力サイズの大きさに対して出力サイズも決まるな。
数値として0になるのはいいんだが、出力時にそれでは困るという話です。
割った値を持つ必要がない理由を教えてください。
>>448 で示したものでは割った値を保持する必要があります。
まだやってたのかw いい加減仕様決めろよww
base64の仕様ぐらい調べろよバカのくせに
base62じゃなかったの?
>>606 辺にこだわってみたけど微妙でしたとかそんなんじゃね?
なんにせよ、色々こだわる仕様じゃないことはたしかだ オナニーしてるだけだよ
そもそも62にする意味がわからない まさか0-9A-Za-zで62か? 文字セットを限定するメリットよりエンコード、デコード処理が 煩雑になるデメリットのがはるかに大きい
>まさか0-9A-Za-zで62か? 最初にそう書いてあるじゃないか。
そもそもCでCGIというのも煩雑でメリット少ない気がする PHPで十分じゃないの
ビスタでアンシーは使えないんだすけど 画面を消したりカーソルを移動するにはどうするですか?
不真面目な奴に教えない
>>612 つーか、環境依存スレなりDOSプログラミングすれなりAPIスレなりで聞けば?
>>612 void clearScreen() {system("cls");}
void cursorMoveToTopOfLine() {putchar('\r');}
>>612 おまえは何のつもりで「アンシー」つってんだ。
エスケープシーケンスの話か?
ウテナの嫁?じゃなくてansi.sysに想いを馳せてるんだろうね
普通「アンシ」だよね
>>612 わかりました。あなたは世界を革命するしかないでしょう。
もう、DOSの知識は捨ててしまえ
char *a="papoi"; fprintf(stdout,"%s",a); とやってpapoiと全ての文字列が表示されるのは %sとやると配列の全てを表示してくれるからでしょうか?
0が来るまで出力
>>603 ビックリするほど頭悪いな
>どんなBase64の実装か知らないけど、手元のBase64じゃ、入力サイズの大きさに対して出力サイズも決まるな。
当たり前だろ
君にもわかるように256進数と62進数じゃなくて10進数と2進数にしようか
例えば10進数の「0010」という列を2進数で表すなら、
情報を失いたくなければ同じように上位に0を入れて00000000001010と表すに決まってる
君は「10進の0000を2進にしたら0になっちゃう!サイズわかんない!使えない!」って騒いでるのと同じ
これでもわからんなら知らん
626 :
282 :2009/07/14(火) 23:06:53
>>625 理論値である1.344倍に対応する入力サイズと出力サイズの比率を実現したいんだけども、
バッファサイズが入力サイズと同程度のサイズを用意せずに、
実現する方法は分からないな。
Base64やBase32は内部のバッファサイズを不要に大きくせずに、理論値最高圧縮が実現出来ています。
これだけ色々な人に見ていただいて、「ない」のであれば、「ない」ということで納得しますよ。
>>626 入出力がストリームなら、バッファなんかchar2個で十分だろ
余りと桁上げの時の法だけ
Base64やBase32だって一緒(桁上げの法はいらないけど)
どんな頭悪い方法考えてるか知らないけど、わかんないなら素直にBase64にした方がいいと思うよ
お前頭悪いんだから
628 :
282 :2009/07/14(火) 23:42:52
>>627 ありがとうございます。
どうやら「桁上げ」が分からないということが分かりました。
割る処理で必要と考えていますがよいでしょうか。
>どんな頭悪い方法考えてるか知らないけど
ベースは
>>448 で、Base62変換するための一時領域(この領域に対して、%や/を実施する)を文字列で持つ方法です。
>>626 理論値最高圧縮って…何か勘違いしてない?
簡単に言えばBase64は変換前と変換後のデータを単純にテーブルで置き換えてるだけ。
バッファの大きさはデータサイズと一切関係なし。処理速度がほんのちょっと違う程度。
出力のサイズは入力の1.33倍で固定。
Base64って、3バイト=24ビットを4分割して6ビットx4で表してるだけでしょ 6ビットで表せる数が0〜63の64通りでBase64 って最後の方のレスしか読んでないが。
>>626 Base64はO(1)の空間とO(n)の時間ですむが,
Base62はO(n)の空間とO(n^2)の時間が必要(入力データを書き換えられない場合).
web上のgif画像をbmp形式で保存したいんだけど入門?
クトリアホテルは客室が55ヶで高興(コフン)で最も大きいホテルだが, 2ヶ月前に予約が完了した。 ホテ
ル側は “発射予定日が夏休暇シーズンと重なり, 周辺モーテルにも空室がない”と伝えた。
ナロ号を船上から見ようとする人々で遊覧船予約も終わった。 羅老島(ナロド)近隣で198t級遊覧船ク
ムホ号を運航するコ・ジョンソク船長(57)は “旅行会社を通じて, 搭乗客200人を募集したが3日で予約
が終わった”と話した。
発射当日,推進体落下などにともなう問題で, 宇宙センター近隣陸上と海上の出入りが統制される。 だ
が天気が良ければ半径20km内外でカウントダウンと共に火花を出すナロ号の威容を見られるものとみ
られる。
全南道(チョンナムド)と高興郡(コフングン),麗水市(ヨスシ)は安全問題と障害物有無などを考慮して
ナロ号を肉眼で見られる‘ビューポイント’16ヶ所を選定した。 宇宙センターから遠く離れておらず統制
区域の外ながらも視野がパッと開いたところは, 高興(コフン)が7ヶ所, 麗水(ヨス)が9ヶ所だ。 高興(コ
フン)地域最適地は影南面(ヨンナムミョン)ナムヨル海水浴場。
高興郡(コフングン)はこちらに多くの観覧客が訪れると見て駐車場と特設舞台を作ることにした。 麗水
市(ヨスシ)は宇宙センターから20〜30km離れた華井面(ファジョンミョン)シド, ナンド, サンナファド, ケド,
ペクヤド等9ヶ所を推薦した。 この島々と宇宙センターの間には障害物がなく視野がパッと開いて, 展望
の良いところで選ばれる。
ビューポイント16ヶ所は全南道(チョンナムド)観光ホームページの南の島コリア(www.namdokorea.com)
で見られる。
教育科学技術部は300人以上を抽選して, 海軍独島艦に乗艦させて, ナロ宇宙センター近海からナロ号
発射場面を観覧するイベントも持つ。
歴史的な韓国最初宇宙ロケット発射を控えた高興郡(コフングン)の客応対手助けも忙しい。 高興郡
(コフングン)は30日ナムヨル海水浴場から発射場面生中継とともにミュージカル ガラショー‘宇宙での
跳躍’等祝い公演を準備している。
高興(コフン)=チョン・スンホ記者
[email protected]
http://news.donga.com/fbin/output?n=200907150148&top20=1 記事入力 2009-07-15 02:59
“ナロ号発射直接見に行こう” 高興(コフン)は今‘部屋を手に入れる戦争’
■韓国最初宇宙ロケット発射D-15…現地表情
民宿はもちろんテントまで品切れになって
遊覧船予約も3日ぶりに終わり
肉眼観測するビューポイント選定
駐車場-特設舞台新設奔走
30日韓国最初宇宙ロケット‘ナロ号(KSLV-I)’発射を控えて韓半島南の端すそ全南(チョンナム), 高興
郡(コフングン)がうきうきしている。 発射当日を前後して, 峰来面(ポンネミョン),ナロ宇宙センター近隣
宿泊施設予約がほとんど終わって, 時宜外れの‘部屋を手に入れる戦争’も広がっている。 ‘宇宙都市’
高興郡(コフングン)は大韓民国の夢と希望をのせて宇宙へ行くナロ号発射祝い行事準備で忙しい。
ロケットが空へほとばしる場面を肉眼で見られる‘ビューポイント’を選定して発射特需を生かすために
観光商品も作った。
“残った部屋がないです。 民宿はもちろんで海水浴場モンゴル式テントまで….”
全南(チョンナム),高興郡(コフングン),影南面(ヨンナムミョン)ナムヨルリ。 この村はナロ宇宙センター
へ直線距離で15km離れているが, 肉眼で宇宙センター建物が見えるほど展望が良いところだ。
この村のマ・ヨンマン次長(63)は “29日から31日まで部屋を探し当てようとする人々のために大変な苦
労をしているが, それでも気持ちは良い”と笑った。
こちらは夏ならば10世帯余りが民宿を運営する。 先月開場した海水浴場には避暑客のためのモンゴ
ル式テント60棟が設置されている。 民宿とテント予約は先月10日ナロ号発射日が発表されてすぐ皆終
わった。 マ次長は “民宿世帯数を増やしてみるが, 駆せ参じる人々を受け入れるには力不足であるよ
うだ”と耳打ちした。 ナロ宇宙センターまで乗用車で40分の距離のトファミョン・パルポ海水浴場近隣ビ
637 :
282 :2009/07/16(木) 20:24:33
>>631 ありがとうございます。そう思いますよね。n=入力サイズと解釈しました。
では、なぜBase62だとO(n)の空間が必要な理由は分かります?
考えたのですが、私は2^x = 62を満たすxが無理数となるからだと思いました。
一方、入力サイズから出力サイズを決めるためには有理数でなければならないかと。
(O(1)を実現させるためには、上記制約が必要だと考えています)
(
>>627 の「桁上げ」とは四則演算する「過程」で必要な一時バッファですよね?
「過程」ではなく「結果」を格納するバッファが欲しいのです)
あと、何をイメージして、
>>631 となってしまうと考えたのでしょうか?
Base64や、
>>448 のような近似値でやってしまう場合の制限であって、
他の方法をとればこの制限はなくなる可能性があるかなと思ったんです。
(コードの偏りによる圧縮などは除く)
この点については「ない」というのであれば「な(略
O(n^2)の時間がかかる部分について、どの処理でO(n^2)になってしまうかについて、
割る処理と余りを求める処理の2つをイメージしましたが、認識合いますでしょ
うか?
O(n^2)の内訳は、割る回数がO(n)で、1回の割る処理にかかる時間がO(n)だか
ら、合わせてO(n^2)だと考えています。
C言語から離れてきましたが、やりたいことはBase62で妥当なコードと
エンコード後のサイズを必要最小限としたいだけでしたが、
「妥当なコード」「必要最小限」を理詰めで説明出来そうな状態となったため、
ほぼ問題は解決しました。
スレッドストッパーになったようで、すみません
printf文の %s フォーマットについて教えてください。 通常、ASCIIテキスト文字列+\0 を渡すと文字列が表示されますが、 ここにバイナリ(非ASCII文字列)が来るかもしれない場合でも とにかくそのまま渡してしまうのは問題ないでしょうか? それとも危険な事がありますか? 例えば printf が落ちるみたいな。
printfが爆発する!
>>638 その「バイナリ」の種類によります。ナル文字(=値0のバイト)が出現しない場合、バッファオーバーランしかねません。
逆に、途中にナル文字が出現するとその先は出力されないことになります。
非表示文字による問題が出るかどうかは、端末エミュレータの仕様次第です。
よく知られているところでは、ベル文字(=値7のバイト)が連続すると、ビープ音が鳴り続けるだけでなくその間
表示も動かず入力も行なえないなんて状況になったりもします。
しかし、リダイレクトでファイルに出力するような応用では殆ど危険がないとも言えます。
尚、バッファオーバーランを防ぐには、"%.20s"のように予め制限するか、"%.*s"のように出力バイト数を
引き数で渡す方法があります。
641 :
638 :2009/07/17(金) 01:02:16
非常に勉強になり、悩みが解消しました。 ありがとうございました。
642 :
639 :2009/07/17(金) 09:35:51
>>641 どういたしまして
お役に立てて光栄です
立ってない立ってないw
いつからボケ突っ込みの場所になったんだ
printfの爆発ってバッファオーバーランのことでしょ普通
バッファオーバーランって略すとBORであってる?
普通じゃねえよ 論理的思考で進めないといけないプログラムの世界で爆発とか抽象的な意味不明なこというな 長年連れ添った夫婦間で交わされるあれとかこれで通用する話じゃねーよ
暴走ならまだしも、爆発って言われてもなんのことやら。
printf の爆発 = RTL メモリ領域の破壊
そもそもバッファオーバーランしないだろう…
>>651 それは甘い
どうやってもすることがあるから仕舞いにはマネージドなんてのができるんだよ
, .-‐'''' ^ ''''ー 、 / : : : : : : : : : : : \ /: : /  ̄ ̄ ̄ 、 : i だんねんながら !: : l l: : ! ニーブにぎゅういちは l: : :! 一 ー !: :.l 発毛の効果を100パーネント /: : !_ィェァュ ii ィァュ_ }: :ヽ 実証するものではございまねん -―-、 ! Y Y / ‐ ー、 / ,ー ― 、i ヽl ! 、_ , ! !/ ハ \ ! i ニ ニ l ! ! / ィ===ュヽ ノ /⌒ヽ、 \ ヽ ヽト _ ィ \! ヽェェェ イ ! イ/  ̄⌒ヽ _ l/ ⌒ ‐-、 - ヽ } i i′ _.イ i\ _/ノi\ i / 人 ___ ヽ ,= !│ /ヽ_,. .ー' ̄/:.:.:.i \  ̄´ / |:.:.:ヽー 、__!, ! / __ ` 、 !丿厶 ー:.:.:.:.:.:.:.:./:.:.:.:.:.:ヽ / ‐ く /:.:.:.:.:.\:.:.:.:.:.:.ヽ| ェュ ィァ i ‐- ノ {:.:.\:.:.:.:.:.:.:.:.:.:.\:.:.:.:.:.:.:V 、 人 l:.:.:.:.:.:.<´:.:.:.:.:.:.:.:.:.:.ヽ || ! _/ | i|:.:.:.:.:.i:.:.:.:.:.:.:.:.:.:./:.:.:.:.:.:.:.i /~ヽ !:.:.:.:.:.:.:.:\:.:.:.:.:.:.:.:.:.:∧=- イ / |:.:.:.:.:.:.:l:.:.:.:.:.:.:.:.:ヽ:.:.:.:.:.:.:.:.:l/ ∨:.:.:.:.:.:.:.:.:./:.:.:.:.:.:.:.:.:/:..:i __/ l
>>654 いやだからお前の主観なんかどうでもいいから。
int search(char *s); long hash(char *s); int com(char *s); char str[10]; long h[15],c[15]; みたいなプロトタイプ宣言?と変数宣言があって、その後のほうでstr[0-9]に文字列が入れてあって、その後で while(search(str)==0){ h[i]=hash(str); c[i]=comcount(str); i++; 以下略、という処理があるんですが、 このsearch(str)==0とかh[i]=hash(str)とかは何が起きますか? どこにも関数の処理の中身が無いのですが。
おまいはうちの弟か。 「機械の調子が悪い」って意味で「爆発」を使う。 例 「うちのビデオデッキが爆発した」
>>656 ここはよろず相談所じゃないので、一つ一つ細切れで質問するのなら全部のソースを提示しなさい。
それはさておき、search(str)もhash(str)も関数を呼んでいるわけだからその内部の記述はどこかにあるのだろ。
>>656 >このsearch(str)==0とかh[i]=hash(str)とかは何が起きますか?
リンク時にライブラリから検索され、そちらが呼び出されます。
>>656 別のファイルに中身が書いてあるんじゃないか
すみません、全然別のファイルに関数定義してるのを見つけました。
そもそも、そのためのプロトタイプ宣言<別のファイルに関数定義
そうなんですね、すみませんでした。 本体ファイルのmain関数が終わった後にあるはずだとばかり思ってました。
今日の愚痴 どこもかしこも中途半端なサンプルばっかで嫌になる おまけにタイプミスしまくりだし ちゃんと一発でコンパイルできるソース載せとけよ そっからコピペすれば単純ミスもなくなるだろうに
>>638 NUL がでるまでだらだらとバイナリーがコンソール出力されるだけでは?無論表示は支離滅裂だけれども。
>664 サンプルに文句言うなよ
アプリケーションに割り当てられたメモリ内にNULがあるとは限らないぞ?
掲載されてるソースリストのインデントが半角スペース3個のサイトがけっこうあるんだけど、 どこの流派なんだろう? 全員が意図的にやってるとは思えないんで、何も考えずにコピペした結果なんだろうけど。
いや、3カラムインデント派はいるよ
スペース3カラムでタブは使わない。 こうすると、タブのカラム数が何カラムの環境であろうと、インデントのカラム数は変わらない。
タブ使わないから、タブのカラム数に影響しないのでは
まあ3カラムである意味は分からないな
きっと比率がπに近いほど美しく見えるんだよ。人間ってふしぎ。 もちろん嘘だからな!
いやいや、e = 2.71828…に近い値を目指しているに違いない。
お
2次元配列をmain関数内で宣言します。 int **x; この時点で各要素数は未定です。 こいつのアドレスを関数【void read_file(?)】に渡して その関数内で要素数(m*n)を決定後、mallocでメモリを割り当てて データを挿入します。 この関数がリターンしてもアドレスを渡していた訳だから main関数内のxにはデータが挿入されてます。 っていうのプログラムを作ってるんですが 関数read_file()の引数をどう宣言して xをどう渡していいのか分かりません。 あくまでリターン無しのやり方でお願いします。
void read_file(int*** x); read_file(&x);
678 :
676 :2009/07/18(土) 01:46:14
>>677 しょっぱなにそれを試しましたがムリでした。
int x[2][2]
を関数に渡す場合は
void read_file(int x[][2])
もしくは
void read_file(int (*x)[2])
とすればいいみたいに書かれてました。
要するに省略できるのは要素の一番左の部分だけ。
これだと要素未確定の2次元配列を渡せないので質問しました。
read_file内ではこうやってる? x = (int*)malloc(sizeof(int)*m*n); それともこうやってる? x = (int**)malloc(sizeof(int*)*m); for(i=0;i<m;i++) x[i] = (int*)malloc(sizeof(int)*n);
>>680 その下の方法しかないよなあ
>>676 C言語ではサイズ不確定の2次元配列は扱えないから、「配列の配列」形式にする
まあ見た目はいっしょだから気にしない方向で…
#include <stdio.h>
void read_file(int ***px, int *pm, int *pn)
{
int i, j;
int m=5, n=4; /* 関数内でmとnの値が確定する */
int **p = (int **)malloc(sizeof(int *) * m);
for (i = 0; i < m; ++i) {
p[i] = (int *)malloc(sizeof(int) * n);
for (j = 0; j < n; ++j) { p[i][j] = i * n + j; }
}
*px = p; *pm = m; *pn = n; /* xに加えてmとnの値もmain()に戻してやる */
}
int main()
{
int **x, m, n, i, j;
read_file(&x, &m, &n);
for (i=0; i<m; i++) { for (j=0; j<n; j++) { printf("x[%d][%d]==%d\n", i,j,x[i][j]); } }
return 0;
}
>>682 そのリンク先のどのへんでそう思ったんだろう
またろくでもないサイトを見つけてきたなぁ。
>>681 メモリの確保は一発でやろうよ。
--
int ** alloc2d(unsigned width, unsigned height)
{
const unsigned fieldSize = sizeof(int) * width * height;
const unsigned arraySize = sizeof(int *) * height;
int ** rtn = malloc(arraySize + fieldSize);
int * field = (int *) & rtn[height];
for (unsigned ic = 0; ic < height; ++ic) {
rtn[ic] = & field[ic * width];
}
return rtn;
}
--
>>685 unsigned 型ってずいぶん久しぶりに見たよ
K&R Cからやってる人なのかな
>>686 引き数のunsigned intは負の数を与えられるリスクを避けられる。上限チェックはするべきだけど。
サイズ保持のunsigned intはsize_tを使うべきかも知れないが、パフォーマンスを気にしたのかもしれない。
ループカウンタのunsigned intは上限値との比較で警告が出るのを回避する効果くらいしかない。
結論:>685は中途半端w
unsigned intをunsignedと書くのを久しぶりに見たんだろ。 俺も久しぶりだわ。
普通はUINTだよな。
テメーの使ってる処理系だけ
intで受け取ってマイナスならエラー返すほうが良くない? size_tだとマイナスの値でも確保しちゃうかもしれない
size_tを・・・
こういう連中が脆弱性を作るのか
その方針だと、あらゆるケースでチェックと戻り値チェックをしないといけなくなるな for 文回すときも
696 :
デフォルトの名無しさん :2009/07/18(土) 14:03:49
すいません、おしえてください。 入力された文字列を逆の順で表示するプログラムをつくりたいのですがうまくいきません 解答をみたら簡潔な答えがのってあって理解できたのですが、なぜこれではうまくいかないのでしょうか? #include <stdio.h> #include <string.h> int main(void) { char str1[80],str2[80]; int a,b; a =0; printf("文字を入力してください(80文字未満)\n"); gets(str1); b = strlen(str1); str2[b] = '\0'; for(;str1[a];a++) strcpy(str2[b-1],str1[a]); /* もしくは str2[b-1] = str1[a]; */ printf(str2); return 0; }
>>696 strcpy()は何をする関数なのか、よく考えてみよう。
>>696 取り敢えず初心者なら、forは必ず{}で囲む習慣をつけましょう。
で、bの値はstrlen()の結果を入れた後ずっと変わらないよね。
それでいいのかな?w
> 取り敢えず初心者なら、forは必ず{}で囲む習慣をつけましょう。 どうでもいい。 囲んでない人は、上級者になったから囲まなくなったってわけじゃないし。
700 :
696 :2009/07/18(土) 14:12:26
すいません for(; str1[a] ; a++ && b++) でおねがいします
701 :
デフォルトの名無しさん :2009/07/18(土) 14:14:32
>>697 独習Cにソースの内容をターゲットにコピーするとかいてありました・・・
>>698 すいません。forの後にタブいれといたんですが消えたみたいです
>>700 for(; str1[a] ; a++, b--)
str2[b-1] = tr1[a];
703 :
デフォルトの名無しさん :2009/07/18(土) 14:25:02
>>702 ありがとうございます!ちゃんと動きました
でもまだなぜstrcpyが駄目なのかちょっとわからないです・・・
>>703 str → string → 文字列 → (末尾に'\0'の格納された)char配列
strcpy → string copy → 文字列のコピー → char配列のコピー
char をコピーしたいんであって、char配列をコピーしたいわけじゃなかろ。
っていうか、教科書にstrcpyの実装書いてあったじゃろ。普通なら。
>>703 strcpy(&str2[b-1],&str1[a]);
は、
for(;str1[a]; a++, b++){
str2[b-1] = str1[a];
}
と同じだから。
706 :
デフォルトの名無しさん :2009/07/18(土) 14:35:12
>>704 それがターゲット、ソースとしかかかれてなくて・・・
要するに文字列をコピーする関数だから配列の中身ひとつひとつをコピーすることはできないってことでいいでしょうか?
こっちのほうがわかりやすいよ #include <stdio.h> void rvs(char *p) { if(*p) { rvs(p+1); putc(*p, stdout); } } int main(void) { char str[] = "123abc"; rvs(str); return 0; }
708 :
696 :2009/07/18(土) 14:39:35
>>705 > strcpy(&str2[b-1],&str1[a]);
コンパイルはできましたが正しく動作しませんでした。
あ、インクリメント部で&&ってつかわなくてもコンマで代用できるんでしょうか?今まで
ずっと&&をつかってたんですけど、こっちのほうがうちやすいですね
&&を使う意味が
710 :
696 :2009/07/18(土) 14:40:34
>>707 ポインタは次の章から勉強なんでまだわからないです><
ごめんなさい。でもありがとうございます
>>706 その教科書は古紙回収に出したほうがいいかもw
>文字列をコピーする関数だから配列の中身ひとつひとつをコピーすることはできない
そんな感じ。頭にstrのつく関数は基本的に配列に対して作用します。
712 :
デフォルトの名無しさん :2009/07/18(土) 15:04:47
>>711 よくわかりました!どうもありがとうございます
>>708 >709も書いているけど、&&は,とは意味が全然違うから要注意。
そもそもなんで&&なんて発想が出てきたのかそのほうが興味深い。
きっとaが0のときはbをインクリメントしたくなかったんだよ
__stdcallと__cdecについてなんですが、 __cdeclは可変引数を取れるメリットがあって、Cの標準的な呼出規約ということですが、 自作関数なんか作るときは、Cであっても__stdcallを意識的に付けるほうが速度的には望ましいんでしょうか アセンブリコード見てたら、引数が決まってる場合には__stdcallの方が良さげですよね もっとも学校の課題レベルの私 & 今の時代に数バイト単位のコードの違いを気にする必要もないのかもしれませんが __stdcallのデメリットみたいなものがあったら、教えて頂きたく思います
>>715 環境依存のキーワードだから、どこでも使えるわけではない。
# __cdeclも同じデメリットを持つけどねw
速度面を気にするなら__fastcall使えよ。 あと、大抵はコンパイラオプションで呼出規約を指定していない関数の呼出規約を選べるので、 そっちで指定するという手もある。そうすると今度はmain関数に__cdeclを指定する羽目になるんだけどね。
どっと演算子についてですが kouzou.nameにアクセスするときは kouzou.nameという場所に行くのでしょうか? それとも kouzouという構造体の先頭アドレスから 何番目にnameがあるのかわかるからでしょうか?
先頭からのバイト数
>>718 後者
でもそれを実際にkouzou.nameという名前でアクセスできるんだから
プログラマが「kouzou.nameという場所がある」と認識しても不都合はないと思う
720の補足 つまり、kouzou.nameにアクセスするとき、 実行時に「kouzouのアドレスを取得してnameのオフセットを加算して…」とやってるわけじゃなくて、 コンパイル時にkouzou.nameのアドレスはわかってる 一般の変数をアクセスするのと、kouzou.nameをアクセスするのは、手間としては一緒です
722 :
718 :2009/07/18(土) 21:38:35
>>721 もし構造体のメンバに
メモリを動的に確保したものがあった場合って
どうするんでしょうか?
これだとコンパイル時にアドレスの場所わかりませんよね?
後で動的に確保するならメンバにポインタをもつだけでいいじゃない
>>722 そりゃまあそのとおりで、構造体メンバがポインタ型なら、間接参照の手間はかかる
この場合は、一般のポインタ型変数と同じと思えばいいかも
たとえば
struct A { int n; char *p; } kouzou;
char *p;
という2つの変数があって、
kouzou.p = malloc(100);
p = malloc(100);
とメモリを割り当ててるとしたら、
kouzou.p[10] = 'A';
p[10] = 'A';
はどっちも同じ手間
たぶんだけど struct A { int n; char *p; int n2; } kouzou; kouzou.p = malloc(100); とメモリを割り当てた場合、kouzou先頭からn2までの場所が 変わってしまうと思っているのでは無いだろうか。
726 :
718 :2009/07/18(土) 22:39:44
>>725 そう思ってしまいましたが
よくよく考えてみると
ポインタにはアドレスしか格納されてないんで
場所はコンパイル時と変わってないんですね
ありがとうございました。
727 :
デフォルトの名無しさん :2009/07/18(土) 23:19:18
a1からh8なら縦横の位置を出して qが入ると終了する。どうするの?
728 :
デフォルトの名無しさん :2009/07/18(土) 23:20:08
ダブルポインターがよくわかりません。 ファイルの1行目に2行目以降の各行に含まれる文字列の数が記述され, 2行目以降はその数の不定長文字列が空白で区切られているような入力ファイルを読み込み, 各行を以下に示す構造体の単方向連結リストに保存するプログラをを作成せよ. ここでは,attributes が1行分のデータを保持する. struct t_list { char **attributes; struct t_list *next; }; という課題が出ているのですが、 **atributes がどういうしくみになっているのかがわかりません。 たとえば、入力ファイル中に abc defg という一文があったときに、 strtokを使い、" "(←スペース)を区切り記号として分割したとして、 それをどのように attributes にいれていけばよいのでしょうか。 どなたか解説していただけないでしょうか。
別にどうもしない。
みならいエスパーさん、お呼び出しです
ふんふん、それで?
>>728 strtokは紙とペンがないと説明しにくいなー。サンプルコードでいい?
まず、ダブルポインターって世間には通じない ポインターのポインターのことならそう書いたほうがいい
ダブルポインタはほとんどの場合、文字列の配列に対して使われるのだ。 だからダブポと聞いたら、「それって日テレ?」と直感するくらいの気持ちでいいのだ。 それを念頭に、ではこれをご覧ください。 int n = 一行目から読み取ったx行目の文字の個数; char *c[n]; c[0] = "x行目の最初の文字列"; c[1] = "x行目の2番目の文字列"; c[2] = "x行目の3番目の文字列"; c[n-1] = "x行目のn番目の文字列"; char **attributes = c; 構造体にcの長さ、つまりnも格納しておかないと 面白いことになるぞ。
735 :
デフォルトの名無しさん :2009/07/18(土) 23:37:30
>>732 ありがとうございます。
ちなみに、
fgetsでファイルを読み込んで、for文でstrtokしています。
for(token=strtok(str, DELIMITER); token!=NULL; token=strtok(NULL, DELIMITER))
strには読み込んだ文字列が入っていて、
char *token;
#define DELIMITER " "
となっています。
しかし理解しているのかと聞かれると、正直理解していません。
今回の質問はstrtokした後に**attributesにどういれるのか、だったのですが、
strtokについても解説していただけると、とっても助かります。
736 :
デフォルトの名無しさん :2009/07/18(土) 23:50:48
>>733 ご指摘ありがとうございます。
>>734 なるほど。
1文に2つ以上文字列があった場合は、
どうやって**attributesにいれればいいですか?
(2つ目以降の文字列の処理です。)
2次元配列みたいな考え方でいいのでしょうか。
>>735-736 strtokは、新しい文字列領域を自動的に確保(malloc())してくれるわけじゃなくて、
元々あるchar配列(ここではstr)の要所に'\0'を挿入しながら、複数の文字列を作っていくしくみ。
たとえばファイルから読み込む1行が80文字以内だとすれば、
それを分割すると最大40個のトークンができるから、
char *tokens[40];
か、それに相当する動的配列をで用意しておく。
で、strtok()で切り出されてくる文字列の先頭アドレスpをtokens[i++] = p; みたいに入れていく
最後に、
char **attributes
にたいして、
attributes = &tokens[0];
とすれば、1行ぶんの分割が完了。
738 :
デフォルトの名無しさん :2009/07/19(日) 00:09:09
>>737 そうか、切り出したトークンの1つ1つのアドレスを
attributesに渡していけばいいんですね。
おおまかな流れはつかむことができたのですが、
いまいちattributesがポインターのポインターである意味が理解できていません。
attributes = &tokens[0];
として、トークンの数が2つ(以上)だったとき、
例えば、先の例に当てはめると、
abc defg
はどのように保存されているのでしょうか。
*attributes[1] = "abc";
*attributes[2] = "defg";
でしょうか?
*attributesは何で、**attributesが何なのかがいまいちわかっていません。
要領が悪くてすみません。
739 :
デフォルトの名無しさん :2009/07/19(日) 00:10:37
あ、すみません *attributes[0] = "abc"; *attributes[1] = "defg"; に訂正してください。
そのアスタリスクいらない attributes[0] = "abc" attributes[1] = "defg"
attributesは文字列の先頭へのポインタの配列の先頭へのポインタ ポインタへのポインタだから**になる
742 :
デフォルトの名無しさん :2009/07/19(日) 00:29:07
ふむふむ。。。 attributes には文字列の先頭、ここでは'a'のアドレスが格納されていて *attributes にはattributes[0]のアドレスが格納されていて(あれ?) **attributes とはなんなんでしょう。 ほんとすいません...
743 :
デフォルトの名無しさん :2009/07/19(日) 00:34:12
**c と *c[] って同義ですか?
□->■->abc ■->defg
>>743 **cという「式」は常に*c[0]やc[0][0]と置き換えられるが,逆は成り立たないし,式でない**cも置き換えられない.
アセンブラやってればわかりやすいんだけどなあ・・・・
747 :
デフォルトの名無しさん :2009/07/19(日) 00:48:48
>>744 一瞬にしてもやもやが晴れました。
>>745 なるほど、ありがとうございます。
ご協力いただいたみなさん、ありがとうございます。
さっそくカタカタやってみます。
なるほど、外野からだけど、正直自分もこのへんわかってない でもこういうのって、アセンブラをやれば理解できるのかー。いい機会だしアセンブラサイトなんか当たってみます
CASLでOK
やっぱポインタ関係のこういう話は、図なしに説明すんの難しいなあ
とおもったら図キター
>>744
こんなのポインタの基礎じゃないの?
ここをどこだと思ってる?
>>751 アセンブラ知ってないとその辺が想像できない人がいるのよ
ポインタで挫折するってのは有名な話じゃん
俺は逆にC独特の記述で悩んだよww
ダブルポインタの有効な使用例を2, 3言えなきゃダブルポインタを理解しているとは言えない
↑さあ言ってみましょう
ん?反論が無ければ俺の勝ちだが?
入門編スレで解説もしないで
>>754 のようなのは恥ずかしいと思うけど
ん?言えなければ俺の勝ちだが?
俺の勝ちとか、恥ずかしいにも程があるw
君の勝ちでいいよおめでとう。言ったところで俺には何の利益もない。
761 :
デフォルトの名無しさん :2009/07/19(日) 01:33:15
>>760 教える気が無いのならもうこないでくださいね〜^^;
顔真っ赤な奴がいてワラタ
すぐ勝ち負けを言い出す奴って決まってアホしか居ないな
764 :
デフォルトの名無しさん :2009/07/19(日) 01:45:11
とりあえずJavaの話しようぜ 後、入門篇とか謡っておきながら入門者に冷たすぎるねC厨は・・・ これからCを始めようと思ってる皆さん、親切なJavaスレに行きましょうね
ところで何でこの手の板ってID付かないんだろうな
スレ違い
なんか失敗発言しやすい話題だし、そしたら一日中恥ずかしいから
納得した
>>764 それが良い。
お前みたいなゆとりはJavaでもやってろ。
OS:WindowsVista 開発環境:VisualC++2008ExpressEdition テキストファイルを読み込んでExtTextOutで表示する動作についてです 半角英数記号は正常に表示されるのですが 全角文字は文字化けしたり別の文字になってしまいます 例えば「テスト」と表示したいのに「eXq」となってしまいます テキストから読み込んだ文字列をいったん変数へ代入しておいて その変数を使用して全角文字を表示するにはどうすればいいですか? よろしくお願いします
いやいや そんなマルエツドザ専用のコード出されましても(^^ゞ
というか環境依存だからここの趣旨とは違うけどな
LPCTSTR str = _T("Ver***byKKK"); これは環境依存しねーだろ
Windowsという環境に依存してますが。
は?
マクロはwindowsに依存しませんが?
L" ほげ"に展開されたときにアウト
>>771 ありがとうございます
wchar_t ss[256];
wcscpy(ss, TEXT("テスト"));
ExtTextOutW(hDC, 0, y, ETO_CLIPPED, NULL, ss, wcslen(ss), NULL);
これなら表示できるのですが
wchar ss[256];
fp=fopen("hoge.txt","r");
fgetws(ss, 256, fp);
ExtTextOut(hDC, 0, y, ETO_CLIPPED, NULL, ss, wcslen(ss), NULL);
これだと文字化けしてしまいます
何が違うのでしょうか?
× ExtTextOutW ○ ExtTextOut × wchar ss[256]; ○ wchar_t ss[256]; です、すいません
hoge.txtの中身の問題だろ
>>782 どこに「バイナリモード」云々と書かれているの?
そもそもその記事のどこがCの話?
まず ・hoge.txtにはどういう文字がどういう文字コードで格納されてるの? ・文字化けするというパターンでバイナリレベルで文字コードはどうなってるかみてみた? たぶんこれだけ確認すればおおよその絞込みはできそうなんだが
>>779 テキストファイルのエンコーディングが適切でないのでしょ。
>>781 txtの中身は
1行目に「テスト」で改行が1回です
>>782 試しに_wfopenしてみましたが同じでした
>>786 だから、そのテキストファイルのエンコーディングが何か、が問題。
>>771 >>してマルチバイトでもユニコードでもコンパイルできるようにした方がいいと思います。
汎用テキストマッピングは無意味だから、ワイド 文字きめうちのほうがいい。
>>783 お前は他人が出したヒントにあおりいれるだけかよ
setlocale vc++ で検索してみつけたからヒントとしてだしたんだよ
>>784 Stirlingでtxtを見てみた所
83 65 83 58 83 67 0D 0A テスト..
って表示されてました
>>789 あんたは他人が出した指摘に逆切れ気味にレスするだけかよ。
C++の話題を書きたいならスレ違いだから指摘したんだよ。
>>790 INはそれだよね
じゃあ
OUTはどうなの?
ファイルオープンして読み込みが終わった際のコードの状態
>>787 すいません、書き込んだりバイナリエディタDLして調べてる間に
785さんが書き込んだので飛ばしてしまいました
>>792 >OUTはどうなの?
>ファイルオープンして読み込みが終わった際のコードの状態
wchar_t ss[256];
fp=fopen("hoge.txt","r");
fgetws(ss, 256, fp);
ExtTextOut(hDC, 0, y, ETO_CLIPPED, NULL, ss, wcslen(ss), NULL);
これの事ですか?
見当違いな事言ってたらすいません
>>790 それどう見てもShift_JISじゃん。
fgetwsで読むならwchar_tのエンコーディングに合わせろよ
>>794 >792の言いたいことは、そのssをダンプしろってこった。
つーか、そもそも本当にCの質問なのか?
>796 が言ってるように入力完了後のwchar_t ss[256];に格納された文字コードがどうか確認するってこと テキストなんて所詮は人間が見やすくした物で文字化けしてるしてる言われても それだけじゃあわからないからw
798 :
797 :2009/07/19(日) 11:04:27
エンコーディング調べてみます ssのダンプの仕方わからないのでそれも調べてみます ありがとうございました
>>799 >796
ついでに言えば、メモリダンプなんてのはデバッグ機能の基本中の基本だ。
VisualStudio使っているなら、fgetws()の次に実行されるコードにブレーク張ればいいだろ。
# 勿論、その詳細もスレ違い。
802 :
デフォルトの名無しさん :2009/07/19(日) 13:22:14
こんな事したいんですけどC言語のソース書いてください 100以下の整数を入力し80以上なら”優”、70以上80未満なら“良”、60以上70未満なら“可”、60未満なら“不可”と表示する。tenに格納された値が不なら終了する。 条件:scanfの前にprintf(”点数を入力してください”);を入れる。whileを使いマイナスの値が入力された場合終了し、100〜0の場合ループさせる。ifを使う
rubyなら書いてあげたのに
>>795 それは違うだろ。fgetwsのようなワイド文字入出力って文字コード変換するんだぜ。
初期状態だとC localeだから、ASCII文字しか変換しない。
そこで、予めsetlocale(LC_ALL, "");を呼んでおく。
すると、適当な文字コード(日本語WindowsならShift_JIS)での変換が行われるようになる。
>>800 スレチなのわかってるから調べに行ったんだろ
最後の1行いらんと思うが
関数の意味が全然わからないので質問させてください もしかしたら日本語でおkとか言われるかもしれませんがよろしくお願いします 例えば、main関数で数値を入力して関数○○に渡して計算しなさい、計算結果は関数側で表示する こういう問題があったとしたら、この関数側とはどういう意味ですかmain関数のことですか?○○関数のことですか?
>>809 それは問題だした教師に言ってやるべきだなw>日本語でおk
まあきっと、○○関数のほうで表示しろという意味
>>809 mainじゃない関数です。
つまり計算+表示を担当する関数を作れってことですね
こういう問題だす講義では嫌がらせに最大限可読性のないコードを提出することにしてるわ
813 :
809 :2009/07/19(日) 14:57:57
全部トライグラフで書くとかw
おー。VC++で文字列リテラルをあらわすときは _T("文字列")と書いておけば、TCHARと同じで 自動的にchar配列かwchar_t配列に変換されてくれるのね。 これは知らなかったよ。
それはC言語の領域ではないが…
だがしかし、その実装は興味深い。 #ifdef _UNICODE #define _T(s) L ## s #else #define _T(s) s #endif 「##ってこういうときに使えるのか」と感心した。
まあ入力側の文字データがちゃんと入力されてるかどうかを確認すればいいだけなんだけどね。 表示される段階の文字が化けてる化けてるとか言われても所詮は人間に都合のいい情報なだけで どう化けてるかなんてコードレベルでみないとわからねえし
>>820 そんな事わかるやつがこのスレで質問するとは思えんが
「俺はできる」って自己主張したいんですかそうですか
824 :
823 :2009/07/19(日) 15:45:57
atoiと_wtoiとを自動的に振り分けてくれるようにするにはどうしたらいいのだ。
>>826 自分でファイルをバイナリモードで読み込んでどういうコードか判断するしかないんじゃね?
828 :
デフォルトの名無しさん :2009/07/19(日) 18:11:01
char *str; と char str[256]; の違いについて質問があります str[256]は256文字以上あふれるとバッファオーバーフローの危険性があると思うのですが、 char *str; の方は無限に文字を入れることができるということでしょうか? strcpyなどで何文字を代入してもPCメモリが存在するだけ文字が入っていくのでしょうか? 回答よろしくお願いします。
有限です それどころか*のほうは明示的にメモリを確保しないと1バイト分もありません 残念でしたね
>>828 ポインタの指す先が256以上確保されてなかったら、やっぱ256であふれる。
>>828 確保したとしても、その制限とPCメモリのサイズには何ら関係がない
>>828 char *str;
は char c とかがあった時、cのアドレス = &c を格納できるだけの領域しか持ってない。
char ary[256] とかがあった時、先頭のアドレス ary (= &ary[0]) を持ったりするのに使う。
文字列リテラル "hogehoge" なんかは宣言したときその文字列がメモリに確保されるが、
その先頭アドレスを保持して参照したりできるように char *str = "hogehoge"; とかってする。
char *str はただの char型アドレス を保持できるだけの領域(32bit環境なら32bits=4bytes)しか持っておらず、
n文字確保したいときは malloc() などでメモリ上に領域を確保して、その先頭アドレスを *str に保持して使う。
char *str;
scanf("%s", str);
とかいうコードはバッファオーバーフローっていうか str の指す先が不定で落ちる可能性が高い
>>828 □を1バイトとするとまあ最近のCPUだと
char *str;
は
□□□□
char str[256];
は
□□□□・・・・□□□□と256個確保されます。
テキストしか使えないので
char *str;
の
を■一つでたとえた場合は
■->
という状態ができただけで矢印の先は不定です。
malloc(sizeof(char)*256);
とすると
□□□□・・・・□□□□と256個確保されます。
この確保した256分の先頭アドレスを
■の中に入れてあげると
■->□□□□・・・・□□□□
という形になります。
素直に落ちてくれれば未だいいけどね。
最悪の場合人類が滅亡するからな
軍事関係か
Cでデストラクタ実現するイイ手法を教えて。
ガベコレを実装してそれで我慢
はぁ?
Cでデストラクタ実装しなきゃらならない ってプロになったらあるんですか? どんなときでしょうか?
どうしてもデストラクタが必要なら、C++を使うよ。
モジュール毎処理に特化した独自スタックでも用意するしかないのかな
844 :
デフォルトの名無しさん :2009/07/20(月) 09:39:59
ここではcharは文字列しか入れられないって認識でやってんのか?
さて、釣りに出かけるか
charなんてCの型にはないし、charだったとしても文字列は入りませんよ。
#pragma once #ifndef HOGE #define HOGE #endif 結局どっちがいいの?
#pragmaはVisualC++の独自記述で 他コンパイラにも対応させようと思ったら#ifndef
gccとVCで対応してれば標準。
そして、同じヘッダがなぜか複数のディレクトリにあって嵌る
ヘッダファイルとかにある # endif とかのおまじないはなんなんでしょうか?
852 :
デフォルトの名無しさん :2009/07/20(月) 17:46:05
if を endするためのおまじないです
文字列の部分比較でchar型配列のbuff[128]の先頭3文字が「cd(バックスペース1文字)」であることを調べるには strncmp(buff,"cd\b",3) だと駄目なのですがこれはどう直せばいいのでしょうか?
バックスペースの文字コード(制御コード)は0x08なので 小文字の場合は 0x63,0x64,0x08 大文字の場合は 0x43,0x44,0x08 という比較用データを容易して比べるといいかも?
テキストファイルに↓の内容があり、 10000 20000 30000 それを上書き保存モードで開き、 2行目に"40000"をfprintfで出力し、 結果的に20000を消し、40000にする やり方がありましたら教えてください。 fseekで2行目に動かしても(ftellで7の状態)、 4行目に40000が出力される形になります。
全部読み込んで、いじって、全部書き込む
859 :
856 :2009/07/20(月) 19:34:28
ありがとうございます。
>>857 基本はそのやり方ですよね。
>>858 "a+"でやっていました。
"r+"でやったらできました。
int型の配列を比較するにはどうすればいいのでしょうか? memcmpはchar型しかできないようなので。自分で関数を作るしかないのでしょうか。
int memcmp(const void *buf1, const void *buf2, size_t n);
大抵の場合は memcmp でもいいんじゃないかな。 いいんじゃないかな。 「int に未使用ビットが存在し、バイト配列として比較すると一致する保証がない」 ような変てこりんなシステムだとそうもいかないだろうけど。
最近じゃ、memcmpの引数はvoid*型になってないか?
>>861-863 ありがとうございます。void型だとどんな型でも代入できるんですね。もう一度試してみたらうまく出来ました。
・・どこが違ったんだろう(;´∀`)
866 :
デフォルトの名無しさん :2009/07/21(火) 09:57:12
>>864 うまくできたって、コンパイル通っただけじゃないよね。テストもしたよね。
>>865 memcmp()を使うのにキャストが必要だと?
>>860 無理にmemcmp()を使うよりも自前で比較ループを書いた方が最適化が利くかもよ。
質問させていただきます。 | 1 2 3 -------- 1 | 1 2 3 2 | 2 4 6 3 | 3 6 9 柴田望洋『新版明解C言語入門編』のP78演習4-15で、上記のような形の 九九表を作る問題があるのですが、九九表の上部にあたる | 1 2 3 -------- の部分をうまく表示させることができなかったため、無理やり次のように 書いてしまいました。 int tate, yoko; puts("九九の表を表示する。\n"); puts(" | 1 2 3 4 5 6 7 8 9\n-------------------------------"); for (tate = 1; tate <= 9; tate++) { printf(" %d | ", tate); for (yoko = 1; yoko <= 9; yoko++) { printf("%2d ", tate * yoko); } puts("\n"); } もっとすっきりした書き方を考えたのですが、思いつきませんでした。 どのように修正するべきでしょうか。
printf(" |");
for (yoko = 1; yoko <= 9; yoko++) {
printf("%2d ", yoko);
}
printf("\n");
for (yoko = 0; yoko <= 9; yoko++) {
printf("---", yoko);
}
printf("\n");
みたいにすればいいけど(幅とかは調整必要)、多分
>>868 の方法が一番単純。
>>868 サイズが9×9で決め打ちなら、それで十分でしょ。
もし物足りないんだったら、サイズが変えられるように
void print_table(int size)
{
/* 表を描く処理 */
}
みたいな関数を作ってみるといいんじゃない
あとputs()を使うと自動改行でかえってわかりにくくなるので
全部printf()にしたほうがいいとは思う。
どうせなら、 printf(" | 1 2 3 4 5 6 7 8 9\n" "-+-----------------------------\n"); と書こう。 # 勿論インデントも揃えると。
>>869 ありがとうございました。
もし表の計算範囲を変える場合には、
>>869 さんが
書いて下さった方法がわかりやすいですね。
参考にさせていただきたいと思います。
873 :
869 :2009/07/21(火) 13:13:00
>>870 ご指摘ありがとうございました。
まだ関数の部分まではテキストを読んでいないため、
そこまで進んだときに改めて考えてみようと思います。
それから、たしかにputs()は不適切でした。修正します。
>>871 ありがとうございます。
2段に分けて記述する方法がわからなかったため、
読みづらい書き方をしてしまいました。それぞれを
""で囲むことで分割できるということですね。
これからは注意していきます。
874 :
868 :2009/07/21(火) 13:14:34
875 :
デフォルトの名無しさん :2009/07/21(火) 17:13:17
フォーマット指定子のフィールド幅を動的にすることはできない? sprintfでフォーマット作ってprintfとかするしかないかな
878 :
デフォルトの名無しさん :2009/07/21(火) 17:55:46
別スレで書き込んだのですが、もう一度ここで質問させて下さい 文の格納に必要なバイト数をJISコードの場合とシフトJISコードの場合のそれぞれで計算する問題なのですが、これはどうやって考えれば良いのですか? 漢字、カタカナ、英数字(半角)、記号で構成されている文です 曖昧な質問で申し訳ないのですが、ここでは課題の文を晒せないので、よろしくお願いします><
libiconvみたいなライブラリを使うんじゃなくて、自力で長さを調べる問題ってこと? JISやシフトJISの仕様を見て、1文字ずつ判定してくんじゃないかなあ・・・
>>878 宿題なら宿題スレに、そうでないなら文字コードの問題なので文字コードスレに。
その元データはどうやって取得するの
俺Algol60しか書いたことないんだけど Cって難しいですかね?
>>882 begin -> {、end -> }、:= -> =
これであなたもC使い
ALGOLにはポインタはない。 はじめにポインタ(->)を使った言語はなんだろう?PL/1かな?
PL/1はIBMが作った汎用言語でOSもPL/1で記述されていたらしい。 日本のメーカーはPL/1をまねてSPLという言語を作って、それで独自のOSを開発していた。 インテルが作ったPL/Mというのもあった。 みーんなCに置き換わっちゃった。
, .-‐'''' ^ ''''ー 、 / : : : : : : : : : : : \ /: : /  ̄ ̄ ̄ 、 : i だんねんながら !: : l l: : ! ニーブにぎゅういちは l: : :! 一 ー !: :.l 発毛の効果を100パーネント /: : !_ィェァュ ii ィァュ_ }: :ヽ 実証するものではございまねん -―-、 ! Y Y / ‐ ー、 / ,ー ― 、i ヽl ! 、_ , ! !/ ハ \ ! i ニ ニ l ! ! / ィ===ュヽ ノ /⌒ヽ、 \ ヽ ヽト _ ィ \! ヽェェェ イ ! イ/  ̄⌒ヽ _ l/ ⌒ ‐-、 - ヽ } i i′ _.イ i\ _/ノi\ i / 人 ___ ヽ ,= !│ /ヽ_,. .ー' ̄/:.:.:.i \  ̄´ / |:.:.:ヽー 、__!, ! / __ ` 、 !丿厶 ー:.:.:.:.:.:.:.:./:.:.:.:.:.:ヽ / ‐ く /:.:.:.:.:.\:.:.:.:.:.:.ヽ| ェュ ィァ i ‐- ノ {:.:.\:.:.:.:.:.:.:.:.:.:.\:.:.:.:.:.:.:V 、 人 l:.:.:.:.:.:.<´:.:.:.:.:.:.:.:.:.:.ヽ || ! _/ | i|:.:.:.:.:.i:.:.:.:.:.:.:.:.:.:./:.:.:.:.:.:.:.i /~ヽ !:.:.:.:.:.:.:.:\:.:.:.:.:.:.:.:.:.:∧=- イ / |:.:.:.:.:.:.:l:.:.:.:.:.:.:.:.:ヽ:.:.:.:.:.:.:.:.:l/ ∨:.:.:.:.:.:.:.:.:./:.:.:.:.:.:.:.:.:/:..:i __/ l
>>885 一応抽象化されたアドレスならアセンブラのマクロ
参照という意味ならLISP
低水準高級言語という意味ならBCPL
char **str; *str[0]="ぱぽい"; *str[1]="greeeen"; *str[2]="ガッ↓"; ってやると 自動的に **strにはchar型へのポインタの要領*3 *str[0]には6byte *str[1]には8byte *str[2]には3byte って感じで割り振ってくれるんでしょうか?
いいえ違います
char *str[] = { "ぬんぱら", "とんぷるぴん", "あめんほてぷ" }; こうすればOKです。
には6byte には8byte には3byte あと文字数の認識もおかしい
>>893 C言語では文字列の最後に、終端文字というものがつきます。
int *mem=malloc(sizeof(int)*10); ○ *mem=malloc(sizeof(int)*10); × mem=malloc(sizeof(int)*10); ○ int mem=malloc(sizeof(int*10); × 宣言のときはできたとに 普通にやるとできなくなったりするのですが なぜこういうことがおきるのでしょうか?
>int *mem=malloc(sizeof(int)*10); ○ これを分解すると int *mem; mem = malloc(sizeof(int)*10); とも書けます。 >*mem=malloc(sizeof(int)*10); × >mem=malloc(sizeof(int)*10); ○ >int mem=malloc(sizeof(int*10); × これはint型の変数memにポインタを入れようとしてるので駄目です。 ちなみに >int *mem; は int* mem; とも書けます。 int*はint型のポインタですよということです。
>>895 int *mem;
とすると、int型の *mem という名前の変数を定義したことになる。
Cでは、変数名の最初が*で始まる場合、その*を取り除くとポインタを取り出すことが出来る
というルールがある。
別の考え方として
int *mem;
とした場合、int型の *mem と、intへのポインタ型の mem の二つが定義されると考えても
いいかもしれない。
宣言構文勉強しなおせ、アホどもが。
そういう構文をいまさら解説してるサイトはすくないような・・・ int* mem; int *mem; どっちも書けるしコンパイルも通るよな・・・ 後者で解説してるサイトが多いけど、イメージとしては前者の方がわかりやすいんが
イメージとして int* 型の mem という方がわかりやすいのはその通りなんだが、 一方で int* mem1, mem2; のように宣言すると勘違いしやすいからな・・・
901 :
899 :2009/07/22(水) 13:38:41
>>900 ふむ
カンマでだらだら書いていけるから変数側にアスタリスクつける方がいんだろうけどなあ
そういう細かいところがCって洗練されてない気がするわ
洗練?なにいってんだこいつ
たとえばint で変数もポインタもカンマで区切ってしていできない使用になってないのが駄目ってことじゃないの? int *p,a; と書けるのをよしとしないで int* p; int a; と分ける
うわ、誤字とかむちゃくちゃw していできない使用になってない 指定できない仕様になってない
>>903 俺もポインタとそうじゃないのを一緒に書くのは好きじゃないな
windowsならポインタもtypedefしてあるのを使う
LPINT a, b, c;
int i, j, k;
みたいな
しかし、Windows APIが多用する「別名」は バージョンがあがるといつの間にか実体が変わってることあるんだよね。 機種依存部分だからカプセル化するべきだし、実際そうするわけで、 結局、使える場所はごく一部に限られてくる。
ここはいつ来ても使えない奴らばかりだな
人を使うことしか考えてない奴とは関わりたくないからちょうどいいよ
∧__∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ∩゜Д゜)< m9(^Д^)プギャー □………(つ | \________  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|
プログラムで3次元配列を「これぐらい用意すれば十分だろう」っと自分で数を決定していたのですが プログラムを使ってる人の入力に対して必要な配列の数を計算し3次元配列を作るにはどうやればいいでしょうか? 書籍調べててメモリの動的割り当てを使って任意の1次元配列を作る例を拡張してできないかと 考えてはいるのですが上手い方法が思いつきませんでした。
>>911 ありがとうございます
これ参考にちょっと考えて見ます
ついでにこのページに他とは違ういろいろ突っ込んだ項目が書いてあるので読んでみよ
あとmalloc()は重い処理なので一度に必要な領域を確保して 後はポインタ配列を後から確保してアドレスを代入するという 方法もよく使われるが、二次元配列を超える配列でやろうとすると 頭のパズルになる
↓のコードなんですが*pにrxBufのアドレスが入りません。 何か問題ありでしょうか? a.c static char *p; static void errorOp(void) { if(getRxData(p) == 0){ rxDataProcess(); } } b.c static char rxBuf[10][10]; char getRxData(char *dt) { int i; if(rxDataManage.wtPt != rxDataManage.rdPt){ dt = rxDataManage.rxBuf[rxDataManage.rdPt]; return 0; } else{ return -1; } }
pを書き換えたいならpの参照を渡せよ。
char getRxData(char **dt) { int i; if(rxDataManage.wtPt != rxDataManage.rdPt){ *dt = rxDataManage.rxBuf[rxDataManage.rdPt]; return 0; } else{ return -1; } }
自作関数なんかを プロトタイプ宣言をmyfunc.h その実体をmyfunc.cなどと2つ作った場合、それをmain.cから利用しようとしたら、 Borland Turbo C++の場合、 > bcc32 main.c myfunc.c などと指定しなければなりませんよね でもstdio.hなどは、ただstdio.hをインクルードするだけでprintfはじめ関数を利用できます で、それらインクルードの関数の実体はlibファイルに定義されていると聞いたことがあります ということはstdio.hの中では、.cファイルではなく、.libを使うという定義がされているんでしょうか?
gcc なんかだとlibを指定すればリンクされるから同じような仕組みがあるんじゃないかな?
>>917 bcc32.exeはコンパイラのみではなく、リンカを呼び出す
仕組みも備わっている
それぞれのソースファイルがコンパイルされてオブジェクトファイルができて、リンカでオブジェクトファイルから必要な関数(アドレス)を見つけてバイナリを吐くんじゃなかったっけ
>>917 どこにあるといった情報はなく、すべての.cと.libの中から目的のものを探す
例えば自分でprintf関数を書いて、そのソースファイルを含めておけば、
.libの中のものではなくそっちがリンクされる (前から順に見て、先に見つかったもの勝ち)
>>910 いや、河野先生ところのは、それはそれでいいんですけれども、x[a*i + b*j + k] でお茶をにごすのが簡単ではないかと。
>>910 これでも使ってろ
void *dim3_alloc(int w, int h, int d, int size){
char ***a=NULL, **b=NULL, *c=NULL;
int y, z;
a=malloc(sizeof(void*)*d);
b=malloc(sizeof(void*)*d*h);
c=calloc(d*h*w, size);
if(!a || !b || !c){
if(a) free(a);
if(b) free(b);
if(c) free(c);
return NULL;
}
for(z=0;z<d;z++){
a[z]=&b[h*z];
for(y=0;y<h;y++){
a[z][y]=&c[size*(h*z+y)*w];
}
}
return a;
}
void dim3_free(void *ptr){
void ***p=ptr;
if(!p){
free(p[0][0]);
free(p[0]);
free(p);
}
}
空ポインタ int *p=0; ってのはプロでも使ってるんですか?
925 :
デフォルトの名無しさん :2009/07/24(金) 00:10:36
#include <stdio.h> int func ( int, int ); int x = 20; int y = 15; int main (){ x = func( x, 10 ); printf("@x:%3d y:%3d\n", x, y ); y = func( y, -10 ); printf("Ax:%3d y:%3d\n", x, y ); for( x=5 ; x>0 ; x-- ){ func( 10, 5 ); printf("Bx:%3d y:%3d\n", x, y ); } return 0; } int func( int a, int b ){ int y; if( a > b ){ y = 5; x = -10; } else{ y = -5; } return y; } これの表示が @x: 5 y: 15 Ax:-10 y: 5 Bx:-10 y: 5 となるんだが意味ワカンナイ だれか教えてください
>>925 変数のスコープの勉強でもしてんのかな。
じっくりおえば分かるからがんばって
>>924 あたりまえに使うが、空ポインタっていう呼び方はしないな
>>925 まずどこがわからないのか?
1行目からか?
わかるところとわからないところをはっきりさせるべき
>>924 そりゃプロもピンキリだから。
ヌルポが0000:0000とは限らないから本当はやるべきじゃない。
大多数の環境では0だから、それで暴走することは滅多にないと思うけど
だからやってもいいという理由にはならない。
>>931 何言ってんの?ポインタに0を代入するのは特別な扱いを受ける
事も知らずにでたらめ書くなアホ
>>931 ソース上の0は常にターゲット環境でのぬるぽを意味する。
ゼロというかNULLを使う方が多いだろ 直接0を入れるのはケースにもよるが・・・
C++では基本的にNULLを使わずに0と書くので、Cでもそうする人はいる。
936 :
デフォルトの名無しさん :2009/07/24(金) 10:52:50
O = Null として扱ってるの?信じられないな。
ANSI C 3.2.2.3 Pointers An integral constant expression with the value 0, or such an expression cast to type void * , is called a null pointer constant. If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type. Such a pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
>>910 へ
malloc()が重いのでなるべく回数を減らすにはこうすればいいが
ノートに図を書いて自分でもやっと理解できた
実用的ではない
malooc()の回数が増えても
>>911 の方法がいいな
#include <stdio.h>
#include <stdlib.h>
/* 例えば3次元配列で1000000個ほど配列が欲しいとする(例えば10 * 100 * 1000) */
int main(void)
{
int i, j, k, l = 0, ***array2, **array1, *array;
array = (int *)malloc(sizeof(int) * 10 * 100 * 1000); /* 一度に確保する */
array1 = (int **)malloc(sizeof(int *) * 10 * 100); /* 例えば */
array2 = (int ***)malloc(sizeof(int **) * 10);
for (i = 0; i < 10; i++) {
array2[i] = array1 + i * 100;
for (j = 0; j < 10 * 100; j++)
array1[j] = array + j * 1000;
}
for (i = 0; i < 10; i++)
for (j = 0; j < 100; j++)
for (k = 0; k < 1000; k++)
array2[i][j][k] = ++l;
free(array2);
free(array1);
free(array);
return 0;
}
>>927 以前 宿題スレで似たようなのがあった
(最終の printf になる為には main 内の変数の初期値を求めよ って奴)
手で追うと間違えや見逃し発生しちゃうので
mathmatica とかの式評価が可能なシステムの補助が欲しいねー
>>925 の事例は結果追跡だけなので、変数名の付け替えだけですっきりするが
JISでもANSIでもいいから規格書をよく読め
ヌルポをintにキャストした時は、その処理系での本当のアドレスにかかわらず
0x0000になるが、逆は規定されていない=保証されていない
ヌルポが0と等価であることが保証されるのはC++の話。Cは上に書いたとおり。
有名なFAQにも0で代用するべきではないと書いてある。
ttp://c-faq.com/null/machexamp.html
構造体の配列で困っています。 構造体pというのがあったとして、その内容が p { char moji; } とかだったとします。このPをCallocを使って領域を確保して、 FOR文でp[1]〜p[27]までのそれぞれのmojiにアルファベットを順番に入れていったとき、 入れ終わってから例えばprintf("%s",p[5].moji)のようにすると、「e」が表示されるべきなのに 「z」が表示されてしまいます。 いったい何がおかしいのでしょうか?
>>942 %s に対応する引数は char const *
メンバーが char 型で文字だから 表示は文字列フォーマットの %s ではなく文字フォーマットの %c でやる
>>941 > ヌルポをintにキャストした時は、その処理系での本当のアドレスにかかわらず
> 0x0000になるが、逆は規定されていない=保証されていない
An integral constant expression with the value 0, or such an
expression cast to type void * , is called a null pointer constant.
と矛盾するんじゃないかな。
> 0で代用するべきではないと書いてある。
そんなの書いてなかったと思うが。
初期化時の事情とは変るけど 可変引数の終端記号として NULL を要求しているようなのは sizeof(int) != sizeof(void*) で破綻する
char* じゃなくてcharになってるのはレスする際のミスでした。実際のプログラムではchar*になっています。 さっきFOR文で文字列を格納しながら、ちゃんと文字が格納されているかprintf("%s\n",p[n].moji)(nはFOR文を回してる変数です)で 確かめてみたのですが、それだときちんと「abc・・・」となっているのです。 なのに、文字列格納のFOR文が終わってから、もう一度新しいFOR文でprintf("%s/n",p[n].moji)を順番に表示させると、 「zzz…」という風になってしまうんです。いったい何が原因なのでしょうか? 実は今規制されていまして、このレスも代理を頼んでやってもらっています。なのでお礼のレスは出来ないと思います。 すみません。これまでレスしていただいた方、これからレスしていただける方、ありがとうございます。
har* じゃなくてcharになってるのはレスする際のミスでした。実際のプログラムではchar*になっています。 さっきFOR文で文字列を格納しながら、ちゃんと文字が格納されているかprintf("%s\n",p[n].moji)(nはFOR文を回してる変数です)で 確かめてみたのですが、それだときちんと「abc・・・」となっているのです。 なのに、文字列格納のFOR文が終わってから、もう一度新しいFOR文でprintf("%s/n",p[n].moji)を順番に表示させると、 「zzz…」という風になってしまうんです。いったい何が原因なのでしょうか? 実は今規制されていまして、このレスも代理を頼んでやってもらっています。なのでお礼のレスは出来ないと思います。 すみません。これまでレスしていただいた方、これからレスしていただける方、ありがとうございます。
コピペミス
>>948 は無視して下さい
スレ汚し失礼しました
それぞれのchar*ごとに別の領域を確保しているか? 全部同じ領域を指していないか?
>>947 (
>>942 )
ソースがあがっているわけではないので、エスパー
代入しているのは ループ内で宣言されたローカルな変数へのポインタ じゃね?
ループ抜けると ループ内で宣言されたローカルな変数 は居ないから
ポインタの指している先は あれー? ってなるぜよ
配列・ポインタ・文字列 周辺をもういっかい整理してみるべし
char moji; 構造体の中ってこれだけ? これってさまず終端文字のことが考えられてないのと パディングのことを想定してるのかな?
>>949 高度な問題なのかと勝手に思い込んで時間使っちまったじゃないか
どうしてくれるんだ
954 :
デフォルトの名無しさん :2009/07/24(金) 15:40:30
fwriteのバイナリデータにするってどういうメリットがあんだ? ASCIIじゃダメなのか? バイナリのメリットってあんの?
>>954 無変換だ ということがメリット
ビットマップなんかの書き出しに たまたま登場した 0x0a が
ファイルに書く時 0x0d 0x0a なんて変換されたらかなわん
>>954 数値データなんかだとascii形式の方が可搬性が高いね
バイナリデータの必要性が感じられないなら使わなくていいよ
957 :
デフォルトの名無しさん :2009/07/24(金) 15:55:51
>>955-956 なんかむずいな。
よくわからん。
普通にプログラミングしてたら使わないか?
それとも使うか?
>>954 ASCIIではデータ量が多くなってしまう
画像なんかを保存するとき、バイナリで保存すればRGB各1バイトずつで済むのに
ASCIIで 255 255 255 なんて書いてたらファイルサイズが2〜4倍になってしまう
959 :
デフォルトの名無しさん :2009/07/24(金) 16:13:03
だから画像ファイルをみると バイナリ形式になってるってこと? なんとなくわかったありがとう。
あー ごめん fopen のモードの話とごっちゃになってた fwarite か? fprintf か? って話だな メリット 出来上がるファイルサイズを小さくおさえることができる 読み込みに楽できる(かも? 文字解釈云々をすっとばせるので速い(かも? デメリット メモ帳で編集できない メモ帳で見たところで化け化けのぐちゃぐちゃ
困ったときはK&R(第2版)。ずばり飲尿。 「標準ライブラリではテキスト・ストリームと2進ストリームをサポートするが、 UNIXのようなシステムではこれらは同じになっている」
constって値が変わらない変数やポインタにはすべてに付けたほうがいいんでしょうか?
>>962 変わらない程度ならつけようがつけまいが
むしろ変えたくないところ、変えちゃだめなところをconstにしておけば
コンパイルの段階で変えるコードをエラーで弾ける
付けた方が最適化が効きやすいかもしれない。
それは気のせい。
ROM化するときに悩めばいい
>>964 constと最適化の関係がわからない
もしかしてrestrict
restrictってさぁ、結構あちこちに付けられるところがあると思うんだけど、 面倒臭くない?
>>962 ローカル変数でやるってこと?
それはめんどくさいだろう。
>>962 > constって値が変わらない変数やポインタにはすべてに付けたほうがいいんでしょうか?
付けても付けなくてもいい場合と、
付けなければならない場合があることは理解してる?
>>970 付けなければならない場合ってどんな時でしょうか?
いまいちわかりません。
>>971 こんなん
const char *hoge(void){
return "hoge string";
}
973 :
970 :2009/07/24(金) 22:10:20
うまくないだろ・・・
せめて引数での例を出してやれよ・・・
>>938 前に質問したものですが参考にさせていただきます
度々ありがとうございます
仮引数でconstを使うと利点があるというのはわかりました。 戻り値にconstを使うということは なぜでしょうか?
まあよくconst付けて変更されるのを防ぐのはcharが多いかなあ ファイルアクセス系も引数にconst付いてることが多いし 自分で文字列から情報を調べたりする関数を作る際にも 受け取るchar型の配列(のポインタ)はconstつけるねえ
適当か?変えないつもりの変数ならとりあえず全部つけとくのもありだとは思うが
理解出来ないヤツ相手には
>>979 の様な返答もあり。
typedef int *(*ojisan)(void); これって、*(*ojisan)(void);をintという型と同じにするって意味なんですかね… typedef int NewINT; とかなら、NewINTがintとして使えるから直感的にわかるんですが この手の関数ポインタのtypedefを理解するようなコツってあるんでしょうか
関数宣言の引数の値渡し以外には全部付けてる // 宣言 const char* foo(float f, const DATA* p, DATA d); // 定義 const char* foo(float const a, const DATA* const p, DATA const d) { static const char* const ret = "くぁwせdrftgyふじこlp;@"; return ret; }
typedef int *(*ojisan)(void); は ojisan == int* (*foo)(void) を入れるための型 == int* foo(void) のポインタ を入れるための型 って考えればいいと思う #include <stdio.h> int* foo(void) { static int ary[] = {0, 1, 2, 3}; return ary; } int main() { typedef int *(*ojisan)(void); ojisan func = &foo; int* ptr = (*func)(); printf("%d, %d", ptr[0], ptr[1], ptr[2], ptr[3]); return 0; }
987 :
983 :2009/07/24(金) 23:35:44
>>985 おお、とても丁寧にありがとうございます
>>986 おつ
関数ポインタを解読するときは
型 (*関数ポインタ)(引数)
っていう基本形を覚えておくといいよ
int *(*ojisan)(void)
↓
ojisanは関数ポインタ
ojisanの引数は -- (void)
ojisanの戻り値は -- int *
>>941 見事なまでに逆を言ってないか?
0をポインタ型にキャストした場合は、内部表現が0ではない処理系においても
ヌルポインターとなることが保証されてるよ
990 :
デフォルトの名無しさん :2009/07/25(土) 01:42:18
あまり賢い方法ではないと思うが、ヘッダーファイルにグローバル配列を用意したんだ。 それを、一つのソースファイル以外ではexternをつけてコンパイルしたいんだけど、どうしたらいい? ヘッダーファイル | /\ ソース1 ソース2 ソース1ではdouble a[10]、ソース2ではextern double a[10]というふうにコンパイルしたいんでふ。
ヘッダのそれを消せばいいだけではなくて?
>>990 初期化しなかったら何も考えずにできるんですけどね。ヘッダーファイルのグローバル変数を初期化する必要がありますか?
993 :
992 :2009/07/25(土) 04:17:29
正確にいいなおします。 ヘッダーファイルのなかでグローバル変数に値を初期化するような書き方をしていますか? 単に宣言しているだけなら、なにも考えずにOK、初期化しているのならばNGらしい。
こんな感じでどう? #ifndef GLOBAL_DEFINITION #define GLOBAL_DEFINITION extern #endif GLOBAL_DEFINITION double a[10]; そして、1つのソースで#define GLOBAL_DEFINITIONしてから当該のヘッダをインクルードする。 なお、__attribute__((common))とか__declspec(selectany)のように処理系依存の方法もある。
ん?分割コンパイル(モジュール別コンパイル)ではないのかな?
--garray.h #define FOO 100 extern bar baz[FOO]; --garray.c #include "garray.h" bar baz[FOO] = {・・・}; --main.c #include "garray.h" int main(void) { baz[0] = ・・・; baz[1] = ・・・; ・・・
>>989 正確には,malloc,realloc,fopen等のポインタを返す著名な
関数が((void*) 0)をエラーケースについて返すように
協定してるだけで( (void*) 0 )がアクセス不能な何らかの
型へのポインタ値(普通こういった領域へのポインタを
ヌルポインタと総称する。)になっているという保証もない
実はアクセスしても問題の無いケースも少なからずあるが、
標準関数で使用しているものに合わせるとメリットが多いし
なによりも整数0と同一視可能なので、
if( ptr )だとかif( !prt )のような短縮表記が可能になるという
理由でNULL( (void*)0 )は多用されている。
NULLをヌルポインタと呼ぶのはやめたほうがいい。
ヌルと呼ぶのは良いが、Cではヌルポインタという概念は
文法上実は存在しない。
なんで
>>997 みたいなことを書くやつがいるの?
どこの入門書にもNULLはヌル(ナル)ポインタで、
言語使用のレベルで特別扱いされるって書いてあるだろ。
ちなみに文字列終端が¥0であることも紳士協定に過ぎぬ 以降次スレで
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。