作者:Meng Kai
1. 选择题
题⽬:以下正确的说法是( )。
A. 定义函数时,形参的类型说明可以放在函数体内。
B. return后边的值不能为表达式。
C. 如果函数值的类型与返回值类型不⼀致,以函数值类型为准。
D. 如果形参与实参类型不⼀致,以实参类型为准。
答: C.
原因:
A:形参的类型说明需放在形参表列内说明。
B: return
后的值可以为表达式。
C:正确。
D:形参和实参不一致时,应以形参为准。
2. 选择题
题⽬:若调⽤⼀个函数,且此函数中没有return语句,则正确的说法是:该函数( )。
A. 没有返回值
B. 返回若⼲个系统默认值
C. 能返回⼀个⽤户所希望的值
D. 返回⼀个不确定的值
答: D.
解析:
通过设计了一串代码,来尝试证实此题:
#include <stdio.h>
int test1(int a, int b);
int test2(int a, int b);
int main()
{
int a = 2, b = 3;
printf("Test1:%d\nTest2:%d", test1(a, b), test2(a, b));
return 0;
}
int test1(int a, int b) //函数一
{
int x;
x = (a + b) * 2;
return x; //该函数运行后返回值为10
}
int test2(int a, int b) //函数二
{
int x, y;
x = (a + b) * 2; //只有第一句时,函数返回值为10
y = (a + b) / 2; //只有前两句时,函数返回值为2
(a + b) * 4; //三句都存在时,函数返回值为2
}
其中的函数二没有return
语句,一共进行了三次运行:
①函数二中只有x = (a + b) * 2;
一句,返回值为10.
②函数二中只有x = (a + b) * 2;
和y = (a + b) / 2;
两句,返回值为2.
③函数二有x = (a + b) * 2;
·y = (a + b) / 2;
和(a + b) * 4;
三句,返回值为2.
从结果来看,①和②次运行时,返回值都分别是x和y的值。这看似是返回了正确的结果,但当第③次运行时,表达式(a + b) * 4;
的结果应该为20,但最后的返回值仍为2。
通过查阅资料了解到:
函数在执行return
语句时,会将其右边语句的值保存在eax寄存器1中,然后整个函数语句被调用时的值就是eax寄存器里面的值。
如果函数中没有return
语句,那么返回的也就自然是上一次变量对应eax寄存器里面的值。
3. 填空题
题⽬:有以下程序,程序运⾏后的输出结果是( )。需附上简要解释。
float fun(int x, int y) {
return (x + y);
}
void main() {
int a = 2,b = 5,c = 8;
printf("%3.0f\n", fun((int) fun(a + c, b), a - c));
}
答: 运行后的输出结果为空格 空格 9。
如图所示:
原因:
①printf("%3.0f\n", fun((int) fun(a + c, b), a - c));
一句中,首先计算函数fun(a + c, b)
,得出的值为15。
②接着运行fun((int) fun(a + c, b), a - c)
,即fun(15 , a - c)
,得出的值为9。
③最后运行printf()
语句,要求输出的格式为%3.0f
。其中3表示数据表示至少3位,后面的.0表示小数点后保留零位(即无小数部分)。由于9这个值不足三位,于是在前面补两个空格。
4. 填空题
题⽬:有以下程序,程序运⾏后的输出结果是( )。
int f (int n)
{
if (n == 1) return 1;
else return f(n - 1) + 1;
}
void main()
{
int i, j = 0;
for (i = 1; i < 3; i++) j += f (i);
printf ("%d\n", j);
}
本题涉及递归函数的概念,下周会讲到这个话题,但现有课程知识⼤家⾜以推出答案,来试⼀试吧~~~
答: 运行后的输出结果为3。
原因:
①首先从语句for (i = 1; i < 3; i++) j += f (i);
开始,i的值为1,首先计算j += f (1)
,从函数中的if (n == 1) return 1;
了解到,f(1)
得到的返回值为1。
②接着计算j += 1
,得到j的值为0 + 1
等于1,并执行i++
。
③接下来i的值为2,满足条件i < 3
,便开始计算j += f (2)
,从函数中的else return f(n - 1) + 1;
了解到,f(2) = f(1) + 1
,已知f(1)
的值为1,于是f(2)
的值为2。
④接着计算j += 2
,得到j的值为1 + 2
等于3,并执行i++
。
⑤接下来i的值为3,不满足条件i < 3
,跳出for循环语句,执行printf ("%d\n", j);
,于是便输出j的值3。
5. 编程题
编写⼀个函数 palindrome
, 该函数⽤于判断⼀个数是否是回⽂数。然后在主函数中使⽤该函数,判断位数为5的正整数的回⽂数数量。
1.回⽂数是指某数与其反序数相等,如5、131、1551、345676543.
2.位数为5的正整数,即 [10000, 99999) 之间的正整数。
答:
代码如下:
#include <stdio.h>
int palindrome(int num);
int main()
{
int num, i, count = 0, start = 10000, end = 99999;
for(num = start; num <= end; num++)
{
i = palindrome(num);
if(i == 1) //若为回文数,则count加一
count++;
}
printf("位数为5的正整数的回文数数量为:%d", count);
return 0;
}
int palindrome(int num) //函数:判断回文数
{
int f1, f2, f3, f4;
f1 = num / 10000;
f2 = num % 10000 / 1000;
f3 = num % 100 / 10;
f4 = num % 10;
if(f1 == f4 && f2 == f3) //满足万位与个位相同,千位与十位相同,便为回文数
{
return 1; //回文数返回值为1
}
else
return 0; //非回文数返回值为0
}
运行结果如下:
6. 编程题 (附加题)
编写⼀个函数 symPalindrome
, 该函数⽤于判断⼀个数是否为对称回⽂数。然后在主函数中使⽤该函数,判断位数为5的正整数的对称回⽂数数量。
对称回⽂数指某数与其平⽅都是回⽂数。例如,n=11时,112 =121 ;n=111时,1112 = 12321 。
答:
代码如下:
#include <stdio.h>
int symPalindrome(int num);
int main()
{
int num, i, count = 0, start = 10000, end = 99999;
for(num = start; num <= end; num++)
{
i = symPalindrome(num);
if(i == 1) //若为对称回文数,则count加一
count++;
}
printf("位数为5的正整数的对称回文数数量为:%d", count);
return 0;
}
int symPalindrome(int num) //函数:判断对称回文数
{
int f1, f2, f3, f4, nums0, nums1, nums2;
f1 = num / 10000;
f2 = num % 10000 / 1000;
f3 = num % 100 / 10;
f4 = num % 10;
if(f1 == f4 && f2 == f3) //满足万位与个位相同,千位与十位相同,便为回文数
{
/*printf("%ld\n", num);*/
int square = num * num;
nums0 = square;
nums2 = 0;
while (nums0 != 0) //计算平方后的数的倒序数
{
nums1 = nums0 % 10;
nums2 = nums2 * 10 + nums1;
nums0 /= 10;
}
if(nums2 == square) //判断倒序数与原数是否相等
{
/*printf("%ld, %ld", nums2, square);*/
return 1; //相等则为对称回文数
}
else
return 0;
}
else
return 0; //非回文数返回值为0
}
运行结果如下:
关于eax寄存器…
形参以及内部变量的值都是临时存放在eax寄存器里面的,所以它的值是时刻更新的,也就是最后一次被更新的变量的值。这也便解释了为什么第③次运行不是返回最后一条语句(a + b) * 4;
的值,而是最后一次被更新的变量y的值。 ↩︎