函数

 

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中系统函数的参数的调用顺序是从右往左调用的
}

 

posted @ 2019-07-28 19:55  Coding_Changes_LIfe  阅读(182)  评论(0编辑  收藏  举报