C语言函数
1.1 什么是函数?
函数是一块代码, 接受零个或多个参数,做一件事情,并返回零个或一个值。
1.2 函数定义
1.3 函数调用
- 函数名()
- ()起到了调用函数的重要作用, 即使没有参数也需要加()
- 如果有参数, 需要给出正确的数量和顺序,这些值会被按照顺序初始化函数中的参数。
- 可以传递给函数的值是表达式的结果,包括数据、变量、函数的返回值、计算结果等
比如:
c = max(1,2);
c = max(a,b);
c = max(max(1,2),2);
c = max(2+3, 2);
- 传入参数的值与设定参数类型不匹配会怎么样? 这是C的一个漏洞, 编译器会做转化,但这个可能并不是设计者原本需要的转化, 后续的语言C++ , Java在这方面很严格, 必须一致。
- C语言在调用的时候,永远只能传值给函数,而不是传变量进去
1.3 函数返回
return 语句停止函数的执行, 并返回一个值, 可有两种用法
- return
- return expression
一个函数里可以出现多个return 语句, 但最好使用单一出口, 多个出口修改起来较麻烦。 - return(i),就是return i 。 但不要写成第一种,给人的误解return是一个函数
1.4 函数定义、调用顺序
c99之后在使用函数之前没有定义函数会出现错误。但是为了突出代码的重点, 也可以将函数的定义放在后面,但需要先声明函数。也就是先定义或者先声明都可以。如下:
在定义之后调用函数
int max(int a, int b){ //定义
if (a>b){
return a;
}else return b;
}
void main(){
int a=2,b=1 ;
int c ;
c = max(a,b); // 调用
printf("%d", c);
}
在声明之后调用函数, 最后定义, 这样代码突出重点,逻辑更顺畅。
int max(int a, int b); // 声明
void main(){
int a=2,b=1 ;
int c ;
c = max(a,b); // 调用
printf("%d", c);
}
int max(int a, int b){ // 定义
if (a>b){
return a;
}else return b;
}
函数头加冒号就是函数原型 ,即函数声明。
函数原型的目的是告诉编译器函数的名称、参数、返回类型。
旧的标准和习惯将函数的声明写在调用它的函数里,现在一把写在调用的函数前面。
声明里可以不写参数的名字, 但最好写上,有助于代码阅读。
1.3 函数传值
每个函数有自己的变量空间, 参数也位于这个独立的空间中, 和其他函数没有关系。 过去,对于函数参数表中的参数, 调用函数时给的值,叫做“实际参数”。 这容易让人误会实际参数就是在实际在函数中进行计算的参数,误会调用的时候把变量传进去了 。 实际上, 他们只是参数与某个函数空间中值的关系。
比如,下面交换a , b值的函数, 调用之后,并没有改变a,b 的值 , 因为只把a , b的值传入函数,而不是传入变量。
void swap(int a, int b){
int t;
t=a;
a=b;
b=t;
}
int main(){
int a = 1;
int b= 2;
swap(a,b);
printf("a=%d ; b=%d",a,b);
return 0;
}
1.4 局部变量
每个函数的每次运行, 都产生了一个独立的变量空间, 在这个空间中的变量, 是函数的这次运行所独有的,称作局部变量。 参数和函数内部定义的变量都是局部变量 。
- 生存期: 变量出现与消失的时间
- 作用域: 在代码的什么范围内可以访问这个变量。 (生存不一定能访问,在另一个没有执行完成函数里,当前函数不能访问)
对于局部变量, 这两个问题的答案都是 大括号内。 - 本地变量是定义在块内的,也就是大括号内, 可以是函数体,也可以是语句块内,比如if ,甚至可以直接用大括号定义变量; 块就是一个独立的空间, 程序在进入之前, 块内变量不存在, 离开之后,块内变量消失。
- 在块外面定义的变量,在块内仍然有效。 (在子空间内有效,函数A在函数B中定义,那么函数A的相当于B的全局空间,但C语言不建议嵌套定义。)
- 在块内定义了与块内同名的变量,二者不相干 。
- 局部变量不会默认初始化,但参数在进入函数时会被初始化。
1.5 备注
- int func(void) 与 int func( ) 不同, 前者确定没有参数,后者不确定,写的时候最好写清楚参数。
- int main(){ } 是一个函数, return 0 是可以起作用的,只是可能现在不需要用到。