プログラミング実習II (2026) 課題

[E9] 第8章 ポインタ

(E9_1)

下のプログラムをコンパイルして実行せよ.表示される結果 (1)~(8) に対して, なぜそのような結果が表示されるのか,ひとつ前の表示と比較することでそれぞれ説明せよ.

#include <stdio.h>

int main( void )
{
	int a = 1234;
	int b = 5678;
	int *p, *q;

	printf("(0) a のアドレスは %p, a の値は %d \n\n", &a, a );

	p = &a;
	printf("(1) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(1) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	*p += 1111;
	printf("(2) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(2) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	a = 2048;
	printf("(3) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(3) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(3) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	b = *p;
	printf("(4) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(4) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(4) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	p = &b;
	printf("(5) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(5) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(5) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	b += 1111;
	printf("(6) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(6) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(6) p が指すアドレスは %p, そこに格納された値は %d \n\n", p, *p );

	q = p;
	printf("(7) a のアドレスは %p, a の値は %d \n", &a, a );
	printf("(7) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(7) p が指すアドレスは %p, そこに格納された値は %d \n", p, *p );
	printf("(7) q が指すアドレスは %p, そこに格納された値は %d \n\n", q, *q );

	*q -= 2222;
	printf("(8) b のアドレスは %p, b の値は %d \n", &b, b );
	printf("(8) p が指すアドレスは %p, そこに格納された値は %d \n", p, *p );
	printf("(8) q が指すアドレスは %p, そこに格納された値は %d \n", q, *q );

	return 0;
}
(E9_2)

関数からは戻り値をひとつしか返せないが,ポインタを用いることで実質的に複数の値を返すことができる.

以下のプログラムを実行し,関数 calc() で行われている計算を確認せよ.

さらに,関数 calc() での計算の結果である x, y が降順(大きい順)に表示されるように関数 sort2 を作成せよ.

#include <stdio.h>

void calc( int *p, int *q )
{
	*p = *p + 1;
	*q = *q * 2;
}

void sort2( int *p, int *q )
{

}

int main( void )
{
	int x, y;

	printf("Enter an integer:");	scanf("%d", &x);
	printf("Enter another integer:");	scanf("%d", &y);

	calc( &x, &y );
	printf("x = %d, y = %d \n", x, y );

	sort2( &x, &y );
	printf("Print in decreasing order: %d %d \n", x, y );

	return 0;
}
(E9_3)

キックオフC言語,7.4節 練習問題4 と同様に,b/a + d/c の結果を表す分数 ( bc + ad ) / ac を計算して(本問では約分されていない分数を表示しても構わない)表示したい.ただし,簡単のため,a, b, c, d > 0 とする.

本問では分母を返す関数と分子を返す関数を別にせず,関数 void add_frac( int a, int b, int c, int d, int *num, int *den ) を作成することとする.ここで,*num は分子を表す変数に対するポインタ,*den は分母を表す変数に対するポインタである.

(E9_4)

下のプログラムを実行し,配列名 a&a[0],および *aa[0] などの対応関係から,配列とポインタの類似性を確認せよ.

#include <stdio.h>

int main( void )
{
    int a[4] = { 100, 101, 102, 103 };

    printf("%p %p %p %p \n", &a[0], &a[1], &a[2], &a[3] );
    printf("%p %p %p %p \n", a, a+1, a+2, a+3 );

    printf("%d %d %d %d \n", a[0], a[1], a[2], a[3] );
    printf("%d %d %d %d \n", *a, *(a+1), *(a+2), *(a+3) );

    return 0;
}
(E9_5)

キックオフC言語 9章のソースコード 9.1 にある自作関数 str_length() をポインタを用いた形式に書き換えよ.str[ i ] をポインタを用いて書き換えればよい.なお,キックオフC言語 9.4 節の説明には文字列とポインタに関する説明がある.

下のプログラム内で指定された文字列の長さは 25 である.

#include <stdio.h>

int str_length( char *str ){

}

int main(void)
{
	char str[] = "Kwansei Gakuin University";

	printf("length = %d \n", str_length( str ) );

	return 0;
}
(E9_6*)

(x, y) を原点中心に反時計回りに r_degree 度回転させる関数 void rotate(double *x, double *y, double r_degree) を作成せよ.

  (1,1) を 90 度回転 → (-1,1)
  (1,1) を 180 度回転 → (-1,-1)
  (1,1) を 270 度回転 → (1,-1)
  (1,1) を 360 度回転 → (1,1)
  (1,1) を 45 度回転 → (0,1.414214)
  (1,0) を 30 度回転 → (0.866025,0.5)
#include <stdio.h>
#include <math.h>

void rotate(double *x, double *y, double r_degree)
{
  /* 本体は自分で書いてね */
}

int main(void)
{
	double x, y, theta;

	printf("x = ");
	scanf("%lf", &x);
	printf("y = ");
	scanf("%lf", &y);
	printf("theta [度] = ");
	scanf("%lf", &theta);
	printf("(%f,%f) → ", x, y);
	rotate(&x,&y,theta);
	printf("(%f,%f)\n", x, y);

	return 0;
}
(E9_A)

「キックオフ C言語」第9章 ソースコード 9.7 を作成・実行し,「ポインタの配列」の扱いについて,ソースコード 9.8 と併せて観察せよ.