電子書籍の厳選無料作品が豊富!

#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;
*q = 0;
printf("|%s|\n", p);
if (ch == 0) break;
p = q + 1;
}
}
```
のコードについてデバッグをして中身を確認したかったため

以下のように置いて
```
```ここに言語を入力
#include <stdio.h>
#include <string.h>

int main(void) {
char str[] = "str == NULL ? \"(NULL)\" : str";
char *p, *q;
int ch;
p = str;
printf("before loop\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
for (;;) {
printf("loop start\n");
printf("--before inner loop\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
for (q = p; !(*q == '?' || *q == ':' || *q == 0); q++)
;
printf("--after inner loop\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
printf(" q = |%s|\n", q);
ch = *q;
*q = 0;
printf("--after *q = 0\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
printf(" q = |%s|\n", q);
printf("|%s|\n", p);
if (ch == 0)
break;
p = q + 1;
printf("--after p = q + 1\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
printf(" q = |%s|\n", q);
printf("loop end\n\n");
}
printf("after loop\n");
printf(" str = |%s|\n", str);
printf(" p = |%s|\n", p);
printf(" q = |%s|\n", q);
}
```

以下のように出力が出ました。
```
before loop
str = |str == NULL ? "(NULL)" : str|
p = |str == NULL ? "(NULL)" : str|
loop start
--before inner loop
str = |str == NULL ? "(NULL)" : str|
p = |str == NULL ? "(NULL)" : str|
--after inner loop
str = |str == NULL ? "(NULL)" : str|
p = |str == NULL ? "(NULL)" : str|
q = |? "(NULL)" : str|
--after *q = 0
str = |str == NULL |
p = |str == NULL |
q = ||
|str == NULL |
--after p = q + 1
str = |str == NULL |
p = | "(NULL)" : str|
q = ||
loop end

loop start
--before inner loop
str = |str == NULL |
p = | "(NULL)" : str|
--after inner loop
str = |str == NULL |
p = | "(NULL)" : str|
q = |: str|
--after *q = 0
str = |str == NULL |
p = | "(NULL)" |
q = ||
| "(NULL)" |
--after p = q + 1
str = |str == NULL |
p = | str|
q = ||
loop end

loop start
--before inner loop
str = |str == NULL |
p = | str|
--after inner loop
str = |str == NULL |
p = | str|
q = ||
--after *q = 0
str = |str == NULL |
p = | str|
q = ||
| str|
after loop
str = |str == NULL |
p = | str|
q = ||
```

0. ただなぜ途中から str の中身が |str == NULL |のみになったのかわかりません。
自分なりに考えたのですが
ポインタqがq=0よりforの条件に入る部分の先頭の文字からNULLまでを要は、 |str == NULL ? "(NULL)" : str|の? "(NULL)" : strを消してしまったため、 そして、ポインタP= |str == NULL |が残っている。。。いや自信がないです。なぜstr の中身が |str == NULL |のみになったのでしょうか? またどうやって "(NULL)" : str|は残っていたのでしょうか?

A 回答 (5件)

> ただなぜ途中から str の中身が |str == NULL |のみになったのかわかりません。


下図の状態のとき、
"str == NULL ? \"(NULL)\" : str"
      ↑
      q
つまり、「*qが'?'を指している」ときに、
*q = 0;
を実行して’?’を0に書き換えた結果、
文字列 "str == NULL ? \"(NULL)\" : str" が
文字列 "str == NULL" に書き換えられたため
です
    • good
    • 0
この回答へのお礼

そして、cの仕様よりstrはヌルまでしか表さないためそのようになったのですね。

お礼日時:2021/02/18 08:47

> #4



言わんとしてる事は分かるんだけど、この質問投稿者は

> 文字列 "str == NULL ? \"(NULL)\" : str" が
> 文字列 "str == NULL" に書き換えられたためです

って言うから勘違いするんですよ。

1. C言語には文字列なんつー高級なデータ型がそもそもない
2. C言語には文字列なんつー高級なデータ型を代入出来るような変数は存在しない

のが徹底的に分かってない。
分かってないからこその連投なんです。

要するに #2 で挙げたような、

"Hello, world!\0"

と言う配列が

"Hello\0 world!\0"

と書き換えられた時の、書式文字列"%s"の動作が分かってない、だけなんです。
ポインタもクソも関係ない。
ポインタ関係ないのにポインタ弄ってドツボにハマってるだけ、なんですよ。

問題は「配列の書き換えとそれに伴う出力関数の動作」なんです。
そこを全然関係ないポインタにこだわって理解を自ら妨げてるだけ、なんです。
#3氏が指摘してるのもそこなのです。
    • good
    • 3

printf(" str = |%s|\n", str);


これがどのように動くか、説明できますか。

別の質問での回答で説明していますのでそちらをよく読みこんで考えてください。
    • good
    • 2

> 是非詳しく原因を教えてください



原因も何も・・・。
そもそも実は全然ポインタ関係ないですよ?

次のコードを打って確認してみてください。

#include <stdio.h>

int main(void) {
 char str[] = "Hello, world!";
 str[5] = 0;
 puts(str);
 return 0;
}
    • good
    • 0

qの指してる先がstrの中の「具体的位置」で、そこ書き換えちゃったらpもstrも影響を受ける、って事でしょ。



うーーーん、Cらしくて「怖い」動作だなぁ(笑)。
くわばらくわばら。
    • good
    • 0
この回答へのお礼

ありがとうございます。
是非詳しく原因を教えてください

お礼日時:2021/02/16 18:12

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