マクロをfor文やscanf関数の使われたプログラム内で便利に使ってみます

アレサ

「では マクロの便利な利用法 を見ていきますよ ソーラーさん」


ソーラー「な、なんか  アレサ 元気がいいね 


精霊さんたちをみて


元気がでてきたみたいだ・・・」


アレサ「はいっ、私、とても元気なんです🌞


それでは 早速参ります。


次のプログラムでは


配列strの配列変数

str[0]

str[1]

str[2]

str[3]

str[4]

str[5]

str[6]

str[7]

str[8]

1

2

3

4

5

6

7

8

9


を格納したのち

str[0]

str[1]

str[2]

str[3]

str[4]

に格納された

1

2

3

4

5


for文を使い


printf出力表示しています。


ここで

for文の条件式を i<TSKOS

マクロの定義を

#define TSKOS 5

とすることにより

for文の条件式

i<TSKOS

i<5

とみなされるよう設定しています。


#include<stdio.h>


#define TSKOS 5


int str[]={1,2,3,4,5,6,7,8,9};

int main(void){

int i;

for(i=0;i<TSKOS;i++)

printf("%d\n",str[i]);

printf("取り出した数値の個数は%dです\n",TSKOS);

return 0;

}


コンパイル結果

1

2

3

4

5

取り出した数値の個数は5です


ソーラー「ね、ねえ このTSKOSって 


もしかして 


T  ;取り出した

S ; 数値の

KO ; 個

S ; 数


取り出した数値の個数という意味合いがあるのかな?」


アレサ「はいっ わかりやすくするために ダイレクトに


取り出した数値の個数イコールTSKOS


で表現してみました。」


ソーラー 「ほ、ほう・・・


では このプログラムのマクロの定義では


#define TSKOS 5


となってるよね。


ということは


TSKOSとかかれた箇所は5とみなされるいうことになる。


for文の条件式

i<TSKOS

i<5

とみなされ

配列strから取り出して表示される数値の個数は

1

2

3

4

5

の5個ということになるかな。


とりあえず

マクロを使わず


TSKOSを5に置き換えると


プログラムは次のようにかきかえられます。


#include<stdio.h>


int str[]={1,2,3,4,5,6,7,8,9};

int main(void){

int i;

for(i=0;i<5;i++)

printf("%d\n",str[i]);

printf("取り出した数値の個数は%dです\n",5);

return 0;

}

コンパイル結果

1

2

3

4

5

取り出した数値の個数は5です



アレサ「マクロの便利なところは


ここで 取り出したい数値の個数を

1

2

3

4

5

6

7

8

に増やしたいなら


マクロの定義を


#define TSKOS 5


から


#define TSKOS 8に書き換えるだけで


TSKOS 


と書かれた箇所がすべて8に書き換えられるところにあります。」


ソーラー「


マクロの定義を使わないで


普通に数値1,2,3,4,5,6,7,8,9を配列に取り込み


1,2,3,4,5を表示したい場合は


前のプログラムで次のように記述されました。


#include<stdio.h>


int str[]={1,2,3,4,5,6,7,8,9};

int main(void){

int i;

for(i=0;i<5;i++)

printf("%d\n",str[i]);

printf("取り出した数値の個数は%dです\n",5);

return 0;

}

コンパイル結果

1

2

3

4

5

取り出した数値の個数は5です


ふつうは

ここで 取り出したい数値の個数を


     5から8に変更したいとすると


手動で5の部分を1つずつ8に書き換えて変更することになる・・・


実際に


プログラムを手動で書き換えてみると・・・


#include<stdio.h>


int str[]={1,2,3,4,5,6,7,8,9};

int main(void){

int i;

for(i=0;i<8;i++)

printf("%d\n",str[i]);

printf("取り出した数値の個数は%dです\n",8);

return 0;

}

コンパイル結果

1

2

3

4

5

6

7

8

取り出した数値の個数は8です


ソーラー「ちょっと5から8への数値の書き換えが間違えやすいかな?」


アレサ「そうなのです。


もっと複雑で長いプログラムでは 手動では


さらに 数値を書き換えるのに時間がかかり、


なおかつ 書き換え忘れの箇所もでてくると思われます。


そこで あとから数値の変更が行われるであろうという個所は


数値の書き換えが

簡単に

できるようにするために


マクロを使って


数値が入れ替わるであろう箇所を 最初から


TSKOS のように表現しておけばよいわけです」



ソーラー「それは便利だね 


ここで


じゃあ


 次は取り出したい数値の個数を2に変更したい


 となれば


#define TSKOS 5

から

#define TSKOS  2


次は7に変更したいなら


#define TSKOS  2

から

#define TSKOS  7

へと


マクロの定義の数値部分を1箇所


変更するだけで


プログラム内の全てのTSKOS の部分が


すぐに書き換えできるんだね、、、、、、、、、、、、」



アレサ「マクロはscanf関数を使用したプログラムにも


有効に活用できます。


scanf関数をつかって


5個の数値をコンピュータのメモリに格納したいとします


次のプログラムでは


scanf関数をつかって入力された数値を


配列strに格納していきます。


int str[100];


により

配列strが作製されますが

そのとき

配列str内に配列変数が


str[0]

str[1]

str[2]

str[3]

str[99]

のように100個生成されています


ですので


配列strの配列変数たちには

100個の数値が格納できますので


5個の数値の入力なら十分格納できるほど


配列変数が存在しています


#include<stdio.h>


#define KSKOS 5


int main(void){

int i;

int str[100];

/*数値をたくさんとりこんでもいいよう要素数は100にしてあります*/

for(i=0;i<KSKOS ;i++){

printf("好きな数値を入力してください\n");

scanf("%d",&str[i]);};


for(i=0;i<KSKOS ;i++)

printf("%d番目に格納した数値は%dです\n",i+1,str[i]);

return 0;

}

コンパイル結果

好きな数値を入力してください

1 (と入力してみます)

好きな数値を入力してください

2 (と入力してみます)

好きな数値を入力してください

3 (と入力してみます)

好きな数値を入力してください

4 (と入力してみます)

好きな数値を入力してください

5 (と入力してみます)


1番目に格納した数値は1です

2番目に格納した数値は2です

3番目に格納した数値は3です

4番目に格納した数値は4です

5番目に格納した数値は5です



ソーラー「ここでKSKOSとは


K  ;格納したい

S ; 数値の

KO ; 個

S ; 数


を表しているんだね


つまり

ユーザーから

受け取りたい数値の個数のことなんだね。


マクロの定義

#define KSKOS 5

により


プログラム内で

KSKOSと記述されている部分は

5が記述されていることになる


となると

このプログラムは


最初のfor文

for(i=0;i<5 ;i++)

の命令により

iの値を変えながら

printf("好きな数値を入力してください\n");

scanf("%d",&str[i]);};

5回くりかえし


次のfor文

for(i=0;i<5 ;i++)

の命令により

iの値を変えながら

printf("%d番目に格納した数値は%dです\n",i+1,str[i]);

5回くりかえしているんだね」


アレサ「はい


ここで


オシャレな方は


int str[100];の要素数100のところにもKSKOSを


かきこまれます。


そうすれば


ちょうど scanf関数によって


ユーザーから受け取りたい

配列strに格納したい


数値の個数(KSKOS)分だけ


配列str内に配列変数が生成されるというわけです。


例えば

int str[KSKOS];


と記述されていれば


格納したい数値の個数が10000000となっても


マクロの定義を

#define KSKOS 10000000

と変更することにより


それにあわせて


配列の要素数が

int str[10000000];

のように

10000000となり


配列str内の配列変数が10000000個生成詩され


格納したい10000000個の数値の個数を


ぴったり10000000個の配列変数に格納できるというわけです」


ソーラー 


「ちょっと話がかわるけど


scanf("%d",&str[i]);

の部分を

scanf("%d\n",&str[i]);


のように

エスケープシーケンス

\n

%d出力変換指定子のあとにつけてしまうと


コンパイル結果は


好きな数値を入力してください

1 (と入力してみます)

2 (と入力してみます)

好きな数値を入力してください

3 (と入力してみます)

好きな数値を入力してください

4 (と入力してみます)

好きな数値を入力してください

5 (と入力してみます)

好きな数値を入力してください

6(と入力してみます)


1番目に格納した数値は1です

2番目に格納した数値は2です

3番目に格納した数値は3です

4番目に格納した数値は4です

5番目に格納した数値は5です


と表示されてしまいます


このコンパイル結果 なんか・・こうバグってない?


好きな数値を入力してください

1 と入力 したあとに


好きな数値を入力してください 

のメッセージが表示されない・・・?


さらに


このプログラムのfor文の構造では5回目までしか


ユーザーから入力を受け付けることができないはずなのに


5回目の数値入力後


好きな数値を入力してください

とメッセージが表示され


6回目の数値入力ができている・・・


となっちゃうんだよ~」


アレサ「はいっ


scanf関数をつかって


数値を取り込まれるときは\nを記入しないようご注意ください😊」


ソーラー「マクロの便利な使い方のエピソードだったのに


思わぬscanf関数の仕組みのエピソードになっちゃったね。」



  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます