第6回:関数とポインタ(2)


前回の演習では値参照とアドレス参照,ポインタを使って配列を関数に渡す方法などの具体的なプログラミング例を学んだ. 今回の演習ではさらにいろいろな例題を通して関数,ポインタなどへの理解を深める.


まず,前回の演習課題がまだ出来ていない人は,第4回第5回を参考に関数とポインタを理解しよう.

(1)変数 a と b の値を,入れ替えるswap()関数を作成せよ.


#include <stdio.h>

void swap(int *pa, int *pb)
{
    int tmp;  /*  一時記憶用の変数  */

    tmp = *pa;    /*  pa の指す「値」を,tmp に代入  */
    *pa = *pb;
    *pb = tmp;

    return;     /*  戻り値なし  */
}

void main()
{
    int a,b;

    printf("a=");
    scanf("%d", &a);   /*  & はアドレスを取り出す演算子!  */

    printf("b=");
    scanf("%d", &b);

    printf("入替前:a=%d, b=%d¥n", a, b);

    swap(&a, &b);     /*  関数の呼び出し.引数に変数 a,b のアドレスを渡す  */

    printf("入替後:a=%d, b=%d¥n", a, b);

}

(2)実数型配列の要素の平均値を求める関数を作成せよ. 例えば,配列データを float data[] = {3.4, 2.0, 7.4, 5.0, 2.7}; とする.


#include <stdio.h>

/* p は配列の先頭アドレス,n は配列の要素数*/
float calc_ave(float *p, int n)
{
    int i;
    float ave;

    ave = 0.0;

    for(i = 0; i < n; i++) {
        ave += *( p + i );
    }

    ave /= n;

    return ave;

}

void main()
{
    float data[] = {3.4, 2.0, 7.4, 5.0, 2.7};
    printf("配列の合計は %f です.¥n", calc_ave(data, 5) );  /*  関数 calc_ave の戻り値を,直接 printf に引数として渡す  */
}

(3)整数型配列の要素をキーボードから10個入力し,その最大値と最小値を求めるプログラムを作成せよ.


#include <stdio.h>

void max_min(float *p,int n, float *max, float *min)       /*  要素数 n 個,配列の先頭のアドレス p を引数とする関数  */
{
	int i;
	
	*max = *min = *p;
	
	for(i=0; i<n; i++){
		if(*max < *(p+i)){
			*max = *(p+i);
		}
	}
	
	for(i=0; i<n; i++){
		if(*min > *(p+i)){
			*min = *(p+i);
		}
	}
	
    return ;
}

void main()
{
	int i;
	float max, min;
	float data[10];
    
	for(i=0; i<10; i++){
		printf("%d番目の要素を入力", i+1);
		scanf("%f", &data[i]);
	}

	max_min(data, 10, &max, &min);
	
	printf("最大値は%fです¥n", max);
	printf("最小値は%fです¥n", min);
	
}

(4)10要素の実数型配列を作り,小さい順に並び替える(ソート)プログラムを作成せよ.


#include <stdio.h>

float swap(float *a,int n)
{
	int i,j;
	float tmp;

	for(i=0;i<n;i++){
		for(j=i+1;j<n;j++){
			if(a[i]>a[j]){
				tmp=a[i];
				a[i]=a[j];
				a[j]=tmp;
			}
		}
	}
	return 0;
}		
void main()
{
	int i;
	float a[10];

	for(i=0;i<10;i++){
		printf("a[%d]=",i+1);
		scanf("%f",&a[i]);
	}
	printf("並び替え前:¥n");
	for(i=0;i<10;i++){
		printf("a[%d]=%f¥n",i,a[i]);
	}
	swap(a,10);
	
	printf("並び替え後:¥n");
	for(i=0;i<10;i++){
		printf("a[%d]=%f¥n",i,a[i]);
	}
}

演習課題:次の機能を有する関数を作りなさい.
関数を呼び出すmain関数も作成し,作成した関数が正しく機能する事を確認する事.

(1)四角形の幅と高さを入力すると,面積と外周を求める関数.
ヒント:void area_out(float width, float height, float *area, float *out)...

(2)自由落下運動時の加速度と時間を入力すると,速度と距離を求める関数.
ヒント:void v_s(float a, float t, float *v, float *s)...

(3)抵抗と電流を入力すると,電圧と電力を求める関数.
ヒント:void v_p(float r, float i, float *v, float *p)...

(4)抵抗と電流と時間を入力すると,電圧と電力と電力量を求める関数.
ヒント:void v_p_wh(float r, float i, float h, float *v, float *p, float *wh)...

(5)実数型配列の要素をキーボードから10個入力し,その標準偏差を求めるプログラムを作成する.配列の要素を入力する関数と,標準偏差を求める関数を作成せよ.
ヒント:先週の演習課題を参考にすると良いでしょう.また,標準偏差の算出方法は前期の第9回のページを参照!



void main()
{
	float a[10], deviation;

	nyuryoku( a , 10 );

	deviation = hyojyunhensa( a , 10 );
	
	printf( "標準偏差 = %f¥n", deviation );
}

授業終了時までのプログラムと完成した提出用プログラムをoh-meijiシステムを使って提出すること.
授業終了時に送るのは出席の確認用であり,完成した課題は提出用の回に送ること.
(提出期限を厳守し,提出用の回に提出しないと採点を行わない)


また提出の行い方については,以下のページを参照してください.
課題の提出方法