共计 10864 个字符,预计需要花费 28 分钟才能阅读完成。
你也能够上程序咖(https://meta.chengxuka.com),关上大学幕题板块,岂但有答案,解说,还能够在线答题。
一、选择题
1. 对于以下递归函数,调用 f(4),其返回值为()。
int f(int n)
{if (n)
return f(n - 1) + n;
else
return n;
}
A.10
B.4
C.0
D. 以上均不是
答:A
解析:
递归函数的调用。
第一次调用函数 f,参数为 4,执行 if 语句,返回 f(3)+4,
第二次调用函数 f,参数为 3,执行 if 语句,返回 f(2)+3,
第三次调用函数 f,参数为 2,执行 if 语句,返回 f(1)+2,
第四次调用函数 f,参数为 1,执行 if 语句,返回 f(0)+1,
第五次调用函数 f,参数为 0,执行 else 语句,返回 0。
而后再一层一层将 return 的后果返回。最终失去的就是 0 +1+2+3+4 = 10。
2. 执行下列程序段后,变量 i 的值为()。
#define MA(x, y) (x*y)
i=5;
i=MA(i, i+1)-7;
A.30
B.23
C.19
D.1
答:C
解析:
函数调用时,如果实参是表达式,要先计算表达式,再把后果值传递过来。而这里应用了宏定义。宏替换不作计算,间接替换进去。
MA(i, i+1),依照 i * (i+1)
计算,i 带入给 x,i+1 带入给 y,那么 x * y
就是 x * x + 1
,计算结果就是 26,再减掉 7,最终后果就是 19。
3. 宏定义 “#define DIV(a, b) a/b”,经 DIV(x+5, y-5) 援用,替换开展后是()。
A. (x+5/y-5)
B. x+5/y-5
C. (x+5)/(y-5)
D. (x+5)/(y-5)
答:A
解析:
宏定义在应用的时候,宏替换不作计算,间接替换进去。就是 (x+5/y-5),选项 A 正确。
4. 以下程序的输入后果是()。
int x = 5, y = 7;
void swap()
{
int z;
z = x;
x = y;
y = z;
}
int main()
{
int x = 3, y = 8;
swap();
printf("%d#%d\n", x, y);
return 0;
}
A.8#3
B.3#8
C.5#7
D.7#5
答:B
解析:
题目中定义了全局变量 x=5,y=7,main() 中又定义了同名的局部变量 x=3,y=8。函数 swap (),函数里替换了 x 和 y 的值,操作的是全局变量。main() 中调用完函数后打印 x 和 y 的值,这里打印的是 main () 的局部变量,还是 3 和 8。所以选项 B 正确。
5. 上面说法中正确的是()。
A. 若全局变量仅在单个 C 文件中拜访,则能够将这个变量批改为动态全局变量,以升高模块间的耦合度
B. 若全局变量仅由单个函数拜访,则能够将这个变量改为该函数的动态局部变量,以升高模块间的耦合度
C. 设计和应用拜访动静全局变量、动态全局变量、动态局部变量的函数时,须要思考变量生命周期问题
D. 动态全局变量应用过多,将导致动静存储区 (堆栈) 溢出
答:A
解析:
A 选项:变量分为全局变量和局部变量。局部变量和形参的作用域是函数外部,全局变量的作用域是整个文件。但能够通过申明一个 extern 的全局变量拓展全局变量的作用域,也能够通过定义一个 static 的全局变量限度这种拓展。
B 选项:如果全局变量仅仅由单个函数拜访,不存在耦合度的问题
C 选项:动静全局变量、动态全局变量、动态局部变量的生命周期都为程序运行期间,其中动态局部变量的生存周期尽管为整个源程序,然而其作用域依然与局部变量雷同,当退出函数是,该变量还存在,然而不能应用。
D 选项:全局变量和动态变量都是存储在动态存储区,所以在递归调用是不会压栈,也不会造成堆栈溢出。
6. 以下 main() 函数中所有可用的变量为()。
void fun(int x)
{
static int y;
.....
}
int z;
int main()
{
int a, b;
fun(a);
.....
}
A.x,y
B.x,y,z
C.a,b,x,y, z
D.a,b,z
答:D
解析:
在 main() 中能够应用的变量包含 main() 中申明的局部变量 a 和 b,以及全局变量 z
二、填空题
1. 对于以下递归函数,调用 f(3),其返回值为()。
int f(int x)
{return((x>0)? f(x-1)+f(x-2): 1);
}
答:5
解析:
这里是递归函数调用:
f(3)
= f(2)+f(1)
= f(1)+ f(0) + f(1) = f(1)+1+f(1)
= f(0)+ f(-1) + 1 + f(0)+f(-1) = 1+1+1+1+1
= 5
2. 输出 6,下列程序的运行后果是()。
#include <stdio.h>
int f(int n, int a)
{if (n == 0)
return a;
return f(n - 1, n * a);
}
int main(void)
{
int n;
scanf("%d", &n);
printf("%d\n", f(n, 1));
return 0;
}
答:720
解析:
这里 f 函数时递归调用,当 n 为 6 时,第一次调用函数,传入参数 n 为 6,a 为 1。
f(6,1)
= f(5,6)
= f(4,30)
= f(3,120)
= f(2, 360)
= f(1,720)
= f(0, 720)
= 720
3. 下列程序的输入后果为()。
#include <stdio.h>
int f(int g)
{switch (g)
{
case 0:
return 0;
case 1:
case 2:
return 2;
}
printf("g=%d\n", g);
return f(g - 1) + f(g - 2);
}
int main(void)
{
int k;
k = f(4);
printf("k=%d\n", k);
return 0;
}
答:
g=4
g=3
k=6
解析:
递归函数调用:
k = f(4)
打印 g=4
= f(3)+f(2) = f(3)+2
打印 g=3
= f(2)+f(1) = 2+2+2 = 6
打印 k = 6
4.C 语言的编译预处理性能次要包含和()、()和()。
答:宏定义、文件蕴含、条件编译
解析:
编译预处理时 C 语言编译程序的组成部分,它用于解释解决 C 语言源程序中的各种预处理指令。
预处理性能是由很多预处理命令组成,这些命令在编译时进行通常的编译性能 (蕴含词法和语言剖析、代码生成、优化等) 之前进行解决。预处理后的后果和源程序一起在进行通常的编译操作,进而失去指标代码。预处理性能次要包含:宏定义、文件蕴含、条件编译。
5. 下列语句的运算后果为()。
#define F(x) x-2
#define D(x) x*F(x)
printf("%d,%d", D(3), D(D(3)));
答:7,-13
解析:
宏定义,是间接将数值带入。
D(3),
=3*F(3)
=3*3-2
=7
D(D(3))
=D(3)*F(D(3))
=3*F(3)*D(3)-2
=3*3-2*3*F(3)-2
=3*3-2*3*3-2-2
=9-18-2-2
=-13
三、程序设计题
题目 1:判断满足条件的三位数:编写一个函数,利用参数传入一个 3 位数 n,找出 101~ n 间所有满足下列两个条件的数:它是齐全平方数,又有两位数字雷同,如 144、676 等,函数返回找出这样的数据的个数。试编写相应程序。
答案代码:
#include <stdio.h>
#include <math.h>
int fun(int n);
int main()
{// 习题(10.3.1)
/*
判断满足条件的三位数:编写一个函数,利用参数传入一个 3 位数 n,找出 101~ n 间所有满足下列两个条件的数:它是齐全平方数,又有两位数字雷同,如 144、676 等,函数返回找出这样的数据的个数。*/
int n;
printf("input n:");
scanf("%d", &n);
printf("total= %d\n", fun(n));
return 0;
}
int fun(int n)
{
int i, d = 0;
for (i = 101; i <= n; i++)
if (((int)sqrt(i) * (int)sqrt(i)) == i)
{if (i / 100 == (i / 10) % 10 || i / 100 == i % 10 || (i / 10) % 10 == i % 10)
{printf("%d\n", i);
d++;
}
}
return d;
}
运行后果:
题目 2:递归求阶乘和:输出一个整数 n(n>0 且 n≤10),求 1!+2!+3!+…+n!。定义并调用函数 fact(n) 计算 n!,函数类型是 double。试编写相应程序。
答案代码:
#include <stdio.h>
double fact(int n);
int main()
{// 习题(10.3.2)
/*
递归求阶乘和:输出一个整数 n(n>0 且 n≤10),求 1!+2!+3!+...+n!。定义并调用函数 fact(n) 计算 n!,函数类型是 double。*/
int i, n;
double sum = 0;
printf("input n:");
scanf("%d", &n);
for (i = 1; i <= n; i++)
sum = sum + fact(i);
printf("%.0lf\n", sum);
return 0;
}
double fact(int n)
{
int result = 0;
if (n == 1)
result = 1;
if (n > 1)
result = n * fact(n - 1);
return result;
}
运行后果:
题目 3:递归实现计算 xn:输出实数 x 和正整数 n,用递归函数计算 xn 的值。试编写相应程序。
答案代码:
#include <stdio.h>
int rec(int x, int n);
int main()
{// 习题(10.3.3)
/*
递归实现计算 x^n:输出实数 x 和正整数 n,用递归函数计算 x^n 的值。*/
int x, n;
printf("input x and n:");
scanf("%d%d", &x, &n);
printf("result : %d\n", rec(x, n));
return 0;
}
int rec(int x, int n)
{if (n == 0)
return 1;
else
return rec(x, n - 1) * x;
}
运行后果:
题目 4:递归求式子和:输出实数 x 和正整数 n,用递归的办法对下列计算式子编写一个函数。
$$
f(x,n)=x-x^2+x^3-x^4+…+(-1)^{n-1}x^n(n>0)
$$
试编写相应程序。
答案代码:
#include <stdio.h>
double f(double x, int n);
double js1(double z, int b);
int main()
{// 习题(10.3.4)
/*
递归求式子和:输出实数 x 和正整数 n,用递归的办法对下列计算式子编写一个函数。*/
double x;
int n;
printf("input x and n:");
scanf("%lf%d", &x, &n);
printf("%.2lf\n", f(x, n));
return 0;
}
double f(double x, int n)
{
double sum;
double b;
if (n == 0)
return 0;
int z;
if (n % 2 == 0)
z = -1;
else
z = 1;
b = z * js1(x, n);
sum = b + f(x, n - 1);
return sum;
}
double js1(double x, int n)
{if (n == 0)
return 1;
return x * js1(x, n - 1);
}
运行后果:
题目 5:递归计算函数 ack(m, n):输出 m 和 n,编写递归函数计算 Ackermenn 函数的值:
$$
ack(m,n)=
\begin{cases}
n+1 & m=0\\
ack(m-1,1) & n=0\&\&m>0\\
ack(m-1,ack(m,n-1)) & m>0 \&\& n>0
\end{cases}
$$
试编写相应程序。
答案代码:
#include <stdio.h>
int Ack(int m, int n);
int main()
{// 习题(10.3.5)
/*
递归计算函数 ack(m, n):输出 m 和 n,编写递归函数计算 Ackermenn 函数的值:*/
int m, n;
int result;
printf("input m and n:");
scanf("%d%d", &m, &n);
result = Ack(m, n);
printf("Ackerman(%d,%d)=%d\n", m, n, result);
return 0;
}
int Ack(int m, int n)
{if (m == 0)
return n + 1;
else if (n == 0)
return Ack(m - 1, 1);
else
return Ack(m - 1, Ack(m, n - 1));
}
运行后果:
题目 6:递归实现求 Fabonacei 数列:用递归办法编写求斐波那契数列的函数,函数类型为整型,斐波那契数列的定义如下。试编写相应程序。
$$
f(n)=f(n-2)+f(n-1)(n>1)
$$
其中 f(0)=0,f(1)= 1。
答案代码:
#include <stdio.h>
long fib(int n);
int main()
{// 习题(10.3.6)
/*
递归实现求 Fabonacei 数列:用递归办法编写求斐波那契数列的函数,函数类型为整型,斐波那契数列的定义如下。*/
int n;
printf("input n:");
scanf("%d", &n);
printf("fib(%d)=%ld\n", n, fib(n));
return 0;
}
long fib(int n)
{
long res;
if (n == 0)
res = 0;
else if (n == 1)
res = 1;
else
res = fib(n - 2) + fib(n - 1);
return res;
}
运行后果:
题目 7:递归实现十进制转换二进制:输出一个正整 n,将其转换为二进制后输入。要求定义并调用函数 dectobin(n),它的性能是输入 n 的二进制。试编写相应程序。
答案代码:
#include <stdio.h>
void dectobin(int n);
int main()
{// 习题(10.3.7)
/*
递归实现十进制转换二进制:输出一个正整 n,将其转换为二进制后输入。要求定义并调用函数 dectobin(n),它的性能是输入 n 的二进制。*/
int n;
printf("input n:");
scanf("%d", &n);
dectobin(n);
printf("\n");
return 0;
}
void dectobin(int n)
{if (n == 0)
return;
else
{dectobin(n / 2);
printf("%d", n % 2);
}
}
运行后果:
题目 8:递归实现程序输入整数:输出一个正整数 n,编写递归函数实现对其进行按位程序输入。试编写相应程序。
答案代码:
#include <stdio.h>
void printdigits(int n);
int main()
{// 习题(10.3.8)
/*
递归实现程序输入整数:输出一个正整数 n,编写递归函数实现对其进行按位程序输入。*/
int n;
printf("input n:");
scanf("%d", &n);
printdigits(n);
return 0;
}
void printdigits(int n)
{if (n < 10)
printf("%d\n", n);
else
{printdigits(n / 10);
printf("%d\n", n % 10);
}
}
运行后果:
题目 9:输出 n(n<10)个整数,统计其中素数的个数。要求程序由两个文件组成,一个文件中编写 main 函数,另一个文件中编写素数判断的函数。应用文件蕴含的形式实现。试编写相应程序。
答案代码:
#include <stdio.h>
#include <math.h>
#include "Prime.c"
int main()
{// 习题(10.3.9)
/*
输出 n(n<10)个整数,统计其中素数的个数。要求程序由两个文件组成,一个文件中编写 main 函数,另一个文件中编写素数判断的函数。应用文件蕴含的形式实现。*/
int n;
int count = 0;
printf("input numbers:");
while (1)
{scanf("%d", &n);
if (prime(n))
{count++;}
if (getchar() == '\n')
{break;}
}
printf("其中素数的个数为:%d\n", count);
return 0;
}
prime.c 文件:
int prime(int n)
{
int flag = 1; // 1: 是素数 0: 不是素数
int count = 0;
if (n == 1)
{flag = 0;}
else
{
count = 0;
for (int j = 2; j <= sqrt(n); j++)
{if (n % j == 0)
{
count++;
break;
}
}
if (!count)
{return 1;}
}
return 0;
}
运行后果:
题目 10:三角形面积为:
$$
area=\sqrt{s\times(s-a)\times(s-b)\times(s-c)} \\
s=(a+b+c) / 2
$$
其中 a、b、c 别离是三角形的 3 条边。请别离定义计算 s 和 area 的宏,再应用函数实现。比拟两者在模式上和应用上的区别。
答案代码:
(1) 应用宏实现
#include <stdio.h>
#include <math.h>
#define S(a, b, c) ((a) + (b) + (c)) / 2
#define AREA(s, a, b, c) sqrt((s) * ((s) - (a)) * ((s) - (b)) * ((s) - (c)))
int main()
{// 习题(10.3.10)
/*
三角形面积为:$$
area=\sqrt{s\times(s-a)\times(s-b)\times(s-c)} \\
s=(a+b+c) / 2
$$
其中 a、b、c 别离是三角形的 3 条边。请别离定义计算 s 和 area 的宏,再应用函数实现。比拟两者在模式上和应用上的区别。*/
double a, b, c, s;
printf("input a,b,c:");
scanf("%lf%lf%lf", &a, &b, &c);
s = S(a, b, c);
printf("area = %lf\n", AREA(s, a, b, c));
return 0;
}
运行后果:
(2) 应用函数实现
#include <stdio.h>
#include <math.h>
double p(double a, double b, double c);
double area(double a, double b, double c);
int main()
{// 习题(10.3.10)
/*
三角形面积为:$$
area=\sqrt{s\times(s-a)\times(s-b)\times(s-c)} \\
s=(a+b+c) / 2
$$
其中 a、b、c 别离是三角形的 3 条边。请别离定义计算 s 和 area 的宏,再应用函数实现。比拟两者在模式上和应用上的区别。*/
double a, b, c, s;
printf("input a,b,c:");
scanf("%lf%lf%lf", &a, &b, &c);
printf("area = %lf\n", area(a, b, c));
return 0;
}
double p(double a, double b, double c)
{return (a + b + c) / 2;
}
double area(double a, double b, double c)
{double s = p(a, b, c);
return sqrt(s * (s - a) * (s - b) * (s - c));
}
运行后果:
题目 11:有序表的增删改查操作。首先输出一个无反复元素的、从小到大排列的有序表,并在屏幕上显示以下菜单,用户能够重复对该有序表进行插入、删除、批改和查找操作,也能够抉择完结。当用户输出编号 1~4 和相干参数时,将别离对该有序表进行插入、删除、批改和查找操作,输出其余编号,则完结操作。
[1] Insert
[2] Delete
[3] Modify
[4] Query
[other option] End
答案代码:
/* 有序表的增删改查操作 */
#include <stdio.h>
#define MAXN 10000 /* 定义符号常量示意数组 a 的长度 */
int Count = 0; /* 用全局变量 Count 示意数组 a 中待处理的元素个数 */
void select(int a[], int option, int value); /* 决定对有序数组 a 进行何种操作的管制函数 */
int input_array(int a[]); /* 输出有序数组 a 的函数 */
void print_array(int a[]); /* 输入有序数组 a 的函数 */
int insert(int a[], int value); /* 在有序数组 a 中插入一个值为 value 的元素的函数 */
int del(int a[], int value); /* 删除有序数组 a 中等于 value 的元素的函数 */
int modify(int a[], int value1, int value2); /* 将有序数组 a 中等于 value1 的元素,替换为 value2 */
int query(int a[], int value); /* 用二分法在有序数组 a 中查找元素 value 的函数 */
int main()
{// 习题(10.3.1)
/*
有序表的增删改查操作。首先输出一个无反复元素的、从小到大排列的有序表,并在屏幕上显示以下菜单,用户能够重复对该有序表进行插入、删除、批改和查找操作,也能够抉择完结。当用户输出编号 1~4 和相干参数时,将别离对该有序表进行插入、删除、批改和查找操作,输出其余编号,则完结操作。[1] Insert
[2] Delete
[3] Modify
[4] Query
[other option] End
*/
int option, value, a[MAXN];
if (input_array(a) == -1)
{ /* 调用函数输出有序数组 a */
printf("Error"); /* a 不是有序数组,则输入相应的信息 */
return 0;
}
printf("[1] Insert\n"); /* 以下 4 行显示菜单 */
printf("[2] Delete\n");
printf("[3] Update\n");
printf("[4] Query\n");
printf("[Other option] End\n");
while (1)
{ /* 循环 */
printf("input you select:");
scanf("%d", &option); /* 承受用户输出的编号 */
if (option < 1 || option > 4)
{ /* 如果输出 1、2、3、4 以外的编号,完结循环 */
break;
}
printf("input value:");
scanf("%d", &value); /* 承受用户输出的参数 value */
select(a, option, value); /* 调用管制函数 */
printf("\n");
}
printf("Thanks.\n"); /* 完结操作 */
return 0;
}
/* 管制函数 */
void select(int a[], int option, int value)
{
int index, value2;
switch (option)
{
case 1:
index = insert(a, value); /* 调用插入函数在有序数组 a 中插入元素 value */
if (index == -1)
{ /* 插入数据已存在,则输入相应的信息 */
printf("Error");
}
else
{print_array(a); /* 调用输入函数,输入插入后的有序数组 a */
}
break;
case 2:
index = del(a, value); /* 调用删除函数在有序数组 a 中删除元素 value */
if (index == -1)
{ /* 没找到 value,则输入相应的信息 */
printf("Deletion failed.");
}
else
{print_array(a); /* 调用输入函数,输入删除后的有序数组 a */
}
break;
case 3:
printf("input value2:");
scanf("%d", &value2); /* 承受用户输出的参数 value2 */
index = modify(a, value, value2); /* 调用批改函数在有序数组 a 中批改元素 value 的值为 value2 */
if (index == -1)
{ /* 没找到 value 或者 vaule2 已存在,则输入相应的信息 */
printf("Update failed.");
}
else
{print_array(a); /* 调用输入函数,输入批改后的有序数组 a */
}
break;
case 4:
index = query(a, value); /* 调用查问函数在有序数组 a 中查找元素 value */
if (index == -1)
{ /* 没找到 value,则输入相应的信息 */
printf("Not found.");
}
else
{ /* 找到,则输入对应的下标 */
printf("%d", index);
}
break;
}
}
/* 有序表输出函数 */
int input_array(int a[])
{printf("input n:");
scanf("%d", &Count);
for (int i = 0; i < Count; i++)
{scanf("%d", &a[i]);
if (i > 0 && a[i] <= a[i - 1])
{ /* a 不是有序数组 */
return -1;
}
}
return 0;
}
/* 有序表输入函数 */
void print_array(int a[])
{for (int i = 0; i < Count; i++)
{ /* 输入时相邻数字间用一个空格离开,行末无空格 */
if (i == 0)
{printf("%d", a[i]);
}
else
{printf("%d", a[i]);
}
}
}
int insert(int a[], int value)
{
int i, j, flag = 0;
for (i = 0; i < Count; i++)
{if (a[i] == value)
{
flag = 1;
break;
}
else
{if (value < a[i])
{break;}
}
}
if (flag == 1)
{return -1;}
else
{for (j = Count - 1; j >= i; j--)
{a[j + 1] = a[j];
}
a[i] = value;
Count++;
}
return 0;
}
int del(int a[], int value)
{
int i, j, flag = 0;
for (i = 0; i < Count; i++)
{if (a[i] == value)
{
flag = 1;
break;
}
}
if (flag == 0)
{return -1;}
else
{for (j = i; j < Count - 1; j++)
{a[j] = a[j + 1];
}
Count--;
}
return 0;
}
int modify(int a[], int value1, int value2)
{if (del(a, value1) == -1)
{return -1;}
if (insert(a, value2) == -1)
{return -1;}
return 0;
}
int query(int a[], int value)
{
int left = 0, right = Count - 1, mid, flag = 0;
while (left <= right)
{mid = (left + right) / 2;
if (value == a[mid])
{
flag = 1;
return mid;
}
else if (value < a[mid])
{right = mid - 1;}
else
{left = mid + 1;}
}
if (flag == 0)
{return -1;}
}
运行后果: