プロが教えるわが家の防犯対策術!

#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "str == NULL ? \"(NULL)\": str";
char* p, * q; int ch; p = str;
for (;;) { for (q = p; !(*q == '?' || *q == ':' || *q == 0); q++);
ch = *q;//'?'か':'か 0(null)が入る。
*q = 0;//'\0'でも良い。
printf("|%s|\n", p);
if (ch == 0) break;
p = q + 1; }
}
以上のプログラムのforに関しての質問です。
文字列がfor (q = p; !(*q == '?' || *q == ':' || *q == 0); q++);の条件!(*q == '?' || *q == ':' || *q == 0); に一致した時だけ、{}の中身を実行するのでしょうか?
また、どんな時にp = q + 1; は働くのでしょうか?

A 回答 (1件)

う〜ん、まだ分かってなかったか。



> for (q = p; !(*q == '?' || *q == ':' || *q == 0); q++);の条件!(*q == '?' || *q == ':' || *q == 0); に一致した時だけ、{}の中身を実行するのでしょうか?

{}の中身って何?そんなモンどこにも無いでしょ?無いモノを訊いても意味がないでしょ?
だから言ったじゃない。
本来ならこう書くべきだ、って。

q = p;
while(!(*q == '?'|| *q == ':' || *q == '\0')) {
 q++;
}

こう書けば分かりやすいのに、こう書いてないから貴方みたいに勘違いするんだ。

提示されたようなforの使い方は、正式名称は知らんけど、敢えていうと

「本体無しのfor」

ってなモンだ。

通常、forを使う時は

for(初期値 ; 非脱出条件; 更新) {
 あれやる;
 これやる;
 ...;
}

みたいにして書く。forはブロックと組み合わせて、ブロック内に複文入れてその中身を逐次実行しつつ繰り返す。
ところが、単文の場合、今はあんま推奨されないけど、こういう書き方が可能。

for(初期値 ; 非脱出条件; 更新)
 これだけやれ;

単文の場合、ブロックを記述する記号{}を使わないで良い、ってルールがあるんだな。もう一回言うけど、これは今やあんま推奨されてない。
もっと言うと、次のように書く事も可能だ。

for(初期値 ; 非脱出条件; 更新) これだけやれ;

でも何もやりたくない場合、この本体を空にする事が出来る。

for(初期値 ; 非脱出条件; 更新) ;

これだ。自分が提示したコードを見てみろ。同じでしょ?

つまり、このforがやってるのはポインタqを「進める」事だけを目的にしていて、「何か他に実行するモノはない」って事なの。
分かる?
だから言ったでしょ。「可読性を重視するなら」

q = p;
while(!(*q == '?'|| *q == ':' || *q == '\0')) {
 q++;
}

こう書くべきだ、って。「ポインタを進める為にここを繰り返しにしてる」って意図がハッキリしてる。
一方「本体無しのfor」は一見何がやりたいんだかサッパリ分からない。
だから貴方みたいに「存在してない{}の中身」なんてワケの分からん事を想像して意味不明な質問をする事になる。

> また、どんな時にp = q + 1; は働くのでしょうか?

外側のfor(;;)が働いてる間は毎回働いてますよ。
もう一回言いますよ。
原理的には出力だ何だって余計なトコを省けば

1. ポインタqが'?'か':'か'\0'を含む場所まで移動させる(内側のfor)
2. ポインタpをqの指すアドレスの次まで移動させる

それだけ、です。
    • good
    • 2

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!