digirakuda ようこそ!  コンピュータの世界へ!

第13回 引数の使い方

このドキュメントは http://icrus.org/c_language_beginers_course/ 上にあります.

[課題13-1] 値渡し(pass by vale)の関数を書こう.(暗号プログラム)

[プログラム例13-1]


01: #include <stdio.h>
02: char code( char, int );
03: void main(void){
04:     char str[80];
05:     int  i, n=0;
06:
07:     while(1){
08:         printf( "\n暗号作成のときは0を\n");
09:         printf( "暗号解読のときは1を\n");
10:         printf( "終了するは2を入力して下さい:");
11:         scanf( "%d%*c", &n );
12:         if( n==2 )   /* n==2のとき終了します*/
13:             break;
14:         printf("文字列を入力して下さい\n");
15:         gets( str );
16:         if( str[0]=='\0' ) /* 文字を入力しないでリターンキーを押したとき終了します*/
17:             break;
18:
19:         for( i=0; str[i]!='\0'; i++ )
20:         str[i] = code( str[i], n );
21:
22:         if( n )
23:             printf( "暗号の解読結果====>%s\n",str );
24:         else
25:             printf( "作成された暗号====>%s\n",str );
26:     }
27: }
28:
29: char code( char c, int chk ){
30:     if( chk )
31:        return c-1;
32:     else
33:        return c+1;
34: }

行説明
19~20行 → str[i]がヌル文字に達するまで実行します.
20行目 → 関数code()を呼び出します.そのとき,1文字str[i]と変数n(暗号化:0,解読:1)を引数として渡します.そして,関数の値(戻り値)をstr[i]に代入します.
23行目 → n==1(解読) のとき実行します.
25行目 → n==0(暗号化)のとき実行します.
31行目 → n==1(解読) のとき文字コードから1引きます.それを関数の値とします.
33行目 → n==0(暗号化)のとき文字コードに1足します.それを関数の値とします.

[結果13-1]

コンパイル・実行すると次のよう表示されます.
暗号作成のときは 0を
暗号解読のときは 1を
終了するは 2を入力して下さい:0[リターン印]
文字列を入力して下さい
He is a boy.[リターン印]
作成された暗号====>If!jt!b!cpz/

暗号作成のときは 0を
暗号解読のときは 1を
終了するは 2を入力して下さい:1[リターン印]
文字列を入力して下さい
If!jt!b!cpz/[リターン印]
暗号の解読結果====>He is a boy.

暗号作成のときは 0を
暗号解読のときは 1を
終了するは 2を入力して下さい:2

リターンキーを押すとプログラムは終了します.

関数に引数として値を渡して,関数がそれを加工して関数の値として返す形になっています.これが値渡し(pass by value)です.

[課題13-2] アドレス渡し(pass by reference)の関数を書こう.

例題13-1と同じ暗号プログラムをアドレス渡しで書きます.

[プログラム例13-2]


01: #include <stdio.h>
05: void code( char *, int );
02: void main(void){
03:     char str[80];
04:     int  n=0;
06:
07:     while(1){
08:         printf( "\n暗号作成のときは0を\n");
09:         printf( "暗号解読のときは1を\n");
10:         printf( "終了するは2を入力して下さい:");
11:         scanf( "%d%*c", &n );
12:         if( n==2 )   /* n==2のとき終了します*/
13:             break;
14:         printf("文字列を入力して下さい\n");
15:         gets( str );
16:         if( str[0]=='\0' ) /* 文字を入力しないでリターンキーを押したとき終了します*/
17:             break;
18:
19:         code( str, n );
20:
21:         if( n )
22:             printf( "暗号の解読結果====>%s\n", str );
23:         else
24:             printf( "作成された暗号====>%s\n", str );
25:     }
26: }
27:
28: void code( char *s, int chk ){
29:     while( *s!='\0' ){
30:         if( chk )
31:             (*s)--;
32:         else
33:             (*s)++;
34:         s++;
35:     }
36: }

19行目→関数code()を呼び出します.そのとき,文字型のポインタ定数strと変数n(暗号化:0,解読:1)を引数として渡します.
22行目→n==1(解読) のとき実行します.
24行目→n==0(暗号化)のとき実行します.
29行~36行→34行目でポインタsをインクリメントしながら(指す文字を1つ次にずらしながら),文字*s(ポインタsが指す1文字)がヌル文字\0になるまで繰り返します.
31行目→n==1(解読) のとき文字コードから1引きます.
33行目→n==0(暗号化)のとき文字コードに1足します.

[結果13-2]

結果は[結果13-1]と同じです.

 関数に引数としてポインタを渡して,関数が渡されたポインタをずらしながらヌル文字に当たるまで,ポインタの指す1文字を加工(「++」インクリメントか「--」ディクリメン)します.これは,main関数の配列strを直接変更することと同じです.これがアドレス渡し(pass by reference)です.
 値渡しの関数は,引数で渡された値を加工して,加工したものを関数の値としてreturn文で返します.アドレス渡しの関数は,引数として配列やポインタを渡されます.関数はその引数のポインタによりどこに値が格納されているかわかりますので,自由にその値を変更できます.このプログラム例では文字列を扱っていますが,単なる変数xを扱った場合でも,例えば


 main(){
     int  x=0;
     func( &x );
 }

 func(int *a){
     *a=10;
 }


のように変数xのアドレスを関数func()に渡して,関数func()で,*a=10
を実行すれば,そのときmain関数の変数xの値は10になります.

[文法13]

1.値渡し(pass by value)

①引数が値であることをいいます.
②呼び出された関数側では変数の値しかわかりませんから,呼び出された関数側で値を変更しても,メイン(呼び出した関数)側の変数は変化しません.

2.アドレス渡し(pass by reference)


①引数がポインタ(アドレス)であることをいいます.
②呼び出された関数側で変数がどのに格納されているかわかりますので,そこを指すポインタを使ってメイン(呼び出した関数)側の変数や配列を直接変更できます.


このドキュメントは http://icrus.org/c_language_beginers_course/ 上にあります.

2017,1 ssatoh@ 足立工科大学 工学部 情報通信工学科