回答編集履歴
3
N_WORDSマクロに関する追記
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
質問への回答追加
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
少し修正
test
CHANGED
@@ -68,7 +68,7 @@
|
|
68
68
|
|
69
69
|
「for (int i = 0; i < 10; ++i) 」と書けませんか?
|
70
70
|
|
71
|
-
それと関係して、変数はできるだけ**変数のスコープを意識**したほうが良いです。使う場所の近くで変数定義する、使う場所の近くで
|
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 <------)))))\
|
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)
|
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",
|
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 <------)))))\
|
213
|
+
printf("(((((------> %d <------)))))\r", i);
|
202
214
|
|
203
215
|
WAIT_SECONDS(1); // 1秒間隔で繰り返し
|
204
216
|
|