以下の問いに答えよ。
[1] 次のC言語プログラムの標準出力への出力結果を示せ。
#include<stdio.h>
int main(void){
int a=0xf0f0, b=0x9876; char s[]="Nagoya_Univ";
printf("%d\n%x\n%d\n%x\n%c", a, a<<2, a|b, a^b, s[7]);
return 0;
}[2] 2つの自然数の最大公約数を求める方法にユークリッドの互除法がある。この方法では,2つの自然数について,のによる剰余をとすると,ととの最大公約数はととの最大公約数に等しいという性質を用いている。これを実現するプログラムの処理過程は以下のようになる。下線部を適切な言葉や数式を用いて埋めよ。
- ステップ1: のによる剰余を計算する。
- ステップ2: であれば,を最大公約数として返して出力してプログラムを終了する。
- ステップ3: へ を代入する。
- ステップ4: へ を代入する。
- ステップ5: ステップ1へ戻る。
[3] 問題[2]で示した性質を用いて,最大公約数を返す関数func1を再帰的プログラミングによりC言語で作成した。この関数は,入力引数として整数変数をとり,返り値として最大公約数を返す。下線部を適切に埋めよ。
int func1(int a, int b){
int r = ______(1)______};
if( ______(2)______){
return ______(3)______};
}else{
return func1(______(4)______);
}
}[4] 問題[3]の関数func1の引数にを,にを代入してプログラムを実行する。このとき,関数func1が再帰的に呼び出される回数と,関数func1が再帰的に呼び出される毎の変数との値を示せ。
[5] 大きさがである整数型1次元配列の各要素に任意の整数が代入されている。配列の各要素のなかの最大値を求める関数func2を,再帰的プログラミングによりC言語で作成した。作成した関数func2は,を引数として受け取り,配列の各要素のなかの最大値を返り値として返す。下線部を適切に埋めよ。
int func2(int a[], int n){
int ______(1)______;
if( ______(2)______){
return a[0];
}else{
v1 = func2(______(3)______);
v2 = a[n-1];
if(______(4)______){
return v1;
}else{
return v2;
}
}
}解答:
[1]
よって、出力結果は
[2]
ユークリッドの互除法のアルゴリズムにより、
[3]
再帰的プログラミングの構造により、
[4]
の実行過程:
よって、
[5]
配列の最大値を求める再帰的構造と未宣言変数の補完により、
这是一道综合考察C语言基础语法和递归算法的题目。第一题要求计算并输出十六进制数的位运算和移位运算结果,需要注意十六进制到十进制的转换,以及%d输出有符号十进制数和%x输出十六进制数的区别,同时还考察了字符串数组的索引读取。第二题与第三题共同考察欧几里得辗转相除法求最大公约数的核心原理,通过先理解迭代的思想,进而将其转化为带有明确递归边界条件和参数传递的递归代码,考察对底层算法转译为高级语言的能力。第四题通过手动代入具体的实参,追踪程序内部的运行状态,能够清晰地分辨初始调用与递归调用的区别并得出变量状态的变化。第五题是将递归思维拓展到对一维数组的处理中,通过不断将问题规模缩小去寻找前n-1个元素的最大值,最后将其与第n个元素比较,从而考察对复杂问题进行递归分解以及局部变量定义的掌握情况。