

[char str[] をポインタで参照したときの挙動が分からない](https://ja.stackoverflow.com/q/74030/19110)
の回答を見ての疑問です。

`printf("str:%s\n", p);`となぜ書いてはいけないのですか？

`*p`はメモリに入ったアドレスの文字コードを呼び出します。なので`p`でよいと思ったのですが、エラーは起きないにしてもデバッグがうまくいきません。仮に`*p`を使うとしたら`printf`の演算子をどう変えればいいでしょうか？

また、なぜ`&(*p)`は良いのですか？もしかして演算子はアドレスからの文字コードしか受け取れないからですか？`printf("*p:%s\n",
&(*p))`において、`printf("*p:%s\n", &p)`としたのですが、駄目でした。なぜ`printf("*p:%s\n", &(*p))`の
`&(*p)`の形ならOKなのでしょうか？あるいは`printf("*p:%s\n", &p)`の演算子`%s`を変えれば `&p`でも可能なのでしょうか？

[code]

    #include <stdio.h>
    int main(void) {
        /*str[]でメモリ上に５文字分の連続したアドレスを確保し、中身をabcdeとします。*/
        char str[] = "abcde";
    
        /* strで確保された最初のメモリアドレスから一つずつ参照していきます。
        /* NULLが出るまでループは終わらない。*/
        /* このループで1文字目から終端NULLまで。2文字目から終端NULLまでと順に表示します */
        for (char* p = str; *p; p++)
        {
            /* pointer *pはstr[]で確保されたメモリ上のアドレスの中身を直接操作する仕組みです。 */
            /* str[]で確保されたメモリアドレスを直接操作できる仕組みが ポインターです。 */
                /* *pで示されているメモリアドレスの値を取り出して、そこにプラス１します */
                /* それを*pで示されているアドレスに代入しています。strで確保されたメモリの中身が書き換わります。 */
            (*p) = (*p) + 1;
            /* *pで示しているアドレスから、終わりのNULLまでを表示します。*/
            printf("*p:%s\n", &(*p));
            /* strの中身も表示します。 */
            printf("str:%s\n", str);
        }
    }
    
[/code]


CC BY-SA 4.0
2021-02-16T04:54:54.483
74037
2021-02-16T11:51:55.763
2021-02-16T09:49:24.880
3060
27296
question
c ポインタ
ポインタを%sでprintfできないのはなぜですか？


駄目と言った覚えはありませんが、そう受け取って、その疑問を自分で解決したいということでしたら、問題がないことを実感できるまで、自分の手で確認してみてください。

確認できる環境はありますよね？

printf については、wikipediaでも詳しい定義が記載されています。  
その気になれば、いろんなOSの定義ファイルを調べることも可能です。  
ヘッダの定義まで確認できると思います。


CC BY-SA 4.0
2021-02-16T10:49:16.720
74050
2021-02-16T11:51:55.763
2021-02-16T11:51:55.763
43957
43957
74037
answer


> printf("str:%s\n", p);となぜ書いてはいけないのですか？

はどうしてそう考えたのでしょうか？全然問題のないコードだと思います。  
`printf("*p:%s\n", &(*p))`がよくて`printf("str:%s\n", p);`がいけない理由はありません。  
どちらかというと`printf("*p:%s\n", &(*p))`の方が問題だと思います。  
`&(*p))`がアドレスであることを明示する意図があるかもしれませんが、通常こんな書き方はしません。

`char *p;`において、`&(*p)`と`p`は同じです。ちなみに`&(*(&(*p)))`も`p`と同じです。  
「&領域」は領域のアドレスを意味し、「*アドレス」はアドレスの指し示す領域の内容です。

pにchar型の領域アドレスが格納されていて、その領域に0個以上の文字コードが格納されていて、ゼロ終端であれば、`printf("*p:%s\n",
&(*p))`と同様に`printf("str:%s\n", p);`は問題なく動きます。


CC BY-SA 4.0
2021-02-16T11:08:31.807
74051
2021-02-16T11:08:31.807
35558
74037
answer