回答編集履歴

2

図と説明を追加

2019/07/05 00:00

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -38,7 +38,69 @@
38
38
 
39
39
 
40
40
 
41
+ char e[7][3] と char e[7][4] の違いを図にしてみました。
42
+
43
+ ![配列の姿](f2d2108a37f3f94682194530e2cbc819.jpeg)
44
+
45
+ 二次元配列であっても、メモリ上では右側の図のように、一列に並んでいます。
46
+
47
+ char e[7][3] という配列なら
48
+
49
+ e[0][2] (== "Sun"の'n')の次は e[1][0] (== "Mon"の 'M')が続きます。間に '\0' が入る余地が無く、メモリ上では "SunMonTue..." とくっついています。 '\0' までが文字列ですから、"Sun" を表示しようとすると "SunMonTue..." を表示してしまうという次第。
50
+
51
+
52
+
53
+ ちなみに、私の手元で e[7][3], j[7][3] はこんな風に表示されました(コンパイラは やや古い GCC を使用)。
54
+
55
+
56
+
57
+ ```
58
+
59
+ 現在時刻のUNIX時間は1562282032秒です.
60
+
61
+
62
+
63
+ ***構造体tmのメンバを参照***
64
+
65
+ tm_sec : 52 秒
66
+
67
+ tm_min : 13 分
68
+
69
+ tm_hour : 8 時
70
+
71
+ tm_mday : 5 日
72
+
73
+ tm_mon : 6 月(-1)
74
+
75
+ >>>tm_mon補正 : 7 月
76
+
77
+ tm_year : 119 年(-1900)
78
+
79
+ >>>tm_year補正 : 2019 年
80
+
81
+ tm_wday : 5 (曜日コード)
82
+
83
+ >>>tm_wday英語 : FriSat@V,a
84
+
85
+ >>>tm_wday日本語 : 金土SunMonTueWedThuFriSat@V,a
86
+
87
+ ```
88
+
89
+ - "Fri" を表示すべきところ、FriSat@V,a と**ゴミまで表示された**
90
+
91
+ - "金" を表示すべきところ、金土SunMonTueWedThuFriSat@V,a と表示された
92
+
93
+
94
+
95
+ 文字列の区切り(終端)となる '\0' が無いため、**'\0' が見つかるまで表示**した結果です。
96
+
97
+
98
+
99
+ char e[7][4] であれば '\0' も格納できます。"Sun", "Mon" ... とそれぞれが区切られてあるので、"Sun" は "Sun" だけが表示されます。
100
+
101
+
102
+
41
- ただ、漢字で書く配列 j は4でよいのか、問題になる可能性があります。漢字の文字コードは一種類ではないからです。漢字コードが違うと漢字一文字のバイト数が違うので、常に長さ4で良いとは限りません。なので、「曜日を格納する領域を十分大きくと」るのが良い、という考えが出てくるわけです(でも16も必要ありません)。
103
+ なお、漢字で書く配列 j は4でよいのか、問題になる可能性があります。漢字の文字コードは一種類ではないからです。漢字コードが違うと漢字一文字のバイト数が違うので、常に長さ4で良いとは限りません。なので、「曜日を格納する領域を十分大きくと」ろうとする考えが出てくるわけです(でも16も必要ありません)。
42
104
 
43
105
 
44
106
 

1

4から16に増やした、を3から16に増やした

2019/07/05 00:00

投稿

rubato6809
rubato6809

スコア1380

test CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
 
5
- 例えば、"Sun" という文字列は 'S', 'u', 'n', '\0' と、4文字(4バイト)で構成されています。"Sun" という文字列の長さは3ですが、メモリ上では4バイト必要です。ところが、
5
+ 例えば、"Sun" という文字列は 'S', 'u', 'n', '\0' と、4文字(4バイト)で構成されています。"Sun" という文字列の長さは3ですが、メモリ上では4バイト必要なのです。ところが、
6
6
 
7
7
  ```C
8
8
 
@@ -12,13 +12,17 @@
12
12
 
13
13
  これでは '\0' (ヌル文字)を格納する場所がありません。その結果、e[7][3] とあるメモリには、'\0'を格納できずに、
14
14
 
15
- "SunMonTueWedThuFriSat" のように、**全部くっついた状態**で文字が並んでいます。そのため "Thu" 表示しようとして、ThuFriSat" と表示されてしまったのです。
15
+ "SunMonTueWedThuFriSat" のように、**全部くっついた状態**で文字が並んでいます。そのため "Thu" 表示しようとすれば、ThuFriSat" と表示されてしまのです。
16
16
 
17
- j[7][3] も同じく、各曜日文字列(漢字一文字)に続くべき '\0' が無いのでメモリには "日月火水木金土" ついいるので同じ結果になったのです。
17
+ 文字列の表示が止まるのは '\0' がある所、とって同じことです。
18
18
 
19
19
 
20
20
 
21
+ j[7][3] も同じく、各曜日文字列(漢字一文字)に続くべき '\0' が無いので、メモリには "日月火水木金土" とくっついているので同じ結果になります。
22
+
23
+
24
+
21
- 取り急ぎの対策は、'\0' が格納できるように、各曜日の長さを3から4に増やせば良いです。少なくとも "Sun", "Mon" ・・・は対策できます。
25
+ 取り急ぎの対策は、'\0' が格納できるように、各曜日の長さを3から4に増やすことです。少なくとも e 配列 "Sun", "Mon" ・・・はこれで対策できます。
22
26
 
23
27
 
24
28
 
@@ -30,11 +34,11 @@
30
34
 
31
35
  ```
32
36
 
33
- tatsu99さんが e[7][16], j[7][16] と、から16に増やしたのも、要は '\0' を格納できるようしたのです。しかし16まで増やす必要はありません。メモリの無駄遣いです。特にアスキーコードを格納する配列 e は e[7][4] で十分です。
37
+ tatsu99さんが e[7][16], j[7][16] と、から16に増やしたのも、要は '\0' を格納できるよう、場所を確保したのです。しかし16まで増やす必要はありません。メモリの無駄遣いです。特にアスキーコードを格納する配列 e は e[7][4] で十分です。
34
38
 
35
39
 
36
40
 
37
- ただ、漢字で書く配列 j は4でよいのか、問題になる可能性があります。漢字の文字コードは一種類ではないからです。漢字コードが違うと漢字一文字のバイト数が違うので、常に長さ4で良いとは限りません。なので、「曜日を格納する領域を十分大きくと」るのが良い、という考え方が出てくるわけです(でも16も必要ありません)。
41
+ ただ、漢字で書く配列 j は4でよいのか、問題になる可能性があります。漢字の文字コードは一種類ではないからです。漢字コードが違うと漢字一文字のバイト数が違うので、常に長さ4で良いとは限りません。なので、「曜日を格納する領域を十分大きくと」るのが良い、という考え方が出てくるわけです(でも16も必要ありません)。
38
42
 
39
43
 
40
44
 
@@ -56,7 +60,7 @@
56
60
 
57
61
  P.S.
58
62
 
59
- 曜日の表示に if 文を7つ続けていますが、if 文は不要です。たっただけで全ての曜日を表示できます。
63
+ 曜日の表示に if 文を7つ続けていますが、if 文は不要です。この2行だけで全ての曜日を表示できます。
60
64
 
61
65
 
62
66