回答編集履歴

5

追記

2016/06/18 11:19

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  {
22
22
 
23
- /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 */
23
+ /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 (外側の配列サイズは省略可能) */
24
24
 
25
25
  const char *strings[] = {"aaa", "bbb", "ccc"};
26
26
 
@@ -58,7 +58,7 @@
58
58
 
59
59
  {
60
60
 
61
- /* 文字の配列はconst宣言しない限りは書き換え可能 */
61
+ /* 文字の配列はconst宣言しない限りは書き換え可能 (外側の配列サイズは省略可能) */
62
62
 
63
63
  char strings[][256] = {"aaa", "bbb", "ccc"};
64
64
 

4

補足

2016/06/18 11:18

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -79,3 +79,39 @@
79
79
  }
80
80
 
81
81
  ```
82
+
83
+
84
+
85
+ ---
86
+
87
+
88
+
89
+ # 補足
90
+
91
+
92
+
93
+ 以下の2つはどちらも全く同じ意味の「文字の配列」です.
94
+
95
+
96
+
97
+ ```c
98
+
99
+ char a[] = {'a', 'b', 'c', '\0'};
100
+
101
+ char a[] = "abc";
102
+
103
+ ```
104
+
105
+
106
+
107
+ 以下は「リテラルを指すアドレス」(ポインタ)です.
108
+
109
+
110
+
111
+ ```c
112
+
113
+ char *a = "abc";
114
+
115
+ // char *a = {'a', 'b', 'c', '\0'}; // この書き方はできない
116
+
117
+ ```

3

変更

2016/06/18 11:15

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
4
4
 
5
- - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
5
+ - **[constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)**
6
6
 
7
7
 
8
8
 
9
- # 「『リテラルへのポインタ』の配列」として作る場合
9
+ # 「『リテラルを指すアドレス』の配列」として作る場合
10
10
 
11
11
 
12
12
 
@@ -20,11 +20,13 @@
20
20
 
21
21
  {
22
22
 
23
- const char *strings[] = {"aaa", "bbb", "ccc"};
23
+ /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 */
24
24
 
25
- strings[1] = "BBB"; // リテラルを指すアドレスの書換はできる
25
+ const char *strings[] = {"aaa", "bbb", "ccc"};
26
26
 
27
+ strings[1] = "BBB"; // 「リテラルを指すアドレス」を上書きすることはできる
28
+
27
- // strings[0][0] = 'A'; // リテラルの中身を書き換えることはできない
29
+ // strings[0][0] = 'A'; // リテラル書きることはできない
28
30
 
29
31
  for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
30
32
 
@@ -56,13 +58,15 @@
56
58
 
57
59
  {
58
60
 
61
+ /* 文字の配列はconst宣言しない限りは書き換え可能 */
62
+
59
63
  char strings[][256] = {"aaa", "bbb", "ccc"};
60
64
 
61
- strcpy(strings[1], "BBB"); // 「文字」をstrcpyを用いて1文字ずつ上書きすることはできる
65
+ strcpy(strings[1], "BBB"); // 「文字の配列」をstrcpyを用いて1文字ずつ上書きすることはできる
62
66
 
63
- // strings[1] = "BBB"; // 「文字の配列」が入る場所に「リテラルを指すアドレス」を入れることはできない
67
+ // strings[1] = "BBB"; // 「文字の配列」が入るべき場所に「リテラルを指すアドレス」を入れることはできない
64
68
 
65
- strings[0][0] = 'A'; // 「文字」をstrcpyを使わずに手動で直接上書きすることはできる
69
+ strings[0][0] = 'A'; // 「文字の配列の一部をstrcpyを使わずに手動で直接上書きすることはできる
66
70
 
67
71
  for (int i = 0; i < sizeof(strings) / sizeof(strings[0]); ++i) {
68
72
 

2

追記

2016/06/18 11:10

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -1,4 +1,12 @@
1
+ - [配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)
2
+
3
+ - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
4
+
5
+ - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
6
+
7
+
8
+
1
- こういうこょうか?
9
+ # 「『リテラルへのポインタ』の配列」として作る場合
2
10
 
3
11
 
4
12
 
@@ -14,6 +22,10 @@
14
22
 
15
23
  const char *strings[] = {"aaa", "bbb", "ccc"};
16
24
 
25
+ strings[1] = "BBB"; // リテラルを指すアドレスの書換はできる
26
+
27
+ // strings[0][0] = 'A'; // リテラルの中身を書き換えることはできない
28
+
17
29
  for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
18
30
 
19
31
  printf("%s\n", strings[i]);
@@ -28,33 +40,7 @@
28
40
 
29
41
 
30
42
 
31
- - [配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)
32
-
33
- - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
34
-
35
- - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
36
-
37
-
38
-
39
- この例における `const char *strings[3]` は,以下のような構成になります.
40
-
41
-
42
-
43
- 1. 書き換え禁止領域に `{'a', 'a', 'a', '\0'}` という配列(NULL終端文字列)が作られ, `strings[0]` にその先頭要素のアドレスが代入される
44
-
45
- 2. 書き換え禁止領域に `{'b', 'b', 'b', '\0'}` という配列(NULL終端文字列)が作られ, `strings[1]` にその先頭要素のアドレスが代入される
46
-
47
- 3. 書き換え禁止領域に `{'c', 'c', 'c', '\0'}` という配列(NULL終端文字列)が作られ, `strings[2]` にその先頭要素のアドレスが代入される
48
-
49
-
50
-
51
- 以下の2点に注意してください.
52
-
53
-
54
-
55
- - 換え禁止領域を指すポインタなで,`const char`として書き換えを明示的に禁止してい
43
+ # 「『255文字まで格納でる文字配列』の配列」として場合
56
-
57
- - `*`に対して`const`制約はかかっていないので,ポインタのアドレス自体の書換はできる.
58
44
 
59
45
 
60
46
 
@@ -62,17 +48,23 @@
62
48
 
63
49
  #include <stdio.h>
64
50
 
51
+ #include <strings.h>
52
+
65
53
 
66
54
 
67
55
  int main(void)
68
56
 
69
57
  {
70
58
 
71
- const char *strings[] = {"aaa", "bbb", "ccc"};
59
+ char strings[][256] = {"aaa", "bbb", "ccc"};
72
60
 
73
- strings[1] = "ddd"; // こはできる
61
+ strcpy(strings[1], "BBB"); // 「文字」をstrcpyを用いて1文字ずつ上書きするはできる
74
62
 
63
+ // strings[1] = "BBB"; // 「文字の配列」が入る場所に「リテラルを指すアドレス」を入れることはできない
64
+
65
+ strings[0][0] = 'A'; // 「文字」をstrcpyを使わずに手動で直接上書きすることはできる
66
+
75
- for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
67
+ for (int i = 0; i < sizeof(strings) / sizeof(strings[0]); ++i) {
76
68
 
77
69
  printf("%s\n", strings[i]);
78
70
 

1

補足

2016/06/18 11:04

投稿

mpyw
mpyw

スコア5223

test CHANGED
@@ -28,4 +28,58 @@
28
28
 
29
29
 
30
30
 
31
+ - [配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)
32
+
33
+ - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
34
+
35
+ - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
36
+
37
+
38
+
31
- 代わりリテラルとして定義した場合は文字列書き換えはできなります.
39
+ 例における `const char *strings[3]` は以下よう構成になります.
40
+
41
+
42
+
43
+ 1. 書き換え禁止領域に `{'a', 'a', 'a', '\0'}` という配列(NULL終端文字列)が作られ, `strings[0]` にその先頭要素のアドレスが代入される
44
+
45
+ 2. 書き換え禁止領域に `{'b', 'b', 'b', '\0'}` という配列(NULL終端文字列)が作られ, `strings[1]` にその先頭要素のアドレスが代入される
46
+
47
+ 3. 書き換え禁止領域に `{'c', 'c', 'c', '\0'}` という配列(NULL終端文字列)が作られ, `strings[2]` にその先頭要素のアドレスが代入される
48
+
49
+
50
+
51
+ 以下の2点に注意してください.
52
+
53
+
54
+
55
+ - 書き換え禁止領域を指すポインタなので,`const char`として書き換えを明示的に禁止している.
56
+
57
+ - `*`に対して`const`制約はかかっていないので,ポインタのアドレス自体の書換はできる.
58
+
59
+
60
+
61
+ ```c
62
+
63
+ #include <stdio.h>
64
+
65
+
66
+
67
+ int main(void)
68
+
69
+ {
70
+
71
+ const char *strings[] = {"aaa", "bbb", "ccc"};
72
+
73
+ strings[1] = "ddd"; // これはできる
74
+
75
+ for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
76
+
77
+ printf("%s\n", strings[i]);
78
+
79
+ }
80
+
81
+ return 0;
82
+
83
+ }
84
+
85
+ ```