teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

追記

2016/06/18 11:19

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  int main(void)
11
11
  {
12
- /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 */
12
+ /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 (外側の配列サイズは省略可能) */
13
13
  const char *strings[] = {"aaa", "bbb", "ccc"};
14
14
  strings[1] = "BBB"; // 「リテラルを指すアドレス」を上書きすることはできる
15
15
  // strings[0][0] = 'A'; // 「リテラル」を上書きすることはできない
@@ -28,7 +28,7 @@
28
28
 
29
29
  int main(void)
30
30
  {
31
- /* 文字の配列はconst宣言しない限りは書き換え可能 */
31
+ /* 文字の配列はconst宣言しない限りは書き換え可能 (外側の配列サイズは省略可能) */
32
32
  char strings[][256] = {"aaa", "bbb", "ccc"};
33
33
  strcpy(strings[1], "BBB"); // 「文字の配列」をstrcpyを用いて1文字ずつ上書きすることはできる
34
34
  // strings[1] = "BBB"; // 「文字の配列」が入るべき場所に「リテラルを指すアドレス」を入れることはできない

4

補足

2016/06/18 11:18

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -38,4 +38,22 @@
38
38
  }
39
39
  return 0;
40
40
  }
41
+ ```
42
+
43
+ ---
44
+
45
+ # 補足
46
+
47
+ 以下の2つはどちらも全く同じ意味の「文字の配列」です.
48
+
49
+ ```c
50
+ char a[] = {'a', 'b', 'c', '\0'};
51
+ char a[] = "abc";
52
+ ```
53
+
54
+ 以下は「リテラルを指すアドレス」(ポインタ)です.
55
+
56
+ ```c
57
+ char *a = "abc";
58
+ // char *a = {'a', 'b', 'c', '\0'}; // この書き方はできない
41
59
  ```

3

変更

2016/06/18 11:15

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,17 +1,18 @@
1
1
  - [配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)
2
2
  - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
3
- - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
3
+ - **[constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)**
4
4
 
5
- # 「『リテラルへのポインタ』の配列」として作る場合
5
+ # 「『リテラルを指すアドレス』の配列」として作る場合
6
6
 
7
7
  ```c
8
8
  #include <stdio.h>
9
9
 
10
10
  int main(void)
11
11
  {
12
+ /* リテラルは書き換えてはいけないので,charに対してのconst宣言は必須 */
12
- const char *strings[] = {"aaa", "bbb", "ccc"};
13
+ const char *strings[] = {"aaa", "bbb", "ccc"};
13
- strings[1] = "BBB"; // リテラルを指すアドレスはできる
14
+ strings[1] = "BBB"; // リテラルを指すアドレス」を上きすることはできる
14
- // strings[0][0] = 'A'; // リテラルの中身を書き換えることはできない
15
+ // strings[0][0] = 'A'; // リテラル書きることはできない
15
16
  for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
16
17
  printf("%s\n", strings[i]);
17
18
  }
@@ -27,10 +28,11 @@
27
28
 
28
29
  int main(void)
29
30
  {
31
+ /* 文字の配列はconst宣言しない限りは書き換え可能 */
30
32
  char strings[][256] = {"aaa", "bbb", "ccc"};
31
- strcpy(strings[1], "BBB"); // 「文字」をstrcpyを用いて1文字ずつ上書きすることはできる
33
+ strcpy(strings[1], "BBB"); // 「文字の配列」をstrcpyを用いて1文字ずつ上書きすることはできる
32
- // strings[1] = "BBB"; // 「文字の配列」が入る場所に「リテラルを指すアドレス」を入れることはできない
34
+ // strings[1] = "BBB"; // 「文字の配列」が入るべき場所に「リテラルを指すアドレス」を入れることはできない
33
- strings[0][0] = 'A'; // 「文字」をstrcpyを使わずに手動で直接上書きすることはできる
35
+ strings[0][0] = 'A'; // 「文字の配列の一部をstrcpyを使わずに手動で直接上書きすることはできる
34
36
  for (int i = 0; i < sizeof(strings) / sizeof(strings[0]); ++i) {
35
37
  printf("%s\n", strings[i]);
36
38
  }

2

追記

2016/06/18 11:10

投稿

mpyw
mpyw

スコア5223

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

1

補足

2016/06/18 11:04

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -13,4 +13,31 @@
13
13
  }
14
14
  ```
15
15
 
16
+ - [配列とポインタの完全制覇](http://kmaebashi.com/programmer/pointer.html)
17
+ - [C言語の const とポインタについて調べてみた](http://hunyoi.com/?p=215)
18
+ - [constの位置の覚え方](http://sunafukin2go.hatenablog.com/entry/2015/06/28/234337)
19
+
16
- 代わり,リテラルとして定義した場合文字列書き換えはできなります.
20
+ 例における `const char *strings[3]` ,以下よう構成になります.
21
+
22
+ 1. 書き換え禁止領域に `{'a', 'a', 'a', '\0'}` という配列(NULL終端文字列)が作られ, `strings[0]` にその先頭要素のアドレスが代入される
23
+ 2. 書き換え禁止領域に `{'b', 'b', 'b', '\0'}` という配列(NULL終端文字列)が作られ, `strings[1]` にその先頭要素のアドレスが代入される
24
+ 3. 書き換え禁止領域に `{'c', 'c', 'c', '\0'}` という配列(NULL終端文字列)が作られ, `strings[2]` にその先頭要素のアドレスが代入される
25
+
26
+ 以下の2点に注意してください.
27
+
28
+ - 書き換え禁止領域を指すポインタなので,`const char`として書き換えを明示的に禁止している.
29
+ - `*`に対して`const`制約はかかっていないので,ポインタのアドレス自体の書換はできる.
30
+
31
+ ```c
32
+ #include <stdio.h>
33
+
34
+ int main(void)
35
+ {
36
+ const char *strings[] = {"aaa", "bbb", "ccc"};
37
+ strings[1] = "ddd"; // これはできる
38
+ for (int i = 0; i < sizeof(strings) / sizeof(char *); ++i) {
39
+ printf("%s\n", strings[i]);
40
+ }
41
+ return 0;
42
+ }
43
+ ```