函数
数组可以作为形式参数使用,数组作形式参数的时候真正的形式参数不是数组而是一个可以当作数组使用的变量,数组形式参数里包含的存储区都不是被调用函数提供的,声明数组形式参数的时候可以省略其中包含的存储区个数(写或不写没任何区别)。
数组形式参数需要配合一个整数类型的形式参数用来表示数组形式参数里包含的存储区个数,数组形式参数可以让被调用函数使用其他函数提供的存储区,数组形式参数可以实现双向数据传递,这种参数叫输入输出参数。
练习:编写函数把调用函数里一个数组的所有存储区内容变成相反数(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