函数
1、函数返回值
#include<stdio.h> #include<stdlib.h> int go(){ //函数没有写返回值类型时,默认为int,所以需要些return 1 printf("gogo"); return 1; } int main(){ go();
return 1;//main函数的return 相当于直接退出,,没有return会执行完,所有语句 }
2、函数的包含
头文件:luoxu.h
源文件有两个:test.c,funtions.c 源文件内部的各个.c源文件中的函数可以相互调用,但需要事先声明函数原型,这就是头文件的作用
luoxu.h
#include<stdio.h>//函数头只放函数的声明 void runH(); void runHFun();
funtions.c
#include"luoxu.h" //实际上此句是为了引人#include<stdio.h>,才能使用printf函数,test.c声明了#include<stdio.h>,此次又声明了#include<stdio.h>,也是声明了两次 //函数源文件用于定义函数,在头文件中将其声明 //重复声明没有问题,重复定义就有问题 //#include<stdio.h> //如果此句写上的话,那在luoxu.h中也声明了#include<stdio.h>,此时就声明了两次#include<stdio.h> void runH(){ printf("runH"); } void runHFun(){ runH(); printf("runHFun"); }
test.c 函数的入口
#include"luoxu.h" //其实此句就相当于函数的声明 //源文件内部的各个.c源文件中的函数可以相互调用,但需要事先声明函数原型,这就是头文件的作用 void main(){ runHFun(); getchar(); }
3、函数参数的值传递 局部变量是为块语句服务的
#include<stdio.h> void change(int a){ //形参,定义时,无法确定局部变量a值是多少,无法分配内存空间,只有在调用时,才知道其具体的值,分配一个临时空间存储实参传过来的值,调用结束后释放 a = 100; printf("%x\n", &a);//18f758 } void main(){ int a = 10; change(a);// 实参,函数调用时分配临时空间,调用完立即释放 printf("%x\n",&a);//18f82c // change()函数中a的地址和主函数值a的地址不同,说明他们是不同的变量,只是值传递过去而已 getchar(); }
#include<stdio.h> void print(int a, char b, float c){ // printf("a=%d,b=%c,c=%f\n", a, b, c);//a=10,b=A,c=1.01 } void main(){ print(10.5, 'A', 1.01);//形参和实参的类型和个数要一致,在值传递中会发生自动类型转换 getchar(); }
4、全局变量与局部变量
#include<stdio.h> int data =0; //定义变量时,未初始化,默认为0 // 全局变量i不属于任何一个函数,可以被任何函数调用 //创建全局变量比main函数还要早,要见名知意 //全局变量的声明周期就是程序的生命周期 //全局变量会一直占用内存,而局部变量用完就释放<br>//容易被局部变量重名,屏蔽 // 避免全局变量被错误的修改,修改时一定要注释,为什么修改 //全局变量可以用于函数之间的通信 int add(int a, int b){ int z =a+b; data++; return z; //z是临时变量,在寄存器中,调用结束后会被马上销毁 } void main(){ data++; //函数的返回值有副本机制,我们这里打印的是返回值的副本,原来的临时变量 z已经被销毁 //除了数组外,其他都有副本机制; //结构体变量(即使内部有数组)有副本机制,结构体数组没有 printf("%d\n",add(1,2)); // printf("%d\n",data); } //块语句内部的局部变量作用域是从块语句开始到结束 // 嵌套块语句内部的同名变量会屏蔽外部的同名变量 // 同一个块语句不能定义同名变量
5、getchar
#include<stdio.h> void main(){ char ch1 =getchar(); // char ch2 =getchar(); //getchar 会把回车当做一个字符接收,从输出的结果可以看出 printf("[%c].[%c]",ch1,ch2); /* d [d].[ ] * */ }
s = gets();
puts();
c =getchar();
putchar();
6、可变参数的函数
#include<stdio.h> #include <stdarg.h> //可变参数的函数 int add(int num, ...){ //累加num个数 int res =0; va_list args; //创建一个char类型的指针 va_start(args,num); //开始读取参数 for (int i = 0; i < num; ++i) { int temp = va_arg(args,int);//以int类型读取args中的数值 res += temp; } return res; } void main(){ printf("%d\n",add(4,3,5,7,6)); //累加四个参数 printf("%d\n",add(2,3,5)); //累加2个参数 }
7、函数参数的调用顺序
#include<stdio.h> #include <stdarg.h> //函数参数的调用顺序 void show(int a, int b){ printf("%d\n%d",a,b); } void main() { int num = 100; show(num, ++num); // 101 101 说明在VC和GCC中自定义函数的参数的调用顺序是从右往左调用的 int num2 = 100; printf("%d\n %d", num2, ++num2); // 101 101 说明在VC和GCC中系统函数的参数的调用顺序是从右往左调用的 }