初见函数
调用自己写的函数。
代码赋值是程序质量不良的表现。
eg1:
//自己定义函数
int isPrime(int i)
{
int ret=1;
int k;
for(k=2;k<i<1;k++){
if(i%k==0){
ret=0;
break;
}
}
return ret;//从函数中返回,返回int的结果。
}
int main()
{
int m,n;
int sum=0;
int cnt=0;
int i;
scanf("%d %d",&m,&n);
if(m==1)m=2;
for(i=m;i<=n;i++){
//调用函数
if(isPrime(i)){
sum+=i;
cnt++;
}
}
printf("%d %d\n",cnt,sum);
return 0;
}
eg2:
把重复的代码抽出来写成函数:
/*函数头,sum是函数名,void叫返回类型,void不返回任何东西,int begin,int end叫参数表,第一个参数是int,第二个参数也是int。即使没有参数,也要有圆括号,不用圆括号,程序不会认为在调用函数。有参数需要给出正确的数量和顺序。*/
void sum(int begin,int end)
{
//大括号内的是函数体
int i;
int sum=0;
for(i=begin;i<=end;i++){
sum+=i;
}
printf("%d到%d的和是%d\n",begin,end,sum);
}
int main()
{
sum(1,10);
sum(20,30);
sum(35,45);
return 0;
}
函数是一块代码,接收零个或多个参数,做一件事情,并返回零个或一个值。
从函数中返回
return作用
- 函数一旦遇到return就停止了,不再运行了;
- 如果return后面有值,我们要送回去一个值;
所以可以写:
return;
或者写:
return 表达式; - 一个函数可以出现多个return语句;
eg:
int max(int a,int b)
{
//int ret;
if(a>b){
return a;
}else{
return b;
}
//return ret;
}
但是这样不满足单一出口原则,所以不好。
将来做修改需要修改很多地方。
4. 返回的值可以赋给变量,可以再传递给函数,甚至可以丢弃。
eg:
int main()
{
int a,b,c;
a=5;b=6;
c=max(10,12);
c=(a,b);
c=max(c,23);
max(23,45);/*可能不需要它的结果,需要的是它的副作用,所以不一定要返回一个值。*/
printf("%d\n",max(a,b));
}
- 没有返回值的函数
void函数名(参数表),不能使用带值的return,可以没有return,调用的时候不能做返回值的赋值;如果函数有返回值,就必须使用带值的return。
eg:
int max(int a,int b)
{
int ret;
if(a>b){
ret=a;
}else{
ret=b;
}
return ret;
}
返回的ret值会被带回来,作为这个函数运行的结果,参与之后计算。
函数先后关系
把函数写在上面是因为C的编译器自上而下分析代码。
但是如果都把函数放在main之上,看代码的人会一下子看不到程序到底要做什么也就是看不到main,所以希望把函数摆在下面。
可以把函数头摆在main之前,函数体摆在下面,这样叫做原型声明:
void sum(int begin,int end);//声明
int main()
{
sum(1,10);
sum(20,30);
sum(35,45);
return 0;
}
void sum(int begin,int end)//定义
{
int i;
int sum=0;
for(i=begin;i<=end;i++){
sum+=i;
}
printf("%d到%d的和是%d\n",begin,end,sum);
}
定义和声明必须一致。
函数原型
函数头,以分号”;”结尾,就构成了函数原型,而函数头后面没有分号;
函数原型的目的是告诉编译器这个函数长什么样,包括:
名称;
参数(数量及类型);
返回类型。
void sum(int ,int )/*函数原型中不写参数的名字也是可以的。或者名字和之后的不一致比如写成a,b也是可以的。
调用函数
如果函数有参数,调用函数时必须传递给它数量、类型正确的值
可以传递给函数的值是表达式的结果,这包括:
字面量:c=max(10,12);
变量:c=max(a,b);
函数的返回值:c=max(max(23,45),a);
计算的结果:c=max(23+45,b);
类型不匹配:
调用函数时给的值与参数的类型不匹配是C语言传统上最大的漏洞;
编译器总是悄悄替你把类型转换好,但是这很可能不是你所期望的;
后续的语言,C++/Java在这方面很严格。
void swap(int a,int b);
int main()
{
int a=5;
int b=6;
swap(a,b);
printf("a=%d b=%d\n",a,b);
return 0;
}
void swap(int a,int b)
{
int t=a;
a=b;
b=t;
}
C语言在调用函数的时候,永远只能传值给函数。
这个代码不能交换a,b的值,因为定义的a,b给函数的a,b传了值,函数返回的a,b
本地变量
变量的生存期和作用域
本地变量的规则
函数的细节
没有参数时
不建议空着,建议写全,确定是没有参数的就吧void写进去。
逗号运算符
在函数里面的逗号,不是运算符,是标点符号,所以传了两个参数值。
如果加一层括号,则逗号就是运算符,运算了之后只传了b。
函数里的函数?
C语言不允许嵌套函数。
可以在一个函数里放另一个函数的声明,但不能放函数体。
main
main里面放void也是对的。
如果return返回任何非零的数则程序有错误,返回零是程序停止了。
所以是有人看的,可以起作用的。