回答編集履歴

3

N_WORDSマクロに関する追記

2021/04/05 23:54

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -277,3 +277,27 @@
277
277
  もう少し言うと、元コードにあったグローバル変数 int bangou; はユーザが意識するようなデータではありません。「今、"hello" をタイプさせられているからには bangou は1になってるはずだ」なんて考えません、bangou の存在さえ意識しないでしょう。bangou は処理内部のための、隠れた存在です。
278
278
 
279
279
  一方、 配列 word はユーザが否応なく目にするデータ("hello"などの文字列)を抱えているので、プログラムの外観=外部仕様に関わるデータと言えます。その分**他の変数よりエライ**、グローバルにするなら bangou より word が相応しい・・・みたいな気持ちです。
280
+
281
+
282
+
283
+ ```C
284
+
285
+ #define N_WORDS (sizeof(word) / sizeof(word[0]))
286
+
287
+ char *word[] = {
288
+
289
+ "hello", "world", "impossible", "knowledge", "capital",
290
+
291
+ ```
292
+
293
+ このマクロは配列の要素数をコンパイラに計算させます。一要素分のところに型名を書くこともあります。
294
+
295
+ 「#define N_WORDS (sizeof(word) / sizeof(char*))」みたいに。
296
+
297
+
298
+
299
+ 元のプログラムでは文字列を10個用意しますが、ずっと10個とは限らない事があるものです。文字列を増やしたい(減らしたいこともあるか)時、配列の初期値として並べて書いてる文字列=**初期値を書き足すだけで良い**、またそうするために「char *word[10] = { ...」とも「char *word[N_WORDS] = { ...」とも書かず、要素数を空欄にするわけ。
300
+
301
+
302
+
303
+ N_WORDS = (配列全体のバイト数 ÷ 一要素分のサイズ) 。32bit機のポインタ変数は4byte長、64bit機のポインタ変数は8byte長です。64bit機で配列word全体が80byteだから、N_WORDS = 80 ÷ 8 = 10 ・・・でも問題は、word がポインタの配列であることとか、ポインタの姿を正確にイメージできていないとか、ポインタにまつわる文法だとか、その辺りがあやふやみたいですね、ありがちだけど。でもそれは別の質問にしてもらったほうがよいかなあ。

2

質問への回答追加

2021/04/05 23:54

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -267,3 +267,13 @@
267
267
  次の課題は関数に分割することかな。ということで残念ながらツッコミどころ満載のコードでした。まだ先は長いですね。
268
268
 
269
269
  Enjoy!
270
+
271
+
272
+
273
+ ---
274
+
275
+ 配列 word[] をグローバル変数にした件ですが、強い理由はありません。普通ならローカル変数にするものです。修正を始めた時に関数の外に配列を書いたのですが、見た感じ**おさまりがよかった**のでそのままにしました。
276
+
277
+ もう少し言うと、元コードにあったグローバル変数 int bangou; はユーザが意識するようなデータではありません。「今、"hello" をタイプさせられているからには bangou は1になってるはずだ」なんて考えません、bangou の存在さえ意識しないでしょう。bangou は処理内部のための、隠れた存在です。
278
+
279
+ 一方、 配列 word はユーザが否応なく目にするデータ("hello"などの文字列)を抱えているので、プログラムの外観=外部仕様に関わるデータと言えます。その分**他の変数よりエライ**、グローバルにするなら bangou より word が相応しい・・・みたいな気持ちです。

1

少し修正

2021/04/03 00:01

投稿

rubato6809
rubato6809

スコア1382

test CHANGED
@@ -68,7 +68,7 @@
68
68
 
69
69
  「for (int i = 0; i < 10; ++i) 」と書けませんか?
70
70
 
71
- それと関係して、変数はできるだけ**変数のスコープを意識**したほうが良いです。使う場所の近くで変数定義する、使う場所の近くで初期値を代入する(score = 0; と score += 10; をできるだけ近づける等)といったことです。
71
+ それと関係して、変数はできるだけ**変数のスコープを意識**したほうが良いです。その変数が必要なブロック内で変数定義する・使う場所の近くで変数定義する、使う場所の近くで値を代入する(score = 0; と score += 10; をできるだけ近づける等)といったことです。
72
72
 
73
73
 
74
74
 
@@ -90,7 +90,7 @@
90
90
 
91
91
  ```
92
92
 
93
- という構造は見直すべきです。こうすれば良い。
93
+ という構造・break 文の位置は見直すべきです。こうすれば良い。
94
94
 
95
95
  ```
96
96
 
@@ -134,7 +134,7 @@
134
134
 
135
135
  for (int i = 5; i > 0; --i) {
136
136
 
137
- printf("(((((------> %d <------)))))\n", i);
137
+ printf("(((((------> %d <------)))))\r", i);
138
138
 
139
139
  WAIT_SECONDS(1); // 1秒間隔で繰り返す
140
140
 
@@ -144,13 +144,25 @@
144
144
 
145
145
 
146
146
 
147
- ・・・といった辺りで、関数に分割することはしてないし、変数名などもう少しブラッシュアップしたいなど心残りがあるけど、書き直してみました。
147
+ ・・・といった辺りで、関数に分割することはしてないし、マジックナンバを整理したいし、変数名などもう少しブラッシュアップしたいなど心残りがあるけど、書き直してみました。N_WORDS はタイプさせる文字列の数を増やしたい場合もあるかなという、よくある工夫です。
148
-
149
-
150
-
148
+
149
+
150
+
151
- ```
151
+ ```
152
+
152
-
153
+ #include <stdio.h>
154
+
155
+ #include <stdlib.h>
156
+
157
+ #include <time.h>
158
+
159
+ #include <string.h>
160
+
161
+ #include <unistd.h>
162
+
163
+
164
+
153
- #define WAIT_SECONDS(n) usleep((n) * 1000000)
165
+ #define WAIT_SECONDS(n) usleep((n) * 1000000)
154
166
 
155
167
  #define N_WORDS (sizeof(word) / sizeof(word[0]))
156
168
 
@@ -158,7 +170,7 @@
158
170
 
159
171
  "hello", "world", "impossible", "knowledge", "capital",
160
172
 
161
- "overcome", "analysis", "station", "linux", "misunderstanding",
173
+ "overcome", "analysis", "station", "linux", "misunderstanding",
162
174
 
163
175
  };
164
176
 
@@ -198,7 +210,7 @@
198
210
 
199
211
  for (int i = 5; i > 0; --i) {
200
212
 
201
- printf("(((((------> %d <------)))))\n", i);
213
+ printf("(((((------> %d <------)))))\r", i);
202
214
 
203
215
  WAIT_SECONDS(1); // 1秒間隔で繰り返し
204
216