1、以下程序的正确运行结果是( D )。
int f(int a);
int main(void)
{
int a = 2,i;
for(i = 0; i < 3; i++)
printf("%4d", f(a));
}
int f(int a)
{
int b = 0;
static int c = 3; //静态局部变量 c=3
b++;
c++;
return (a+b+c);
}
A. 7 7 7 B. 7 10 13 C. 7 9 11 D. 7 8 9
解析:static int c =3表示静态局部变量 c=3,当i=1,a=2,b=1,c=4,返回a+b+c=7;当i=2,a=2,b=2,c=4,返回a+b+c=8;当i=3,a=2,b=3,c=4,返回a+b+c=9;i=3跳出循环,输出7,8,9
2、在一个被调用函数中,关于return语句使用的描述,( D )是错误的
A. 被调用函数中可以不用return语句
B. 被调用函数中可以使用多个return语句
C. 被调用函数中,如果有返回值,就一定要有return语句
D. 被调用函数中,一个return语句可以返回多个值给调用函数
解析:一个return语句返回一个确定值
3、以下程序的运行结果为( C )
#include <stdio.h>
#include <string.h>
int SubCount(char *dest, int count)
{
strcpy(dest, "555");
count++;
return 0;
}
int main()
{
int count = 3;
char caBuf[8];
SubCount(caBuf, count);
printf("%d\n", count);
return 0;
}
A. 8 B. 4 C. 3 D. 5
解析:由于C语言中的参数传递是按值传递的,所以 SubCount
函数接收到的 count
实际上是 main
函数中 count
变量的一个副本。因此,在 SubCount
函数中对 count
的任何修改都不会影响 main
函数中的 count
变量。
4、请问运行Test函数会有什么样的结果?
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
系统会报错
解析:Test
函数中,您尝试打印从 GetMemory
返回的字符串。但是,由于前面提到的原因,这个指针可能不再指向有效的内存区域,因此调用 printf(str);
是非常危险的,可能导致程序崩溃或打印出垃圾值。
5、分析以下程序,写出运行结果并写出过程
#include <stdio.h>
#include <stdlib.h>
void getalloc(char *p)
{
p = (char *)malloc(100);
strcpy(p, "hello world");
}
int main()
{
char *str = NULL;
getalloc(str);
printf("%s\n",str);
free(str);
return 0;
}
6、下列程序的输出结果是____11____。
fun(int a, int b, int c)
{
c = a*b;
}
void main()
{
int c = 10;
fun(2,3,++c);
printf("%d\n", c);
}
解析:当你调用fun(2,3,++c);
时,++c
首先被求值,因此c
的值从10增加到11。但是,由于函数参数是通过值传递的,fun
函数接收到的c
是11的一个副本,而不是原始变量c
本身。
7、找错题,说明那里错了
void test1()
{
char string[10];
char *str1 = "0123456789";
strcpy( string, str1 );
}
解析:string[10];没有足够的空间来存储0123456789,还有一个字符'\0',应该增加一个字符的空间以存储终止的空字符,改为char string[11];
8、下面的代码片段会输出______段错误____
void test(void)
{
char *p = NULL;
strcpy(p, "hello");
printf("%s", p);
}
和第四题类似
9、sizeof(str); 的值是多少?
void Func(char str[100])
{
sizeof(str);
}
100
10、递归函数最终会结束,那么这个函数一定( B );
A. 使用了局部变量
B. 有一个分支不调用自身
C. 使用了全局变量或者使用了一个或多个参数
解析:递归函数最终会结束,这个特性意味着在递归的过程中,必须有一个明确的退出条件或终止点,以防止无限递归导致的栈溢出或程序崩溃。
A. 虽然局部变量在递归函数中非常常见,用于存储中间结果或临时数据,但它并不是递归函数能够结束的必要条件。递归函数完全可以使用全局变量,只要它有适当的退出条件。
B. 这个选项是递归函数能够结束的关键。在递归过程中,必须有一个或多个分支不调用递归函数本身,这样递归调用才能逐步减少,直到达到退出条件。这是递归函数设计的核心,也是递归能够正常结束的必要条件。
C. 这个选项虽然描述了递归函数中常见的做法(使用参数传递数据,有时也使用全局变量),但它并不是递归函数能够结束的直接原因。递归函数可以使用全局变量,也可以使用参数,但这并不直接决定递归是否会结束。关键在于递归函数内部是否有合适的退出条件。
因此,正确答案是B。
11、程序如下,程序执行后的输出结果是:
int f(int x, int y)
{
return (y-x)*x;
}
void main()
{
int a = 3,b=4,c=5,d;
d=f(f(3,4),f(3,5));
printf("%d\n", d);
}
9
解析:d=f(f(3,4),f(3,5));表示b=f(f((4-3)*3),f(5-3)*3)=f(3,6)=(6-3)*3=9
12、请判断下面程序输出的值是多少?
int func(int a)
{
static int b = 0;
b+=a; //b=b+a;
return b;
}
int main(void)
{
printf("%d %d\n", func(1)+func(3), func(5));
}
5 9
解析:求func(1):静态变量第一次被调用0,加上参数1,返回b=1,并返回1
func(3):b=1,加上参数3,返回b=4,并返回4
func(1)+func(3)=1+4=5
求func(5):态变量b的值仍然是上一次调用后留下的 4,加上参数5,返回b=9,并返回9
13、这段程序的输出是(____A____)
void f1(int *, int);
void f2(int *, int);
void(*p[2]) (int *, int);
main()
{
int a;
int b;
p[0] = f1;
p[1] = f2;
a=3;
b=5;
p[0](&a, b);
printf("%d\t %d\t", a, b);
p[1](&a, b);
printf("%d\t %d\t", a, b);
}
void f1(int * p, int q)
{
int tmp;
tmp = *p;
*p = q;
q = tmp;
}
void f2(int *p, int q)
{
int tmp;
tmp = *p;
*p = q;
q = tmp;
}
A. 5 5 5 5 B. 3 5 3 5 C. 5 3 5 3 D. 3 3 3 3
14、有以下程序段, x=7执行后的值为 ( B )
int fun(int x) {
int p;
if(x==0||x==1)
return(3);
p=x-fun(x-2);
return p;
}
A. 0 B. 2 C. 5 D. 6
解析:递归函数fun的返回值, x=7,p=7-fun(5),需要求fun(5),没有满足条件;因此执行递归调用
当x=5,p=5-fun(3),,需要求fun(3),没有满足条件,因此执行递归调用;
x=3,p=3-fun(1),满足条件(x==0||x==1)返回值3,
回到fun(3),p=3-3=0;回到fun(5),p=5-fun(3)=5;回到fun(7),p=7-fun(5)=7-5=2;
15、有以下函数,该函数的返回值是:( B )
char *fun(char *p)
{
return p;
}
A. 无确切的值 B. 形参 p 中存放的地址值
C. 一个临时存储单元的地址 D. 形参 p 自身的地址值
解析:函数 char *fun(char *p)
接收一个指向字符的指针 p
作为参数,并且直接返回这个指针。在 C 语言中,函数参数是通过值传递的,但这里的参数 p
本身就是一个指针,因此传递的是地址
16、编写strcpy函数
已知strcpy 函数的原型是
char *strcpy(char *strDest,const char *strSrc);其中 strDest 是目的字符串,strSrc 是源字符串。
(1)、不调用 C 的字符串库函数,请编写函数 strcpy。
(2)、strcpy 能把 strSr 的内容复制到 strDest,为什么还有 char"类型的返回值?
(3)、strcpy 和 memcpy 的区别。
#include <stdio.h>
// 修改返回类型为 void,因为字符串复制通常不需要返回值
void my_cpy(char *strdest, const char *strsrc) {
// 使用 const 修饰 strsrc,表示这个参数不应该被修改
while (*strsrc != '\0') {
*strdest = *strsrc; // 复制字符
strdest++; // 移动目标指针
strsrc++; // 移动源指针
}
*strdest = '\0'; // 在目标字符串的末尾添加字符串结束符
}
int main() {
char src[] = "Hello, World!";
char dest[50]; // 确保目标数组足够大以存储源字符串
my_cpy(dest, src); // 调用修正后的字符串复制函数
printf("Copied string: %s\n", dest);
return 0;
}
(2)strcpy
函数返回目标字符串的起始地址(即传入的 strDest
参数的地址),这是为了方便链式调用和在某些情况下获取目标字符串的地址。虽然直接操作目标字符串通常不需要返回这个地址,但在某些特定的编程模式下,这个返回值非常有用。
(3)操作对象:strcpy
专门用于处理字符串,它会复制字符串直到遇到 '\0' 字符,并确保目标字符串也以 '\0' 结尾。而 memcpy
是通用的内存复制函数,它不处理字符串的终止符,而是简单地复制指定数量的字节。
安全性:由于 strcpy
不检查目标缓冲区的大小,它很容易导致缓冲区溢出。相比之下,memcpy
的安全性更高(或更低,取决于你如何使用它),因为它只复制指定数量的字节,不会修改额外的内存。然而,使用 memcpy
时,你需要确保不会复制超出目标缓冲区大小的数据。
用途:strcpy
用于复制字符串,而 memcpy
可以用于复制任何类型的内存块,包括非字符串数据。
性能:对于复制大量非字符串数据时,memcpy
通常比 strcpy
更高效,因为它不需要逐字符检查终止符。但在复制字符串时,strcpy
可能更优,因为它确保字符串以 '\0' 结尾。然而,在现代编译器和硬件上,这种差异通常非常小。
17、请实现一个函数,输入一个整数,输出该数二进制表示中的1的个数。例如:把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。
#include <stdio.h>
// 函数用于计算整数n的二进制表示中1的个数
int fun(int n)
{
int count = 0;
while (n > 0)
{
// 检查n的最低位是否为1
if (n % 2 == 1)
{
count++; // 如果是,则计数器加1
}
// 将n右移一位(等价于n除以2并取整)
n = n >> 1; // 或者使用 n /= 2; 但位操作通常更快
}
return count;
}
int main()
{
unsigned int n;
printf("请输入一个整数:");
scanf("%u", &n); // 使用%u来读取无符号整数
int ones = fun(n); // 调用函数并接收返回的1的个数
printf("整数%u的二进制表示中1的个数为:%d\n", n, ones);
return 0;
}
18、请用编写递归算法计算fibinacci数列第1000位的值。斐波拉契数列为1,1,2,3,5,8,13,21,……
#include <stdio.h>
// 递归函数计算斐波那契数列的第n项
long long fibonacci(int n) {
if (n <= 1) {
return n;
} else {
return fibonacci(n-1) + fibonacci(n-2);
}
}
int main() {
int n = 1000;
long long result = fibonacci(n);
printf("Fibonacci sequence at position %d is %lld\n", n, result);
return 0;
}
// 注意:上述代码在实际环境中可能因为栈溢出或运行时间过长而无法正常执行。
果然不出意外,无法正常执行。
19、用 C 语言写一个递归算法求 N!
#include <stdio.h>
// 函数声明
long long factorial(int n);
int main() {
int N;
printf("请输入一个整数 N 来计算 N!:");
scanf("%d", &N);
if (N < 0) {
printf("阶乘仅适用于非负整数。\n");
} else {
printf("%d! = %lld\n", N, factorial(N));
}
return 0;
}
// 递归函数定义
long long factorial(int n) {
// 递归终止条件
if (n == 0) {
return 1;
} else {
// 递归调用
return n * factorial(n - 1);
}
}