プログラミング実習II (2025) 課題
[E9] 第8章 ポインタ
(E9_1) 下のプログラムをコンパイルして実行せよ.表示される結果 (1) と (2) に対して, なぜそのような結果が表示されるのかを, 次の例に倣って説明せよ.
(0) では a=1234, b=1972, c=1234, p= 0xffffcbe8, q=0xffffcbe0, *p=1234, *q=1972 と表示される. まず, p = &a; q = &b; を実行すると, p に a のアドレスが, q に b のアドレスが入る. この時点で の変数のアドレスと内容は, 次の通りである. 0xffffcbfc番地 a = 1234 0xffffcbf8番地 b = 5678 0xffffcbf4番地 c = 7777 0xffffcbe8番地 p = 0xffffcbfc (a のアドレス) 0xffffcbe0番地 q = 0xffffcbf8 (b のアドレス) 次に, c = *p; を実行する. *p は「0xffffcbfc番地の内容」なので, それはつまり a の内容 である. 言い換えると, この文は, c = a; と等価であり, c には 1234 が代入される. 次に, *q = 1972; であるが, *q は「0xffffcbf8番地の内容」なので, それはつまり b の内容で ある. 言い替えると, この文は, b = 1972; と等価であり, b には 1972 が代入される. 従って, (0) の時点では, a = 1234 b = 1972 c = 1234 p = 0xffffcbfc (a のアドレス) q = 0xffffcbf8 (b のアドレス) *p = 1234 (a の内容) *q = 1972 (b の内容) が表示される. |
(プログラム)
#include <stdio.h> int main(void) { int a = 1234; int b = 5678; int c = 7777; int *p, *q; printf("a の番地は %p \n", &a); printf("b の番地は %p \n", &b); printf("c の番地は %p \n", &c); printf("p の番地は %p \n", &p); printf("q の番地は %p \n", &q); p = &a; q = &b; c = *p; *q = 1972; printf("(0) a=%d, b=%d, c=%d, p=%p, q=%p, *p=%d, *q=%d\n", a, b, c, p, q, *p, *q); p = &b; q = &c; a = *q + 10; *p = 9999; printf("(1) a=%d, b=%d, c=%d, p=%p, q=%p, *p=%d, *q=%d\n", a, b, c, p, q, *p, *q); p = q; *p = *q / 2; printf("(2) a=%d, b=%d, c=%d, p=%p, q=%p, *p=%d, *q=%d\n", a, b, c, p, q, *p, *q); return 0; } |
(E9_2) 下のプログラムの実行し,行われている計算を確認してレポートで説明せよ.
その上で,
before: a=10,b=20 after: a=200,b=4000 |
#include <stdio.h> void calc( int *x, int *y ) { *x = *x + 1; *y = *y * 2; } int main( void ) { int a = 10; int b = 20; printf("before: a=%d, b=%d\n", a, b); calc( &a, &b ); // a と b のアドレスを渡している printf("after: a=%d, b=%d\n", a, b); return 0; } |
(E9_3) プログラムが,下記の動作をするように関数 sort2 と sort3 を完成せよ(main は変更不要).
#include <stdio.h> void sort2( int *a, int *b ) { } void sort3( int *a, int *b, int *c ) { // sort2 を使用 } int main( void ) { int x, y; int l, m, n; // 整数 x, y を受け取る printf("Enter an integer:"); scanf("%d", &x); printf("Enter another integer:"); scanf("%d", &y); sort2( &x, &y ); // 整数 x, y を降順で表示 printf("Print in decreasing order: %d %d \n", x, y ); // 整数 l, m, n を受け取る printf("Enter an integer:"); scanf("%d", &l); printf("Enter another integer:"); scanf("%d", &m); printf("Enter yet another integer:"); scanf("%d", &n); sort3( &l, &m, &n ); // 整数 x, y, z を降順で表示 printf("Print in decreasing order: %d %d %d \n", l, m, n ); return 0; } |
(E9_4) ポインタを用いて複数の値を関数の呼び出し元に返すことができる.
正の整数 n に対して,n = 2s × u を満たす非負の整数 s と奇数 u を求めて表示したい.以下のプログラムの関数 factoring1 を完成せよ.
例えば,n = 360 のとき,s = 3, u = 45(360 = 23 × 45)である.
さらに,正の整数 n に対して,n = 2s × 3t × u を満たす非負の整数 s,t と u を求めて表示したい.u は 3 で割り切れない奇数とする.以下のプログラムの関数 factoring2 を完成せよ.
例えば,n = 360 のとき,s = 3, t = 2, u = 5(360 = 23 × 32 × 5)である.
#include <stdio.h> void factoring1( int n, int *s, int *u ){ // 計算はこの関数内で定義したローカル変数を用いて行ってよい. // (計算結果を *s, *u に代入する) } void factoring2( int n, int *s, int *t, int *u ){ // 計算はこの関数内で定義したローカル変数を用いて行ってよい. // (計算結果を *s, *t, *u に代入する) } int main(void) { int n; int s, t, u; printf("正の整数を入力して下さい \n"); scanf( "%d", &n ); printf("%d = 2^%d * %d \n", n, s, t ); printf("%d = 2^%d * 3^%d * %d \n", n, s, t, u ); return 0; } |
(E9_5) 下のプログラムを実行し,配列とポインタの類似性を確認せよ.
#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) ); printf("\n"); return 0; } |
(E9_6) キックオフC言語 9章 ソースコード 9.1 の関数 str_length, ソースコード 9.2 の関数 str_copy,ソースコード 9.3 の関数 str_concat をポインタを使用した ものに書き換えることで,以下のプログラムを完成せよ.
#include <stdio.h> #define M 128 int str_length( char *str ){ } void str_copy( char *dest, char *src ){ } void str_concat( char *dest, char *src ){ } int main(void) { char str1[M] = "Kwansei Gakuin"; char str2[M]; printf("length = %d \n", str_length( str1 ) ); str_copy( str2, "University"); str_concat( str1, " "); str_concat( str1, str2 ); printf("%s \n", str1 ); return 0; } |
(E9_7*) 2 次元平面上の点 (x,y) を, 原点を中心に半時計回りに r_degree 度だけ回転させた点に変換する関数 void rotate(double *x, double *y, double r_degree) を作成せよ. 下のようなプログラムで次の結果が得られることを確認せよ (0 が -0.00000000 等と表示される等, 小数点表示やその誤差は気にしなくてよい).
#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; } |