for()文の意味がわからないので教えてください。
1for文の初期値が ;で、何の意味か良く分かりません。 2条件*pと、インクリメントP++ はわかります。 3実行文 ;はなにもしないということでしょうか? 4for文を抜けてp--はポインタをpが偽になった位置に 5に戻しているでいいでしょうか? 6 7そのあとのwhile 文は改行があれば0を代入して 8文字列の最後の文字(改行の前の文字)のポインタを指すようにするでいいでしょうか? 9よろしくおねがいします。 10 11void chop(char *p) { 12 for (; *p; p++) 13 ; 14 15 p--; 16 while (*p == '\r' || *p == '\n') 17 *(p--) = 0; 18}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
iを1から100までカウントするためのfor文
C
1for ( i = 1; i <= 100; i++ )
のおよその意味が、
for (値の初期化; ループ継続条件; 値のカウント)
である事はご存知かと思いますが、
実態は、
for (ループ前に実行される式; ループ継続条件; 継続判定前に実行される式)
でしかありません。
なので、ループ開始前に値の初期化が必要なければ省略できますし、
他の式も必要なければすべて省略できます。
極端な例では
C
1for (;;)
とすることで、無限ループを作ることもできます。
Cではwhile(1)と書くのが普通ですが。
投稿2016/04/24 02:21
総合スコア324
0
for の意味は既に他の回答にある通りです。
質問文にあるコードの問題点について述べます。
問題点: chop() は、与えられた 文字列の領域外のデータを書き変えてしまう恐れがある。
↓のコードと実行結果を参照してください。
x.c
c
1#include <stdio.h> 2#include <string.h> 3 4void chop(char *p) { 5 for (; *p; p++) 6 ; 7 p--; 8 9 while (*p == '\r' || *p == '\n') 10 *(p--) = 0; 11} 12 13void chop2(char *p) { 14 for (char * t = p + strlen(p) - 1; p <= t; t--) { 15 if (*t == '\r' || *t == '\n') { 16 *t = 0; 17 } else { 18 return; 19 } 20 } 21} 22 23//void chop2(char *p) { 24// int len = strlen(p); 25// for (int i = 0; i < len; i++) { 26// if (p[i] == '\r' || p[i] == '\n') { 27// p[i] = 0; 28// } 29// } 30//} 31 32void dump(char * p, int len) { 33 for (int i = 0; i < len; i++) { 34 printf(" %02X", *p & 0xff); 35 p++; 36 } 37 printf("\n"); 38} 39 40int main(int atgc, char** argv) { 41 char str[10]; 42 43 printf("--- chop1\n"); 44 strcpy(str, "0\n\n"); 45 printf("[%s]\n", str); 46 chop(&str[3]); 47 printf("[%s]\n", str); 48 dump(str, sizeof(str)); 49 50 printf("--- chop2\n"); 51 strcpy(str, "0\n\n"); 52 printf("[%s]\n", str); 53 chop2(&str[3]); 54 printf("[%s]\n", str); 55 dump(str, sizeof(str)); 56 57 printf("\n"); 58 59 strcpy(str, "1\n2\n"); 60 chop(str); 61 printf("chop\n[%s]\n", str); 62 strcpy(str, "1\n2\n"); 63 chop2(str); 64 printf("chop2\n[%s]\n", str); 65 return 0; 66}
実行例
$ gcc x.c $ ./a.out --- chop1 [0 ] [0] 30 00 00 00 B5 57 FF 7F 00 00 --- chop2 [0 ] [0 ] 30 0A 0A 00 B5 57 FF 7F 00 00 chop [1 2] chop2 [1 2]
chop には &str[3] を渡しているので、str[0], str[1], str[2] の内容が書き換わってはいけないです。
chop を呼んだ後は 30 00 00 ... となってます。
chop2 を呼んだ後は 30 0A 0A ... となってます。
str[1], str[2] は 0A, 0A のままであるべきです。
chap(p) では、 0 をさがした後、 p-- しています。
これが p の領域の外になってしまうことがあるわけです。
そしてそこから p-- しながら \n, \r を探して 0 への置き換えをしているので...
chap2(p) では、 p の領域外へのアクセスが発生しないようにしています。
変更: 2016-04-24 17:10
変更前は, 文字列の途中に改行がふくまれている場合、 chop2() の挙動が chop() と異なっていました。
chop2()の挙動が chop() と同じになるようにしました。
投稿2016/04/24 00:33
編集2016/04/24 08:13総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/04/24 01:19
2016/04/24 01:54
2016/04/24 04:42
2016/04/24 08:14
0
OS、Cコンパイラの、種類、名称、エディションが書かれていませんが、
掲示の質問の大部分は、
1.ソースコードデバッガを使って、ステップ実行しつつ
変数の内容を確認する。コンパイル時に、オプティマイザは切っておく。
2.もうちょっと興味があるのであれば、機械語対応のデバッガを使って、
機械語レベルで、1ステップづつトレースしてみる
コンパイル時に、オプティマイザは切っておく。
⇒構造体、ポインタ、キャスト、変数定義への疑問が、アセンブラを齧っている程度でも
理解に繋がる方法の、一つです。
言語によっては、ライブラリコールの塊の事があるので、全てに適用できるわけでは有りません。
3.エディタ、コンパイラが使えるだけでも、プログラムは組めるけれど
効率の良いデバッグを行うには、デバッガが使えないと、話になりません。
デバッガが使えるだけでも、効率は上がりますが、
更に、デバッグをどう行ったら良いか、を考えながらコードを書く事も必要です。
⇒コードを書く前に、テスト手順を考えておく事も大切です。
デバッグコードを入れるは、どうしようもない場合の手段。
見難く、醜いコードになるので、可能であれば避けます。
投稿2016/04/24 00:18
編集2016/04/24 00:31総合スコア2028
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
*p
が0になるまでp
を進める、つまり文字列としてのp
の最後までポインタを進める、という意味です。
もっとも、標準関数のstrlen
を使って、p += strlen(p);
と書いたほうが読みやすい気もします。
投稿2016/04/23 22:18
総合スコア145184
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/04/23 22:29
退会済みユーザー
2016/04/23 22:37
2016/04/23 23:10
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/04/24 02:50