#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; は働くのでしょうか?
No.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の指すアドレスの次まで移動させる
それだけ、です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
fopne で失敗する原因
-
C言語でのconstを返す関数
-
c言語で任意のファイルから読み...
-
TCHAR文字列内の検索について
-
main(int argc,char **argv[])...
-
cv::Mat から vectorにコピー
-
構造体とfscanf
-
[C#] DeviceIoControlの変数の型
-
VB6でのgethostbyaddrの使用方...
-
bsearch関数の呼び出しで
-
ExcelVBAでのkernel32(64bit)
-
基本アルゴリズムの『返す』の...
-
ハンドルはポインタか
-
関数ポインタの利点
-
C++で関数ポインタから関数名を...
-
パスからファイル名を抽出
-
エラーの意味
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語のポインタに直接アドレス...
-
C言語の関数と配列に関する質問
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
セグメントエラー
-
アプリを32bitから64bit移行
-
コンストラクタでnewを失敗した...
-
ExcelVBAでのkernel32(64bit)
-
Cで作成したDLL関数をVBから呼...
-
ハンドルはポインタか
-
DLL<->VB間での受け渡し(文字...
-
C言語でのconstを返す関数
-
ポインタについて
-
参照型で受け取った引数をポイ...
-
TCHAR文字列内の検索について
-
デバイスハンドルとは?
-
基本アルゴリズムの『返す』の...
おすすめ情報