回答編集履歴
2
アドレスを具体的に確認する方法を追加
answer
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
- result 変数は 0x0C001248 番地にある
|
16
16
|
|
17
17
|
と仮定しました。それが「"Hello" と result変数の様子」図です。
|
18
|
-
実際のアドレス
|
18
|
+
実際のアドレスがどこかはともかく、何か具体的なアドレスを与えないと説明が面倒なのでテキトーにアドレスを決めました(少し工夫すれば実際のアドレスを確認できる)。
|
19
19
|
|
20
20
|
char *result; は変数宣言、或いは変数定義ですね。
|
21
21
|
- result という名前の変数を設ける(メモリ上に割り当てる)
|
@@ -38,12 +38,41 @@
|
|
38
38
|
|
39
39
|
> printf("%s", *result);とするべきのような気がする
|
40
40
|
|
41
|
-
ここで** *result は result ポインタが指すメモリの値**で
|
41
|
+
ここで重要なのは** *result は result ポインタが指すメモリの値**であること。 *result の値は 72 です。72 は 'H' という値なので、
|
42
42
|
printf("%s", 72); すなわち printf("%s", 'H'); という呼出しになります。
|
43
43
|
|
44
44
|
72 という値を受け取った printf() は、運が良ければw 'H' という文字を表示できるかもしれないけれど、Hに続く0x0006A005番地の 'e' を、どうやって知るのでしょうか???
|
45
45
|
|
46
46
|
こう考えれば printf("%s", *result); では期待する動作にならないことが理解できると思います。実際は "%s" を指定する限り、72 番地から始まる文字列を表示しようとして異常終了するでしょう。
|
47
47
|
|
48
|
-
一方、printf("%s", result); は result の値 0x0006A004 を printf() に渡します。つまり printf("%s", 0x0006A004); です。文字列の先頭アドレスを渡
|
48
|
+
一方、printf("%s", result); は result の値 0x0006A004 を printf() に渡します。つまり printf("%s", 0x0006A004); です。文字列の先頭アドレスを渡された printf() は、そこから順次 H, e, l, l, o という文字を表示できる・・・これは既にご理解いただけたようですが。
|
49
|
-
メモリの図を描くと、こういうことも実感として理解できるし、ポインタの扱いで間違いが少なくなります。
|
49
|
+
メモリの図を描くと、こういうことも実感として理解できるし、ポインタの扱いで間違いが少なくなります。
|
50
|
+
|
51
|
+
P.S.
|
52
|
+
少し工夫すれば実際のアドレスを確認できる・・・
|
53
|
+
printf() にはポインタの値(アドレス)を表示する %p という変換指定があります。これと sizeof 演算子を使って、4行追加してみました。result の値を表示すれば "Hello" 文字列リテラルのアドレスがわかります。
|
54
|
+
|
55
|
+
```C
|
56
|
+
#include<stdio.h>
|
57
|
+
|
58
|
+
int main(void){
|
59
|
+
char *result;
|
60
|
+
result = "Hello";
|
61
|
+
printf("%s", result);
|
62
|
+
|
63
|
+
printf("\n\n");
|
64
|
+
printf("\"Hello\" is located at %p.\n", result); // 文字列リテラルの位置
|
65
|
+
printf(" result is located at %p.\n", &result); // 変数 result の位置
|
66
|
+
printf(" size of result is %d bytes.\n", sizeof(result));
|
67
|
+
return 0;
|
68
|
+
}
|
69
|
+
```
|
70
|
+
私の手元では、こんな表示になりました。
|
71
|
+
```
|
72
|
+
Hello
|
73
|
+
|
74
|
+
"Hello" is located at 0x4006f4.
|
75
|
+
result is located at 0x7ffc337f9950.
|
76
|
+
size of result is 8 bytes.
|
77
|
+
```
|
78
|
+
result変数のサイズが8なのは64bit環境であることを示してます。もちろんデバッガでも確認できます。具体的なアドレスを知れば、より深い理解につながります。例えば、関数内のローカル変数とグローバル変数ではアドレスが大きく違うはずです。こうした情報を元にメモリの図を描きなおしてみることをお勧めします。
|
1
4バイトのメモリアドレス、誤りを修正
answer
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
- そのアドレスのメモリは char 型(或いは char型配列)である
|
24
24
|
|
25
25
|
という意味です。
|
26
|
-
32bitコンピュータのアドレスは 32bit ですから、result 変数には4バイトが必要です(32bit = 8bit/byte * 4byte)。この例では 0x0C001248から
|
26
|
+
32bitコンピュータのアドレスは 32bit ですから、result 変数には4バイトが必要です(32bit = 8bit/byte * 4byte)。この例では 0x0C001248から0x0C00124B番地までの4バイトをひとまとめに使って、ひとつのアドレスを記憶します。ポインタ変数とは、そういうものです。
|
27
27
|
|
28
28
|
なお、メモリは1バイトだけポツンとあるわけではなく、**メモリは連続して存在するから、char一文字を指すポインタも、文字配列を指すポインタも、同じ格好**です。
|
29
29
|
|