函数的定义
函数名
函数名的后面有个圆换号(),代表这个为函数,不是普通的变量名。
形参
在定义函数时指定的形参,在未出现函数调用时,它们并不占内存中的存储单元,因此称它们是形式参数或虚拟参数,简称形参,表示它们并不是实际存在的数据,所以,形参里的变量不能赋值。
void max(int a = 10, int b = 20) // error, 形参不能赋值
{
}
函数的调用
main()
为自动被调用的主函数,无需人为调用。一个C程序里有且仅有一个main()
函数。
函数的声明
如果使用用户自己定义的函数,而该函数与调用它的函数(即主调函数)不在同一文件中,或者函数定义的位置在主调函数之后,则必须在调用此函数之前对被调用的函数作声明。
所谓函数声明,就是在函数尚在未定义的情况下,事先将该函数的有关信息通知编译系统,相当于告诉编译器,函数在后面定义,以便使编译能正常进行。
注意:一个函数只能被定义一次,但可以声明多次。
#include<stdio.h>
/*
* test()定义在main()方法之后,
* 如果此处不作声明,将编译失败。
*/
void test(int a); // 函数的声明,分号不能省略
//void test(int);//另一种声明方式
int main() {
test(10);
return 0;
}
void test(int a) {
printf("这里是test方法, 收到的参数是%d\n", a);
}
函数定义和声明的区别:
1)定义是指对函数功能的确立,包括指定函数名、函数类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
2)声明的作用则是把函数的名字、返回值类型以及形参的个数、类型和顺序(注意,不包括函数体)通知编译系统,以便在对包含函数调用的语句进行编译时,据此对其进行对照检查(例如函数名是否正确,实参与形参的类型和个数是否一致)。
变量的声明与定义的区别可以忽略不计。
变量的声明:只是通知编译器该变量占用了一个变量名,但不要给变量分配内存。其它变量不可以起和它一样的名字。
变量的定义:通知编译器该变量占用了一个变量名并且已经分配给它一块内存了。
被声明的变量一旦被赋值了,就相当于被定义了。
int i;//这是定义变量
extern int i;//这是声明变量
main函数与exit函数
在main函数中调用exit和return结果是一样的,但在子函数中调用return只是代表子函数终止了,在子函数中调用exit,那么程序终止。
#include<stdio.h>
void test(int a);
int main() {
test(10);
printf("test方法执行结束了");//(1)
return 0;
}
void test(int a) {
printf("这里是test方法, 收到的参数是%d\n", a);
exit(0);//此处终止了程序,所以代码(1)没有被执行
}
多文件(分文件)编程
分文件编程
- 把函数声明放在头文件xxx.h中,在主函数中包含相应头文件
- 在头文件对应的xxx.c中实现xxx.h声明的函数
//这是max.h
int max(int, int);
//extern int max(int, int);//关键字extern可以省略
//这是max.c
int max(int a, int b) {
return a > b ? a : b;
}
//这是main.c
#include<stdio.h>
#include"max.h"
int main() {
int a = 1;
int b = 2;
int c = max(a, b);
printf("a = %d, b = %d, 二者最大值为%d\n", a, b, c);
return 0;
}
防止头文件重复包含
当一个项目比较大时,往往都是分文件,这时候有可能不小心把同一个头文件 include 多次,或者头文件嵌套包含。
a.h
包含b.h
#include"b.h"
b.h
包含a.h
#include"a.h"
main.c
中使用其中头文件
#include "a.h"
int main()
{
return 0;
}
上面的代码编译失败:
为了避免同一个文件被include多次,C/C++中有两种方式,一种是 #ifndef 方式,一种是 #pragma once 方式。
方法一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
// 声明语句
#endif
方法二:
#pragma once
// 声明语句