

以下のコードに関して、char型の `str[]` は文字列の途中にヌルがあるとヌルがある手前までしか表示できないのですか？

また、ポインタ `p` はアドレスが指すメモリ一個のアドレスしか保持できないのですか？

例えば文字列があり、文字列の先頭からヌルの手前までの文字列の先頭のアドレスのみを保持するのですか？

また、`*p` はアドレスの先頭の値のみを扱うのですか？だとしたらその数値を表す場合は `%c` しか使えないのでしょうか？

[code]

    #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;
        }
    }
    
[/code]


CC BY-SA 4.0
2021-02-16T15:31:54.227
74056
2021-02-17T04:27:10.457
2021-02-16T16:33:10.743
3060
27296
question
c ポインタ
char strとポインタと*pについて。


C言語での文字列というのは、終端に'\0'(ゼロ)を置いた文字の配列、と定義されてるので、

> ヌルがあるとヌルがある手前までしか表示できないのですか？

ではなく、ヌル（ゼロ）があるところが終端と判断している、ということですね

> また、ポインタ p はアドレスが指すメモリ一個のアドレスしか保持できないのですか？

そのとおり。  
ましかし、配列であれば、連続したアドレスにその要素は配置されますんで、配列のアドレス、という扱いができます

> また、*p はアドレスの先頭の値のみを扱うのですか？だとしたらその数値を表す場合は %c しか使えないのでしょうか？

先に言ったように、文字列とは文字の配列です。  
*p としてしまうとアドレスのナカミとなってしまうので、pが文字列を指してても文字がでてきます。  
文字列として扱いたければ、%s として、pを渡しましょう


CC BY-SA 4.0
2021-02-16T23:47:27.177
74063
2021-02-16T23:47:27.177
27481
74056
answer


[c](/questions/tagged/c "'c' のタグが付いた質問を表示") は 1970
年代に開発された言語なので当時のコンピュータで無理なく扱える程度の仕様しか規定されていないわけっス。２１世紀のプログラム言語ではもっといろいろな機能が組み込まれているわけだけど
[c](/questions/tagged/c "'c' のタグが付いた質問を表示")
の仕様にはそういう「人間にとって簡単で、コンピュータにとって難しい機能」は入っていない。っていうか、むしろそういう便利な機能を実用的な速度で実装するために
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") は使われている。だから便利な機能を簡単に使いたいのであれば
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") なんぞ使うのやめて他の言語に乗り換えるほうが良いっス。

* * *

[c](/questions/tagged/c "'c' のタグが付いた質問を表示") の標準関数はそういう約束（＝仕様）になっているので A1. は
Yes
なんだけど、標準関数を使わないなら「あなたの好きに実装すればいい」に変わるっス。真にやりたいことが書かれていないので具体的にどうすればよいかは例示できない。

「`****` へのポインタ」は、その先頭アドレスをもって `****` 全体を表す仕様なので A2. も Yes

A3.

# 厳密さをちょっと置いとく

たとえば `char c; char* p=&c;` があるとき `p` の値が `0x4321` であるなら `0x4321`
の値をもって８個のビットの全部を指すのが `char*`

同様 `double d; double* q=&d;` として `q` の値が `0x5678` で `double` が 64bit であるなら
`0x5678` の値をもって `0x5678~0x567F` の 64bit (8byte) 全部を指すのが `double*`

`struct very_large_struct { ... };` を指すポインタ `struct very_large_struct*
r=&vls;` があるとき、同様 `r` の値が `0x3210` であるなら `0x3210`
の値をもって構造体全体（うん十万ビット）を指すことができる。

`*p` は８ビット (`char` １個) を指すので「文字」ではあっても「文字 **列** 」ではない。 `*q` は `double` １個を
`*r` は `very_large_struct` の１個を指す。

後は [c](/questions/tagged/c "'c' のタグが付いた質問を表示") の配列は **メモリ上連続したアドレスに配置される**
という仕様があるので `p` が配列の要素の１つ（先頭）を指すとき  
`*p` は `*(p+0)` とも `p[0]` とも書けるが、先頭要素 (の別名 `char` なら 8bit `double` なら 64bit)  
`*(p+1)` は `p[1]` とも書けるが、２番目の要素、以下同様  
標準関数は文字列処理の際 `\0` を見つけるまで連続で処理する約束なので `p` の値１個で文字列を代表させることができるが `*p`
ではどうにもならない

`printf()` の `%s` は対応する値として `char*` を求めるし `%c` は対応する値として `char` を求めるので、答えは Yes

* * *

で、この程度の話なら教科書には必ず書いてあるし、教科書読んでわからないのならこの回答を読んでもわからないであろうし、今までの挙動を見るに元発言者氏はこういう掲示板系サイトでの
Q&A
が成立するレベルまで到達できていないであろうことが明らかなので、もう少し理解が進んでからコミュニケーションの場に参加するべきだろう。今のままだと意義ある質疑応答が成立しないっス。


CC BY-SA 4.0
2021-02-17T04:27:10.457
74065
2021-02-17T04:27:10.457
8589
74056
answer