首页 > 其他分享 >函数、递归和递推

函数、递归和递推

时间:2024-10-20 21:10:06浏览次数:8  
标签:函数 递归 int 局部变量 num 全局变量 递推 形式参数

函数

数组可以作为形式参数使用,数组作形式参数的时候真正的形式参数不是数组而是一个可以当作数组使用的变量,数组形式参数里包含的存储区都不是被调用函数提供的,声明数组形式参数的时候可以省略其中包含的存储区个数(写或不写没任何区别)。

数组形式参数需要配合一个整数类型的形式参数用来表示数组形式参数里包含的存储区个数,数组形式参数可以让被调用函数使用其他函数提供的存储区数组形式参数可以实现双向数据传递,这种参数叫输入输出参数

练习:编写函数把调用函数里一个数组的所有存储区内容变成相反数(12345 -> -1-2-3-4-5)

/*
 *
 *函数调用内容相反
 *
 *
 * */
#include<stdio.h>
void neg (int arr[],int size){
	int num = 0;
	for (num = 0;num <= size - 1;num++){
		arr[num] = 0 - arr[num];
	}
}
int main (){
	int arr[] = {1,2,3,4,5};
	int num = 0;
	neg(arr,5);
	for (num = 0;num <= 4;num++){
		printf("%d",arr[num]);
	}
	printf("\n");
	return 0;
}

练习:编写函数得到一张彩票里的所有数字,然后再主函数里显示彩票里的所有数字

/*
 *
 *彩票数字显示(1-36)随机数7个
 *
 * */
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void create (int arr[],int size){
	int num = 0;
	for (num =0 ;num <= size - 1;num++){
		arr[num] = rand() % 36 +1;
	}
}
int main (){
	int arr[7] = {0},num = 0;
	srand(time(0));
	create(arr,7);
	for (num = 0;num <= 6;num++){
		printf("%d ",arr[num]);
	}
	printf("\n");
	return 0;
}

C语言里函数参数的个数可以不固定,这种参数叫做变长参数,变长参数不能在编写函数的时候命名,在被调用函数里需要使用特殊的方法才能获得这些参数的内容。

如果编译器首先遇到函数调用语句就会猜测函数的格式,计算机认为函数有一个整数类型的返回值并且有任意多个不确定类型的形式参数。这个猜测结果叫做函数的隐式声明。函数隐式声明里参数的类型只能是int或double,如果函数的真实格式和隐式声明不一致编译就会报错。

函数大括号前面的部分可以单独作为语句使用,这种语句叫做函数声明语句,函数声明语句里可以省略形式参数名称把函数声明语句写在文件开头叫做函数显式声明,显式声明可以避免隐式声明,除了主函数以外的所有函数都应该进行显式声明。

exit标准函数

exit标准函数可以立刻结束程序的执行,为了使用这个标准函数需要包含stdlib.h头文件,这个函数需要一个整数类型的参数,这个参数的作用和主函数返回值的作用一样。

递归函数

C语言里函数可以调用自己,这种函数叫递归函数,如果一个问题可以分解成几个小问题,至少其中一个小问题和原来的问题本质上一样(只是稍微简单一点)这种问题就适合采用递归函数解决。

递归函数的编写步骤:

1.编写语句解决分解后的每个小问题(假设递归函数已经编写完成可以直接使用的)

2.在递归函数开头编写分支处理不可分解的情况(这个分支必须保证函数可以结束)

练习:编写递归函数计算从1到某个给定正整数之间所有整数的和并把结果传递给调用函数

用递归函数解决问题的思路叫递归,用循环解决同样问题的思路叫递推。检验递归函数的时候首先用最简单的参数检测,然后逐渐把参数变得复杂继续测试。

练习:编写递归函数计算两个非负数的最大公约数

/*
 *
 *递归求最大公约数
 *
 * */
#include<stdio.h>
int common (int min,int max){
	if (!(max % min)){
		return min;
	}
	return common(max % min,min);
}
int main (){
	int min = 0,max = 0;
	printf("请输入两个数字");
	scanf("%d%d",&min,&max);
	printf("最大公约数是%d\n",common(min,max));
	return 0;
}

练习:

1 1 2 3 5 8 13 21……
0 1 2 3 4 5  6  7……

编写递归函数根据编号计算对应的数字

#if 0
/*
 *
 *斐波拉契数列
 *
 * */
#include<stdio.h>
int fei (int num){
	int arr[50] = {0};
	if (num <= 1){
		return 1;
	}
	if (!arr[num - 2]){
		arr[num - 2] = fei(num - 2); 
	}
	if(!arr[num - 1]){
		arr[num - 1] = fei(num - 1);
	}
	return (arr[num - 2] + arr[num - 1]);
}
int main (){
	int num = 0;
	printf("请输入一个编号:");
	scanf("%d",&num);
	printf("%d\n",fei(num));
	return 0;
}

#elif 0
/*
 *
 *费波拉契数列
 *
 * */
#include<stdio.h>
int fei (int num){
	if (num <= 1){
		return 1;
	}
	return (fei(num - 2) + fei(num - 1));
}
int main (){
	int num = 0;
	printf("请输入一个数字");
	scanf("%d",&num);
	printf("结果是:%d\n",fei(num));
	return 0;
}
#endif

局部与全局变量

能够使用了某个变量的所有语句叫做这个变量的作用域,声明在函数里面的变量叫做局部变量,他的作用域包含在函数里面的所有语句,声明在所有函数外面的变量叫做全局变量,他的作用域包含程序里面的所有语句。

没有初始化的全局变量自动被初始化成0,全局变量和局部变量可以重名;这个变量名优先代表局部变量,如果全局变量和局部变量都能解决问题就优先考虑使用局部变量。

存储区的使用不受作用域的限制(可以跨函数使用存储区),存储区的使用受生命周期的限制,生命周期是一段时间,在生命周期开始的时候计算机给程序分配存储区,在生命周期结束的时候计算机把分配给程序的存储区收回。

全局变量的生命周期是整个程序的执行时间,局部变量的生命周期是函数某一次执行的时间范围。当函数开始的时候计算机为局部变量分配存储空间,在函数结束的时候计算机把局部变量的存储区收回。如果函数多次执行则每次执行的时候局部变量对应的存储区都可能不同。

静态变量

静态变量的生命周期和作用域跟普通变量不一样,声明静态变量的时候应该使用 static关键字

static int num;

不论全局变量还是局部变量都可以声明成静态的,静态局部变量的生命周期是整个程序的执行时间,没有初始化的静态变量会自动初始化成0;静态局部变量的存储区随时可以使用,静态局部变量的作用域和普通局部变量的作用域一样,静态局部变量的初始化只在程序开始的时候执行一次,不管初始化语句写在哪里。

静态全局变量的生命周期还是整个程序的执行时间,但他的作用域只包含声明他的那个文件里的所有语句(不可以跨文件使用静态全局变量)。

生命周期作用域

变量的作用域分为三种:局部变量、静态全局变量、全局变量。

变量的生命周期分为两种:普通局部变量、其他变量

标签:函数,递归,int,局部变量,num,全局变量,递推,形式参数
From: https://www.cnblogs.com/GQH1000/p/18487911

相关文章

  • 重载运算符、析构函数
    重载运算符、析构函数1.重载运算符2个对象进行==比较,重载==运算符说白了,就是,写一个成员函数,这个成员函数名"operator==",这个成员函数体里边写一些比较逻辑//定义Time&operator=(constTime&tmpobj)//实现Time&Time::operator=(constTime&tmpobj){cout......
  • 字符函数和字符串函数
    字符函数:字符函数的头文件是ctype.hislower是用来判断参数部分的c是否为小写字母intislower(intc);通过函数值来说明是否是小写字母,如果是小写字母就返回非零的整数,如果不是小写字母,则返回0;练习:写一个代码,判断这个字符串是否有小写字母,如果有将小写字母,转变成大写字母......
  • DES加密,哪位大神能看看我的key_round函数为啥生成的子密钥不对啊/(ㄒoㄒ)/~~球球了
    #include<stdio.h>voidIPchange(intpt[],intIP[]){  for(inti=0;i<64;++i)  {    pt[i]=pt[IP[i]-1];  }}voidIP_1change(intct[],intIP_1[]){  for(inti=0;i<64;i++)  {    ct[i]=ct[IP_1[i]......
  • 关于递归问题的复杂度计算
    背景:前段时间在背八股,手撕快速排序,算法时间复杂度为\(O(nlogn)\),没想太多,记个结论就pass,和当初上算法课的时候一样;然后做小红书笔试题的时候,有一道题是这样:voidfunc(n){if(n==1){printf("good\n");}func(n-1);func(n-1);}    也是问时间复......
  • Day20--递归
    Day20--递归A方法调用B方法容易理解,递归就是A方法调用A方法,即自己调用自己。利用递归可以用简单程序解决复杂问题,通常把大型复杂问题层层转化为与原问题相似的规模较小问题求解,递归策略用少量程序描述解题过程所需多次重复计算,大大减少程序代码量。递归的能力在于用有限......
  • 基于最速下降法和坐标轮换法求解二元函数的极小点和极小值(附word文档)
    基于最速下降法和坐标轮换法求解二元函数的极小点和极小值(附word文档)......
  • C语言库函数round函数
    简单使用:把浮点数四舍五入到整数round函数定义在<math.h>头文件中,其原型为doubleround(doublex);round函数用于将浮点数四舍五入到最接近的整数以下的C语言代码用round函数计算了不同浮点数的四舍五入值,并将结果打印出来#include<stdio.h>#include<math.h>intmai......
  • 65.C指针---sizeof()函数和strlen()函数常见考
    #include<stdio.h>#include<string.h>intmain(){inta[]={1,2,3,4};printf("%d\n",sizeof(a));printf("%d\n",sizeof(a+0));printf("%d\n",sizeof(*a));printf("%d\n",s......
  • 奇数偶数分开并排序(冒泡函数)
    voidbubbleSort(intarr[],intn){inti,j;for(i=0;i<n-1;i++){for(j=0;j<n-i-1;j++){if(arr[j]>arr[j+1]){//交换arr[j]和arr[j+1]inttemp=arr[j];arr[j]=arr[j+1];arr[j+1]=temp;}}}}intmain(){int......
  • 209号资源-源程序:(SIC)黑翼风筝算法:一种受自然启发的元启发式算法,用于解决基准函数和工
    ......