全局变量使用:
1.在源文件中定义全局变量;
2.如果只是在定义该全局变量的文件中使用该全局变量,可以不声明;
3.如果要在一个外部的源文件中使用该全局变量,则该变量必须被声明;
4.在对应的头文件中加extern关键字声明,头文件中全局变量只能声明不能初始化,定义应在.c文件
在头文件的声明里,函数默认为extern,编译器会自动加上。
预处理阶段(只认
#include):
预处理器看到#include "ji.h",把ji.h里的int get_ji(int num1, int num2);复制过来。看到#include "shang.h",把shang.h里的声明复制过来。
此时,main.c里只有“声明”(知道有这两个函数),但没有“定义”(不知道这两个函数具体怎么算)。编译 + 链接阶段(关键区别):
如果只输入gcc main.c,编译器会报错:undefined reference to 'get_ji'和undefined reference to 'get_shang'。因为编译器只编译了main.c,找不到get_ji和get_shang的具体代码(定义)。头文件只是“承诺”这些函数存在,但真正的“兑现”需要靠链接器把对应的.c文件编译结果合并进来。
Makefile:管理代码工程的编译和链接,由make工具进行解释,实现一键化工程的编译和链接。
文件:Makefile/makefile(文件/脚本)
语法:
目标文件:依赖文件
编译规则
目标文件:a.out
依赖文件(生成目标文件所依赖的源文件):main.c sum.c sub.c ......
编译规则:gcc main.c sub.c sum.c ( -o a.out)
编译代码:make
Makefile中的变量:
1.自定义变量
OBJ = a.out //定义Makefile的变量OBJ,并为其赋值 SRC = main.c sum.c sub.c == SRC += main.c SRC += sum.c SRC += sub.c CC = gcc INCLUDE = ../include //include"xxx"双引号里的内容只能在当前路径下访问,所以使用-I指明头文件路径 LIBS = ../lib $(OBJ) :$(SRC) //变量的引用:$() $(CC) $(SRC) -o$@ -I$(INCLUDE) -L$(LIBS) -lm //-o $(OBJ) 给自定义变量起名 //-I头文件路径 -L指定库的位置 //-lm链接数学库 == a.out: main.c sum.c sub.c gcc main.c sub.c sum.c 自定义伪代码: clean: rm $(OBJ) //表示clean实现移除文件功能 //用 make clean调用=:给变量赋值
+=:在原变量值的基础上再增加新增
?=: 若变量之前没有被赋值则赋值,若之前被赋过值则保留原值
2.系统变量
可直接使用:
$@:表示目标文件
$^ :表示所有依赖文件
$<:表示第一个依赖文件