C语言刷题-----声明和定义

一、选择题

1.关于递归的描述错误的是:( )

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续
  • 每次递归调用之后越来越接近这个限制条件
  • 递归可以无限递归下去
  • 递归层次太深,会出现栈溢出现象

答案解析:
递归的两个条件:

  1. 将问题转化为其子问题,子问题要与原问题具有相同的解法
  2. 递归的出口
    A:正确,限制条件即递归的出口,如果限制条件满足,递归程序就可以退出了
    B:正确,因为每次递归,都是将原问题进一步缩小,缩小到限制条件时,就可以往回返,直到第一次递归调用

2.关于函数的声明和定义说法正确的是:( )

  • 函数的定义必须放在函数的使用之前
  • 函数必须保证先声明后使用
  • 函数定义在使用之后,也可以不声明
  • 函数定义在使用之后,也可以不声明

答案解析:
A:错误,函数的定义可以放在任意位置,函数的声明必须放在函数的使用之前
B:正确
C:错误,函数定义在使用之后,使用之前没有声明时,编译器编译时识别不了该函数
D:错误,函数的声明只是告诉编译器函数返回值类型、函数名字以及函数所需要的参数,函数定义才是说明函数是怎么实现的

二、编程题

1.递归和非递归分别实现求第n个斐波那契数

要求:
输入:5 输出:5
输入:10, 输出:55
输入:2, 输出:1

迭代方法

#include"stdio.h"
int Fib(n)
{
	int a = 1;
	int b = 1;
	int c = 1;
	while (n >= 3)//1和2的时候不适用
	{
		c = a + b;
		a = b;//把原来的第二个数变成新计算中的第一个数
		b = c;//把算出的结果变为新计算的第二个数
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d", ret);
	return 0;
}


递归方法

#include<stdio.h>
int fib(int m)
{
    int ret = 0;
    if (m<=2)
    {
        ret = 1;//第一二项为1
    }
    else 
    {
        ret = fib(m - 1) + fib(m - 2);//三项及三项以后,后一项等于前两项的和
    }
    return ret;
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    printf("%d",fib(n));
    return 0;
}

2.编写一个函数实现n的k次方,使用递归实现

参考代码

int Pow(int n, int k)
{
	if(k==0)
		return 1;
	else if(k>=1)
	{
		return n*Pow(n, k-1);
	}
}

3. 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19

参考代码

int DigitSum(int n)//1729
{
	if(n>9)
		return DigitSum(n/10)+n%10;
	else
		return n;
}

4.编写一个函数 reverse_string(char * string)(递归实现)

实现:将参数字符串中的字符反向排列,不是逆序打印。
要求:不能使用C函数库中的字符串操作函数。
如:char arr[ ] = “abcdef”;逆序之后数组的内容变成:fedcba

参考代码


/*
思路:
逆置字符串,循环的方式实现非常简单
  1. 给两个指针,left放在字符串左侧,right放在最后一个有效字符位置
  2. 交换两个指针位置上的字符
  3. left指针往后走,right指针往前走,只要两个指针没有相遇,继续2,两个指针相遇后,逆置结束
*/
void reverse_string(char* arr)
{
	char *left = arr;
	char *right = arr+strlen(arr)-1;
 
 
	while(left<right)
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;
 
 
		left++;
		right--;
	}
}

5.递归和非递归分别实现strlen

/*
strlen的含义是:求字符串中有效字符的长度,不包括\0。
*/
 
 
/*
循环实现:
1. 给一个计数,用来统计有效字符的个数
2. 遍历字符串,只要没有遇到\0, 遇到一个字符给计数加1,直到遇到\0
*/
 
 
 int my_strlen(char* str)
 {
 	int count = 0;
 	while('\0' != *str)
 	{
 		count++;
 		str++;
 	}
 	return count;
 }
 
 
 
 
/*
递归实现:
                0  *str == '\0' 
my_strlen(str)
                my_strlen(p+1) + 1  子问题划分
*/
int my_strlen(char *str)
{
	if('\0' == *str)
		return 0;
	else
		return 1+my_strlen(1+str);
}

6.递归和非递归分别实现求n的阶乘(不考虑溢出的问题)

//递归方式
long long Fac(int N)
{
    if(N <= 1)
        return 1;
    
    return Fac(N-1)*N;
}
//循环方式
long long Fac(int N)
{
    long long ret = 1;
    for(int i = 2; i <= N; ++i)
    {
        ret *= i;
    }
    
    return ret;
}

7. 递归方式实现打印一个整数的每一位

void print(unsigned int n)
 {
 	if(n>9)
 		print(n/10);
 	printf("%d ", n%10);
 }

总结

以上就是今天的C语言声明与定义相关的题目整理了,有哪里不正确的欢迎在评论区指正,你的点赞和关注就是对我最大的支持,谢谢

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值