1、多文件编程
- 把函数声明放在头文件xxx.h中,在主函数中包含相应头文件
- 在头文件对应的xxx.c中实现xxx.h声明的函数
a、主文件
#include<stdio.h>
#include "MyMain.h"//需要包含头文件,头文件包含我们自定义的函数
int main()
{
int num1;
int num2;
printf("请输入两个数字:");
scanf("%d %d",&num1,&num2);
int MAXA_B=max(num1,num2);
int ADDA_B=add(num1,num2);
printf("%d、%d两数的和%d,最大值为%d\n",num1,num2,ADDA_B,MAXA_B);
return 0;
}
b、函数1:求和函数,函数的C文件名称不需要和函数名称一致。,且无需添加头文件(放函数声明的头文件)。
int add(int a,int b)
{
return a+b;//返回两个值的和。
}
c、函数2:最大值函数
int max (int a,int b)
{
return a>b?a:b;//比较大小,返回最大值
}
d、头文件:放函数1和函数2,并在该函数中进行声明。
#ifndef _MYMAIN_H_
#define _MYMAIN_H_
int max (int a,int b);
int add(int a,int b);
#endif
注意
1、定义函数的时候,记得加括号,函数和函数文件名(.c文件)可以不一致。
2、头文件模版需要熟记
#ifndef _文件名_H_
#define _文件名_H_
函数1;
函数2;
#endif
2、gcc命令行编译多文件程序
gcc -g main.c AddA_B.c MaxA_B.c
-g 后面存放需要编辑的文件名称,头文件无法加进去,多个文件用空格隔开,默认编译生产的可执行文件名称为a.exe,可以通过后面加-o 修改文件名
gcc -g main.c func.c -o main.exe
//编译g main.c func.c两个文件,生产main.exe 文件。
ps:命令行显示中文乱码,修改命令:chcp 65001
3、头文件包含的区别、防止头文件重复包含
- 当一个项目比较大时,往往都是分文件,这时候有可能不小心把同一个头文件 include 多次,或者头文件嵌套包含。
- 为了避免同一个文件被include多次,C/C++中有两种方式。
- 方法一:
#ifndef __SOMEFILE_H__
#define __SOMEFILE_H__
// 声明语句
#endif
- 方法二:
#pragma once
// 声明语句
4、extern关键字
extern主要用于声明外部变量或函数,当我们将一个变量或函数声明为extern时,那么就表示该变量或函数是在其他地方定义的,我们只是在当前文件中引用它。
示例
#include <stdio.h>
extern int global_val;
extern void printf_val();
int main() {
global_val = 100;
printf_val();
return 0;
}
#include <stdio.h>
int global_val;
void printf_val() {
printf("other->global_val: %d\n", global_val);
}
- > 表示系统直接按系统指定的目录检索
- "" 表示系统先在 "" 指定的路径(没写路径代表当前路径)查找头文件,如果找不到,再按系统指定的目录检extern关键字
5、static 关键字
- 作用1:隐藏,限制作用域
示例:
#include<stdio.h>
#include "MyMain.h"//需要包含头文件,头文件包含我们自定义的函数
int main()
{
int num1;
int num2;
printf("请输入两个数字:");
scanf("%d %d",&num1,&num2);
int MAXA_B=max(num1,num2);
int ADDA_B=add(num1,num2);
printf("%d、%d两数的和%d,最大值为%d\n",num1,num2,ADDA_B,MAXA_B);
return 0;
}
b、函数1:求和函数
static int add(int a,int b)
{
return a+b;//返回两个值的和。
}
c、函数2:最大值函数
int max (int a,int b)
{
return a>b?a:b;//比较大小,返回最大值
}
d、头文件:
#ifndef _MYMAIN_H_
#define _MYMAIN_H_
int max (int a,int b);
int add(int a,int b);
#endif
编译结果
gcc -g main.c AddA_B.c MaxA_B.c//编译指令
main.c:11: undefined reference to `add'
collect2.exe: error: ld returned 1 exit status
在上面文件中,我在AddA_B.c文件中 int add(int a,int b)前面加上static,重新编译就会报错,主要就是我将AddA_B.cw文件中函数通过static 进行隐藏,导致其他函数无法调用。
当我们同时编译多个文件时,所有未加 static 前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问
对于函数来讲,static 的作用仅限于隐藏
应用场景:智能网关项目:zigbee ble wifi模块的同事都需要用日志打印的函数,如何设计一个日志打印函数给他们使用?,
通过该关键字就可以进行隐藏数据,限制查看权限,只能查看日志,而不是所有数据都可以看。
- 作用2:管理生命周期
程序实例
打印程序的调用次数
a、未使用static版本
int add( )
{
int a=0;
a++;
return a;
}
#ifndef _NUM_H_
#define _NUM_H_
int add();
#endif
#include <stdio.h>
#include"num.h"
int main()
{
for(int i=0;i<5;i++)
{
int a=add();
printf("%d\n",a);
}
return 0;
}
gcc -g man.c number.c -o a.exe//编译指令
//编译结果
1
1
1
1
1
出现该结果的原因是由于每次调用函数add时,调用完a的值就清除了,所以每次调用打印都会重置,结果都是1.
b、使用static版本
int add( )
{
int a=0;
static a++;
return a;
}
#ifndef _NUM_H_
#define _NUM_H_
int add();
#endif
#include <stdio.h>
#include"num.h"
int main()
{
for(int i=0;i<5;i++)
{
int a=add();
printf("%d\n",a);
}
return 0;
}
gcc -g man.c number.c -o a.exe//编译指令
//编译结果
1
2
3
4
5
成功打印调用结果,a是add()的局部变量 -只初始化一次
每次调用函数add()''a’值不会被重置
应用案例:点餐屏:统计损耗(打印机)模块的使用次数。