- 1 名前:デフォルトの名無しさん mailto:sage [2007/03/19(月) 16:45:25 ]
- C言語の入門者向け解説スレです。
・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 9 pc11.2ch.net/test/read.cgi/tech/1173284217/ 過去スレ Part 1 pc8.2ch.net/test/read.cgi/tech/1146700389/ Part 2 pc8.2ch.net/test/read.cgi/tech/1153818463/ Part 3 pc8.2ch.net/test/read.cgi/tech/1160682950/ Part 4 pc8.2ch.net/test/read.cgi/tech/1162999861/ Part 5 pc8.2ch.net/test/read.cgi/tech/1165022193/ Part 6 pc10.2ch.net/test/read.cgi/tech/1167325490/ Part 7 pc10.2ch.net/test/read.cgi/tech/1170064980/ Part 8 pc11.2ch.net/test/read.cgi/tech/1171946674/ 関連スレ C/C++の宿題を片付けます 84代目 pc11.2ch.net/test/read.cgi/tech/1172981618/ くだすれC言語(初心者用) Part.2 pc11.2ch.net/test/read.cgi/tech/1172099763/ 【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 131 pc11.2ch.net/test/read.cgi/tech/1170338926/ 【初心者歓迎】C/C++室 Ver.35【環境依存OK】 pc11.2ch.net/test/read.cgi/tech/1171888583/ 【C 関数検索 man on WWW】 www.linux.or.jp/JM/index.html
- 331 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:02:34 ]
- >>330
LUT
- 332 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:32:00 ]
- これでよくね?
int y = 0; if(x & 1) y |= 128; if(x & 2) y |= 64; if(x & 4) y |= 32; if(x & 8) y |= 16; if(x & 16) y |= 8; if(x & 32) y |= 4; if(x & 64) y |= 2; if(x & 128) y |= 1;
- 333 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:41:31 ]
- 全然スマートじゃないけどな
- 334 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:48:09 ]
- 10 進法で考えたら分かりやすくね?
int a = 1365; int b = 0; while (a>0) { b *= 10; b += a % 10; a /= 10; } これを応用して int a = 1365; int b = 0; while (a>0) { b << 1; b |= a & 1; a >> 1; }
- 335 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:50:36 ]
- スマートって結局主観だろ。
他人のことなんてわからん。 余計なことして気分的にスマートって思いたいだけだろ。
- 336 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:56:24 ]
- それに加え「速いのが良ければ実測しろ」だしな。
- 337 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:56:28 ]
- int test8bit(int x)
{ static BYTE table[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15}; int y = table[x>>4] | (table[x&15]<<4); return y; } int test16bit(int x) { int y = test8bit(x>>8) | (test8bit(x&255)<<8); return y; } intは32ビット以上前提で
- 338 名前:デフォルトの名無しさん mailto:sage [2007/04/02(月) 23:57:12 ]
- そんな言い訳ばかり並べて逃げるやつからは何も生まれてこないと思うんだ。
- 339 名前:330 mailto:sage [2007/04/02(月) 23:57:19 ]
- LUT作りました。
皆さん、ありがとう。
- 340 名前:デフォルトの名無しさん mailto:sage [2007/04/03(火) 00:01:40 ]
- まあ>>332をスマートだと思う奴なんていないだろうけどな
- 341 名前:デフォルトの名無しさん mailto:sage [2007/04/03(火) 00:06:38 ]
- そんなことに時間かけるくらいなら
可読性も速度も無難なのがいい。
- 342 名前:330 mailto:sage [2007/04/03(火) 00:12:13 ]
- 可読性と速度を考えてLUT。
実測はしてないですが。
- 343 名前:デフォルトの名無しさん mailto:sage [2007/04/03(火) 00:13:58 ]
- まあ、速すぎて調べても誤差程度にしかならんけどね。
- 344 名前:デフォルトの名無しさん [2007/04/03(火) 23:57:14 ]
- 文字列を戻り値に指定するときに
char ch[] = " "; return ch; だとエラーが出て char ch[] = " "; return &ch[0]; だと通ったんですが、戻り値に配列を指定するときは return ch; のように省略して書いてはいけないのでしょうか?
- 345 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:01:54 ]
- 関数内で宣言した変数は静的変数(static付けた奴)以外、
関数を抜けると同時に破棄される。 呼出元に戻ったらもうそんな変数を指すポインタは無意味と化している。 だから前者ではそのことを警告されただけだと思う。 無論後者の書き方をしたところで問題の解決にはなっていない。
- 346 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:20:51 ]
- >>344
エラーがでるでないはともかく関数内で宣言したローカル変数を戻り値にしちゃだめだよぉ return で戻ったときにはchar ch[] はもう亡くなっているだろうから
- 347 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:32:46 ]
- 結論、Cでは文字列を単純には戻り値にはできない。
- 348 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:34:15 ]
- なんでそういう結論になるのか
- 349 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:43:41 ]
- >>348
他の結論になるとでも?
- 350 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:45:26 ]
- 後者は&リテラル返してるじゃん
- 351 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:50:12 ]
- 呼び出し元で確保しておけと。
- 352 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:51:02 ]
- >>344
C言語で関数から文字列を返却したいときは、戻り値にしないで引数で返す つまり、呼び側関数内で配列の領域を確保し、呼ばれる関数に渡す
- 353 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 00:51:35 ]
- 被ったorz
- 354 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 01:30:59 ]
- 超初心者で申し訳ないんですけど、
コンパイルしようとしたときに、cant open: stdio.hっていうエラーが出るんです。 解説お願いします。
- 355 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 02:15:58 ]
- すいません、自己解決しました。
- 356 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 03:58:31 ]
- >>347は要するにC言語では配列そのものをreturn文で返すことはできない、
ってことだろ。 自動的にポインタに変換されてしまうから。
- 357 名前:デフォルトの名無しさん [2007/04/04(水) 04:33:37 ]
- BinarySearchTreeの勉強をしてるんですが
階層の数はどんな感じで出せばいいですか?
- 358 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:04:32 ]
- 350 デフォルトの名無しさん sage 2007/04/04(水) 00:45:26
後者は&リテラル返してるじゃん
- 359 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:05:34 ]
- 356 デフォルトの名無しさん sage 2007/04/04(水) 03:58:31
自動的にポインタに変換されてしまうから。
- 360 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:07:33 ]
- 358 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/04(水) 12:04:32
350 デフォルトの名無しさん sage 2007/04/04(水) 00:45:26 後者は&リテラル返してるじゃん 359 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/04(水) 12:05:34 356 デフォルトの名無しさん sage 2007/04/04(水) 03:58:31 自動的にポインタに変換されてしまうから。
- 361 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:16:40 ]
- 自分で考えろ
- 362 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:36:27 ]
- ソケット通信ってchar型以外のデータを送信できるのでしょうか?
構造体でデータをまとめて通信したいんですけど…
- 363 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 12:40:33 ]
- 送信する関数のポインタの型を良く見ろ
- 364 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 13:28:03 ]
- >>362
「ネットワークバイトオーダー」でググるよろし。
- 365 名前:344 [2007/04/04(水) 16:54:10 ]
- ローカル変数だってことすっかり忘れてました…
staticにするか引数に渡すかしないといけなかったんですね。。 皆さん分かりやすい説明ありがとうございました。
- 366 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:19:44 ]
- 前者がリテラルへの参照、後者がリテラルの先頭アドレスを返してる。
char* moji(){ char ch[] = "a"; return ch;//もしくはreturn &ch[0]; } int main(){ char* b=moji(); return 0; } これで、各所にブレークポイント置いて、メモリとレジスタを見てみりゃわかる。 ローカル変数はベースポインタ(EBPレジスタ)からのオフセットで決まるから、 moji()からmain()に戻ってくりゃ、ベースポインタが変わるから、リテラルへの参照chは意味を成さなくなる。 ただし、戻り値(EAPレジスタ)の残骸が残っている場合、一見何事もなく済んでしまう場合もある。 ch[0]というのは、リテラルそのもの、文字がメモリにセメダインで張り付いてるようなもので、値を変えようとすると AccessViolationでOSから怒られる。&ch[0]は参照じゃなく直接リテラルのアドレスを返している。
- 367 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:31:18 ]
- >>366
>リテラル 何か混乱しているようですが、そのコード中の文字列リテラルは "a" のみです。 ch はリテラルではなく、単なる char[2] のローカル変数です。
- 368 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:31:47 ]
- 真っ赤な間違い乙
- 369 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:32:18 ]
- 真っ赤な間違いは>366ね。
- 370 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:43:37 ]
- >>367
だから、chは文字リテラル"a"への参照だよ。 chは、単なるch[2]のローカル変数? だから違うよ、ch[2]の先頭を参照するローカル変数。 参照ってなに?
- 371 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:51:02 ]
- >>367
左辺値と右辺値の区別くらいつけろや
- 372 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:56:47 ]
- >>366
Cならいついかなる場合でも配列chに対して、chと&ch[0]は同じ。 どちらも配列の先頭要素を指すポインタが式の結果として得られる。
- 373 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:57:01 ]
- 安価間違ってない?
- 374 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 17:58:42 ]
- vipperはカエレ
- 375 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:00:17 ]
- 安価とか言うのは高確率で
おっさん
- 376 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:06:40 ]
- >配列ch
だからchはアドレス参照だと それと、結果は同じでも過程は違うとはよくいったもんで
- 377 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:06:57 ]
- なんか恥ずかしいやつが混じっているなぁ。
char ch[2] = "a"; char foo[2] = {'a', '\0'}; printf("%p, %p\n", ch, foo); を実際にコンパイルして(アセンブル出力を見るか)実行してみれば直ぐに判ることだろうに。
- 378 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:08:43 ]
- 行火
- 379 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:16:00 ]
- >>377
そのプログラムを実行して結果を見たところで何がわかるのやら
- 380 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:19:42 ]
- 何も判らないならプログラミングは止めたほうがいい。
- 381 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:25:49 ]
- >>366
ちなみに文字列リテラルそのもの(の先頭要素)を指すポインタを返したければこうする どちらも結果的には同じこと char* moji() { return "a"; } char* moji() { char* ch = "a" return ch; }
- 382 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:27:26 ]
- >>380
当然過ぎる結果が返ってきたということだw 上の方のレスはカオス過ぎて読んでいない。
- 383 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:27:45 ]
- どうせなら
char *p = "a"; も付け足しとけ。
- 384 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:30:53 ]
- 「配列とポインタは同じ」
って罪な言葉だな…
- 385 名前:344 [2007/04/04(水) 18:31:09 ]
- つまり
ch → "a"の先頭アドレスを参照 ch[0] → 'a'を参照 &ch[0] → 'a'のアドレスを指す と言うことで、これらは全部 'a' '\0' を参照しているからアドレスは同じってことですか?
- 386 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:32:37 ]
- >>366のアホさに久々にワロタ
- 387 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:33:17 ]
- >>385
違う。
- 388 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:34:01 ]
- なんつーか、参照って言葉をむやみに使わないほうがいいと思うんだ。
- 389 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:35:43 ]
- 配列の初期化子に使う場合でも文字列リテラルって言うの?
- 390 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:39:39 ]
- >>389
e-words.jp/w/E383AAE38386E383A9E383AB.html
- 391 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:40:44 ]
- >>389
そう言う。 規格上、charの配列を文字列リテラルで初期化できるという規則になっているから。
- 392 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:42:09 ]
- ch → 配列の先頭を指すポインタとして見なされる
ch[0] → char型の値 &ch[0] → ch[0]のアドレス
- 393 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 18:44:38 ]
- >>390
いやリテラルであることに疑問の余地はないんだけど、文字列リテラルってなんか微妙に違和感あったもんで… >>391 規格じゃあしょうがないね
- 394 名前:344 [2007/04/04(水) 18:56:51 ]
- >>388
少し調べたんですが、 参照ってC++だと特別な意味があったんですね。。 これから気をつけます。 >>392 ありがとうございます。 自分が考えていたことと全然違いますね…
- 395 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:00:32 ]
- kmaebashi.com/programmer/pointer.html
より引用 " で囲まれた文字列を、文字列リテラルと呼ぶ。 通常は、文字列リテラルは、「char の配列」を意味する。 よって、式の中では「charへのポインタ」に読み換えられる。 しかし、char の配列を初期化する場合は例外である。 (こちらを参照のこと) この場合の文字列リテラルは、中括弧内に文字を区切って書く初期化子の 省略形として、コンパイラに特別に解釈される。 char str[] = "abc"; /* この宣言は、下の宣言と同義 */ char str[] = {'a', 'b', 'c', '\0'}; /* 配列の最外周なので、要素数は省略できる */ …だそうだ
- 396 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:12:16 ]
- コード上で"で囲まれてれば全部文字列リテラルなのねー
感覚としてはあたかも文字列リテラルのように書くことが許されてるって感じだった
- 397 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:15:40 ]
- でも現実的には初めそう教えておくほうがいいと俺は思う。
- 398 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:31:04 ]
- >>366
がアホなのは解った。
- 399 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:39:27 ]
- オレはC言語はきちんと理解できていないが
ゲームなんかのクラックをして変な知識だけはある しかもアセンブラの意味も分かっているわけではなく シンボルを見て分かった気になっているだけの スクリプトキディみたいなもんだ 言っとくがオレは >>366 でも代弁者でもないぞ
- 400 名前:デフォルトの名無しさん [2007/04/04(水) 19:44:49 ]
- >>399
どういう流れでその書き込みなのか頭の悪い俺に教えてください。
- 401 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 19:47:48 ]
- >>399
いったい、誰に対して何の主張をしてるんだ?
- 402 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:02:08 ]
- それをこれから書くところなんじゃないか
- 403 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:02:45 ]
- スレ違いはスルー汁
- 404 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:28:28 ]
- とりあえず>>370の
char ch[] = "a"; は文字リテラル"a"への参照だよ。 ってのはおかしいよね・・・?
- 405 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:37:08 ]
- argv[1][2]って*(p+2)みたいに表現できないの? > エロイ人(愛を込めて)
- 406 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:43:08 ]
- >>405
*(argv[1] + 2)
- 407 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:50:32 ]
- >>405
もしくは *(*(argv+1)+2)
- 408 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 20:52:20 ]
- argv[ i ][ k ] = *(*(argv+i)+k)
と等価って意味ね
- 409 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 21:05:21 ]
- 2[1[argv]]
- 410 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 21:13:52 ]
- argv[i][k] == *(*(argv+i)+k) == k[i[argv]]
- 411 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 21:22:45 ]
- >>406-410
サンクス なるほど *を2回使うのね
- 412 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 21:53:54 ]
- a[b]におけるaとbの可換則だけは釈然としない
こんなの使って可読性が上がる場合なんてあんの?
- 413 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 21:57:04 ]
- >>412
その仕様は初期のコンパイラの都合によるものと思われる でも、できるからといって使う必要はないじゃないか
- 414 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:35:53 ]
- char *argv[]に対して
*(argv+i)って言うのはargv[i] *(*(argv+i))って言うのはargv[i][] と同じと考えておk?
- 415 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:37:44 ]
- 下は *(*(argv+i)) == *(*(argv+i)+0) == argv[i][0] ?
- 416 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:45:43 ]
- うん。
*p == p[0]
- 417 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:48:02 ]
- 構造体ってのは最初に宣言しないといけないの?
#include <stdio.h> int main(void){ struct person{ char *sei; int age; }taro; taro.age=13; taro.sei="山田"; struct person hanako; printf("太郎の姓は%s、年齢は%dです\n",taro.sei,taro.age); return 0; } これコンパイルできないんだけど
- 418 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:50:09 ]
- struct person hanako;
を削ってみ。
- 419 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:51:59 ]
- >>417
Cの場合宣言(struct person hanako; )は関数スコープの最初に taro.age=13; taro.sei="山田"; の後で宣言はダメ
- 420 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:52:17 ]
- >>417
コンパイルできるよ。
- 421 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:57:13 ]
- あれがコンパイルできるC99は残念ながら普及していないのさ
- 422 名前:デフォルトの名無しさん mailto:sage [2007/04/04(水) 23:59:18 ]
- gccが普及してないとでも?
- 423 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 00:10:03 ]
- GCCは普及しているものの、社会がC99を使う風潮になっていない。
見たことあるか?C99で書かれたプログラム。
- 424 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 00:17:24 ]
- FreeBSDのソースがC99でかかれてたなー。
- 425 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 00:23:08 ]
- 拡張子をcppにすればいい
- 426 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 00:44:47 ]
- >>423
コメントが//のCのソースコードをよく見るんだが
- 427 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 03:02:41 ]
- C99で書かれたものは、C89でも書ける。
極端な事言えば、C++でusing namespace std; をグローバルで宣言して、あとはCの様に書けば 事足りる。 なんだよ、_BOOLって (w
- 428 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 03:09:55 ]
- 極端な事言えば、 で書かれたものは機械語でも書ける。
- 429 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 07:05:03 ]
- ふつうにboolにしてくれた方が使いやすい
- 430 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 07:51:37 ]
- >>423
毎日飽きるほど見てますが、何か。
- 431 名前:デフォルトの名無しさん mailto:sage [2007/04/05(木) 08:04:55 ]
- >>427>>429
<stdbool.h>
|

|