1 名前:デフォルトの名無しさん mailto:sage [2010/03/05(金) 23:27:18 ] C言語の*入門者*向け解説スレッドです。 ★前スレ C言語なら俺に聞け(入門編)Part 60 pc12.2ch.net/test/read.cgi/tech/1264920499/ ★過去スレ makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000 ★初心者、初級者の方は他の質問スレのほうが良いかもしれません。 例えば 【初心者歓迎】C/C++室 Ver.72【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1267775473/ とか ★教えて欲しいのではなく宿題を丸投げしたいだけなら ↓宿題スレ↓へ行ってください。 C/C++の宿題片付けます 134代目 pc12.2ch.net/test/read.cgi/tech/1263824755/ ★C++言語についてはなるべく聞かないでください。C++対応明記スレへどうぞ ★分からない事をなるべく詳しく書いて下さい。 ★ソースコードを晒すと答えやすくなるかもしれません。 # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること # サイズが大きい場合は宿題スレのアップローダ等を利用してください ★開発環境や動作環境も晒すと答えが早いかもしれません。 ★質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
433 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:04:08 ] >>431 だいたい合ってるが、1点だけ。 > ここでbufとするとABCDEという文字列を表すことになりますが、 bufがABCDEという文字列を表しているわけではない。 あくまで文字列の先頭のアドレスを保持しているにすぎない。 buf == &(buf[0]) puts(buf)で"ABCDE"と表示されるのは、以下のような処理をしているため。 for(char *p = buf; *p != '\0'; p++) { *pを出力; }
434 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:07:07 ] >>431 配列は配列であってポインタじゃない
435 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:10:42 ] char buf[] = {'h', 'o', 'g', 'e', '\0'} char *p = buf; buf ↓ 'h' 'o' 'g' 'e' '\0' ↑ 0x00..... ← p
436 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:13:39 ] グダグダ言ってないでデバッガで変数見りゃいっぱつだろうが
437 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:14:09 ] >>431 >ここでbufとするとABCDEという文字列を表すことになりますが ここでってどこだよw
438 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 20:26:53 ] >431 言っていることはその通り何だけど NUL('\0')終端文字列はNULが現れるまでを文字列とみなすから表示させたい最初の文字のアドレスを渡すだけでいいのよ あなたにお薦めなサンプルプログラム #include <stdio.h> #include <string.h> int my_print(char const*str) { size_t i; for ( i = 1; i < str[0]+1; ++i ) { putchar(str[i]); } return i-2; } int main(int argc, char **argv) { char foo[6] = {'a', 'b', 'c', 'd', 'e', '\0'}; char bar[16] = {'a', 'b', 'c', 'd', 'e'}; char baz[] = {3, 'b', 'a', 'z'}; memset(bar+5, '\100', 10); /* ゴミを入れる */ bar[15] = '\0'; /* NUL終端させる */ printf("%s\n", foo); printf("%s\n", &foo[0]); printf("%s\n", &foo[3]); printf("%s\n", bar); my_print(baz); return 0; }
439 名前:デフォルトの名無しさん [2010/03/19(金) 21:22:55 ] 配列はメモリ上連続しているので、先頭アドレスと型がわかれば計算で出ます。 コンパイラは &buf[5] を &buf[0] + (5 * sizeof(char)) と捉えます。
440 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 21:33:35 ] プログラミングに使う単語って英語ですか?
441 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 21:37:20 ] 基本的には
442 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 21:43:31 ] 皆さんは英語ペラペラですか?
443 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 21:44:01 ] My English is poor.
444 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:17:57 ] >>442 fuck u
445 名前:431 [2010/03/19(金) 22:18:43 ] >>433 buf自体がが先頭アドレスなのは↓に書いたように知ってます >buf自体はアドレスの開始地点 結局全部 for(char *p = buf; *p != '\0'; p++) { *pを出力; } これやってるだけなんですね…
446 名前:431 [2010/03/19(金) 22:24:21 ] >>439 buf[5]を例えばprintfするときはオフセットで 文字列を全部表示するときはポインタをズラす方法で表示しているのですか? for(char *p = buf; *p != '\0'; p++) { *pを出力; } このようにポインタをズラしているのか、 それとも &buf[5] を &buf[0] + (5 * sizeof(char)) のようにオフセットで計算しているのか 内部の処理はどっちなんでしょうか? それが>>431 の質問で一番知りたいことなんですが
447 名前:431 [2010/03/19(金) 22:26:02 ] >>436 オフセットで計算したものか、ポインタをズラしたものなのか 格納されたアドレス見るだけじゃわからないんですよ…
448 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:26:32 ] どういう風にprintfを作るかなんて決まってないしコンパイラメーカーが勝手にやってるだけだよ きっと、前者だろうなって気はするけど
449 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:27:39 ] 前者な気がする
450 名前:431 [2010/03/19(金) 22:28:24 ] >>448 そうなんですか… どっちが主流なのか知りたかったのですが(速度とかいろんな意味で)
451 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:30:39 ] そんなこと知ってどうすんだろ
452 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:31:24 ] 速度とかそれこそきまってねえだろ おまえはなにか?コンパイラは全て同じ中身じゃないといけないと思ってんのか?主流ってなんだ?どの環境の主流だ? クソして寝ろや
453 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:33:28 ] >>450 もう答えは出てるだろう。文字列探索程度のコストを気にするより もっと他の所の速度を気にしろ。
454 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 22:35:29 ] 簡単なプログラムつくって、最適化全部はずしてバイナリを逆アセンブルして追っかけてみれば? ペンティアム以降になると急に難しくなるから、LSICの試食版あたりからははじめて あるいはgccならprintfもソースみれるよ そうやって3,4個調べてみれば主流もわかるんじゃね
455 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:38:50 ] robot C わかる人いる?
456 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:41:38 ] ボクは個人的には char c[1234] ってのを putchar( c[0] ); putchar( c[1] ); putchar( c[2] ); putchar( c[3] ); putchar( c[4] ); putchar( c[5] ); 〜〜〜ずーっとつづく って書くよりも char* p=c; putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); 〜〜〜ずーっとつづく って書く方が、コピペが楽なので好きですw
457 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:43:53 ] ?
458 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:44:02 ] 頭おかしいのかおまえ
459 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:52:53 ] 俺がコンパイラなら syntax error 出すわな
460 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:53:21 ] 最終的にはsystem callを追っかけてlibcやkernelに入りそうだな
461 名前:デフォルトの名無しさん mailto:sage [2010/03/19(金) 23:59:13 ] int 21Hで終わりでいいじゃん
462 名前:デフォルトの名無しさん mailto:sage [2010/03/20(土) 00:06:12 ] char c[1234]; ってのは、使うときは putchar( c[3] ) みたいにして使います。 c[0] なら最初の文字、c[3]なら3番目の文字です。 &c[3] みたいに、頭に&マークをつけると、このデータがメモリのどこに書かれてるかがわかります。配列の先頭が、メモリのどこにあるかは &c[0] でわかります。 使うときにカッコを取って c って書くと、 &c[0] って書いたときと同じ数字がわかります。 この c そのものを c++ ってやって一個増やすと、 char型の配列なら、char一個分だけメモリをさしてる場所が増えます。 だから c++ とすると、つぎに使うときは c は &c[1] といういみになります。 int型の配列なら、int i[1234];
463 名前:デフォルトの名無しさん mailto:sage [2010/03/20(土) 00:08:19 ] i++ で int の大きさ分だけ増えます。 や〜めた
464 名前:デフォルトの名無しさん mailto:sage [2010/03/20(土) 00:14:26 ] >462 またまたご冗談を
465 名前:デフォルトの名無しさん mailto:sage [2010/03/20(土) 00:19:03 ] >>462 そんなコンパイラなんて… あるかもしれないが規格無視じゃないか
466 名前:デフォルトの名無しさん mailto:sage [2010/03/20(土) 00:27:03 ] >>462 その場合cは定数だからc++なんて出来ないだろアホ