C语言--递归函数、指针函数、函数指针

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;

b++;

c++;

    return (a+b+c);

}

A. 777                  B. 7 10 13                C. 7 9 11          D. 7 8 9

分析:主函数通过for循环调用f函数,当i=0时,a=2,调用f函数,b=0,c=3,b++、c++都为单独语句,分别加一,此时b=1,c=4,返回值为a+b+c=2+1+4=7;当i=1时,再次调用f函数,此时因为b是局部变量,每次调用函数时都会对其重新赋值,所以b=0,而c是静态局部变量,只在函数第一次调用时赋值,因此此时c为上次循环结束时数值4,a仍为传入数值2,所以b++为1,c++为5,a+b+c=2+1+5=8;当i=2时,同样执行上述操作,此时b=0,c=5,a=2,b++为1,c++为6,a+b+c=2+1+6=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

分析:值传递时,形参的改变不会影响实参;因为题中count时值传递,但最后输出语句在主函数,所以实参的数值并没有改变,仍为3;

4.请问运行Test函数会有什么样的结果?

char *GetMemory(void)

{

    char p[] = "hello world";

    return p;

}

void Test(void)

{

    char *str = NULL;

    str = GetMemory();

    printf(str);

}

答:空值;

分析:test函数定义了一个指针,使其指向空,没有被赋予有效的内存地址,空指针不指向任何有效的数据或对象,就成了野指针,调用函数后字符写入局部变量指向的地址,函数结束后就释放了,任何试图通过空指针访问内存的操作都可能导致程序崩溃或未定义行为,所以输出为空;

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;

}

 答:运行结果是段错误;过程:定义一个指针指向空,调用getalloc函数,参数是该指针,函数为p指针开辟新内存,将hello world复制给p;然后回到主函数输出字符串,释放指针;但是注意正是由于新开辟内存,使得p地址和主函数指针不在一个地址,str指针事实上仍是一个野指针,所以输出结果是段错误;

6.下列程序的输出结果是__10______。

fun(int a, int b, int c)

{

    c = a*b;

}

void main()

{

    int c = 10;

    fun(2,3,++c);

    printf("%d\n", c);

分析:函数参数传递方式是值传递,形参改变不影响实参,所以c为主函数初始值10;

7.找错题,说明那里错了

void test1()

{

    char string[10];

    char *str1 = "0123456789";

    strcpy( string, str1 );

}

答:数组长度为10,字符串长度还要包括'\0'所以是11,在进行复制操作时溢出了;

8.下面的代码片段会输出__________

void test(void)

{

    char *p = NULL;

    strcpy(p, "hello");

    printf("%s", p);

}

分析:原因同第五题,空指针不指向任何有效的数据或对象,因此在使用空指针进行操作时需要特别小心,因为任何试图通过空指针访问内存的操作都可能导致程序崩溃或未定义行为

9.sizeof(str); 的值是多少? 

void Func(char str[100])

{

sizeof(str);

}

答:参数传递时会将数组名认为成指针,所以sizeof(str)为指针长度8;

10.递归函数最终会结束,那么这个函数一定(B );

A. 使用了局部变量

B. 有一个分支不调用自身

C. 使用了全局变量或者使用了一个或多个参数

分析:递归函数就是在函数内部调用自身,局部变量只会在每次递归开始被重新赋值,并不能使递归函数结束,c也许会使函数结束,但不是一定,只有函数分支不再调用自身才行;

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),首先将参数3和4传递到f函数中,返回值是(y-x)*x==>(4-3)*3=3;然后将参数3和5传递到函数中,返回值是(5+3)*3=6;此时外层为f(3,6),然后再次将参数3和6传递到函数中,返回值最终为(6-3)*3=9;

12.请判断下面程序输出的值是多少? 

int func(int a)

{

    static int b = 0;

    b+=a;

    return b;

}

int main(void)

{

    printf("%d %d\n", func(1)+func(3), func(5));

}

答:5 9;

分析:1.func(1)+func(3);当参数为1时,b=0,b+=a ==>b=b+a b=0+1=1,因此func(1)为1;当参数是3时,因为b是静态局部变量,只在函数第一次调用时赋初值,所以此时b=1,a=3,b+=a==>b=1+3=4;所以func(3)为4,那么func(1)+func(3)=1+4=5;

2.func(5);当参数为5时,a=5,此时b为func(3)结束时的值4,b+=a==>b=a+b=5+4=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

分析:p是一个函数指针数组,存放两个指向函数的指针,p[0]存放指向f1函数的指针,p[1]存放指向f2函数的指针,a=3,b=5,p[0](&a,b)是调用f1函数,并将a的地址和b的值传递给函数,由于a是地址传递,经过f1函数也就是交换函数后实参发生改变,b为值传递,实参未改变,因此第一个输出为5 5;f2函数与f1函数参数传递方式相同,因此最终输出结果为 5 5 5 5

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

分析:当x=7时,p=7-fun(7-2),继续拆解,p=7-(5-fun(5-2))==》p=7-(5-(3-fun(1)))==》p=7-5+3-3=2;

15.有以下函数,该函数的返回值是:( B) 

char *fun(char *p)

{

    return p;

}

A. 无确切的值                                    B. 形参 p 中存放的地址值

C. 一个临时存储单元的地址          D. 形参 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>
#include <string.h>
#include <stdlib.h>
//定义一个函数,参数是两个char型指针,返回值也是char型指针
char *my_strcpy(char *strDest,char *strSrc){
    //定义局部变量指针指向第一个字符串首地址
	char *p=strDest;
    //当第二个字符串不为\0
	while(*strSrc){
       //将第二个字符串复制给第一个
	  *strDest=*strSrc;
	  strDest++;
	  strSrc++;
	}
	*strSrc='\0';
	return p;
}
int main(int argc, const char *argv[])
{
	char a[100]="the8";
	char b[]="xuminghao";
    //调用函数
	printf("%s\n",my_strcpy(a,b));
	return 0;
}

运行结果如图所示:

17.请实现一个函数,输入一个整数,输出该数二进制表示中的1的个数。例如:把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int fun(int n){
	static int count=0;
	if(n%2==1){
		count++;
	}
	if(n==1||n==0){
		return count;
	}else{
		return fun(n/2);
	}
}
int main(int argc, const char *argv[])
{
	int n;
	printf("请输入一个整数:");
	scanf("%d",&n);
	printf("该二进制有%d个1\n",fun(n));
	return 0;
}

运行结果如图所示:

18.请用编写递归算法计算fibinacci数列第1000位的值。斐波拉契数列为1,1,2,3,5,8,13,21,……

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int fbnq(int n);
int main(int argc, const char *argv[])
{
	for(int i=1;i<=20;i++){
		printf("%6d",fbnq(i));
		if(i%5==0)
			printf("\n");
	}
	return 0;
}
int fbnq(int n){
	if(n==1||n==2)
		return 1;
	else
		return fbnq(n-1)+fbnq(n-2);

}

运行结果如图所示:

19.用 C 语言写一个递归算法求 N!

代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int fun(int n){
    //确定递归结束的条件
	if(n==0)
		return 1;
    //返回n*(n-1)
	return n*fun(n-1);
}
int main(int argc, const char *argv[])
{
	int n;
	printf("请输入阶乘值为:");
	scanf("%d",&n);
	printf("%d的阶乘是%d\n",n,fun(n));
	return 0;
}

运行结果如图所示:

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛应用于系统编程和嵌入式开发的高级编程语言函数指针C语言中的一个重要概念,它可以指向函数,并且可以通过函数指针来调用函数。快速排序算法是一种常用的排序算法,它的核心思想是通过分治的策略将一个大问题分解为多个小问题,并通过递归的方式解决这些小问题。 下面是C语言中使用函数指针实现快速排序算法的示例代码: ```c #include <stdio.h> // 交换两个元素的值 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 快速排序的分区函数 int partition(int arr[], int low, int high) { int pivot = arr[high]; // 选取最后一个元素作为基准 int i = (low - 1); // 定义一个指针,用于指向小于基准的元素 for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } // 快速排序函数 void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); // 将数组分区,并获取分区点的位置 quickSort(arr, low, pi - 1); // 对分区点左边的子数组进行快速排序 quickSort(arr, pi + 1, high); // 对分区点右边的子数组进行快速排序 } } // 打印数组元素 void printArray(int arr[], int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = {10, 7, 8, 9, 1, 5}; int n = sizeof(arr) / sizeof(arr[0]); printf("原始数组:"); printArray(arr, n); quickSort(arr, 0, n - 1); printf("排序后的数组:"); printArray(arr, n); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值