【C/C++】C语言 makefile文件与头文件的写法

makefile 文件的书写。

总结下make 执行过程

1)make 在当前目录下找 "Makefile"或"makefile"的文件

2)如果找到,则会找文件中第一个目标文件(target)。

3)如果 main 命令的执行,依赖后面命令执行所产生的文件,则先执行后面命令    

4)当main 命令需要的文件生成完毕,则执行main 命令

makefile:

#开头的都是注释
一般的格式是: 
target:components  
rule
第一行表示的是依赖关系,第二行是所需文件齐全后得出目标所用的语句。
main:main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c
clean:
rm -rf *.o main

Makefile有三个非常有用的变量。分别是 @ , @, @^,$< 代表的意义分别是: 
$@ 目标文件
$^ 所有的依赖文件
$< 第一个依赖文件  
这样就可以把文件简化为

main:main.o mytool1.o mytool2.o
  gcc -o $@ $^
main.o:main.c mytool1.h mytool2.h
  gcc -c $<
mytool1.o:mytool1.c mytool1.h
  gcc -c $<
mytool2.o:mytool2.c mytool2.h
clean:
rm -rf *.o main
首先C语言的编译过程为

1.预处理阶段

2.语法词法分析阶段

3.编译阶段,首先编译成汇编语言,再将之编译成与CPU相关的二进制码,生成目标文件 .o ( .obj文件)。 // gcc -c

4.连接阶段,连接各个.o目标文件,生成特定平台相关的可执行文件。

#默认的头文件目录为/usr/include 和/usr/src/linux-headers-x.xx.0-xx/include/

头文件

//另一个角度分析编译过程。

gcc -c 命令只编译不链接的过程。

程序开始#include“xxx” 头文件,编译器寻找xxx头文件并把此行删掉,用xxx文件替换。(所以建议.h文件只放声明和定义,不放具体实现,影响效率)

没有语法错误及变量重名,则产生对应 .o 文件。此时还不检查.h中实现的函数,只要有.h文件就可。

接下来就有一个问题是,哪个文件对应实现了xxx.h 内声明的函数。这里其实不用把对应实现的命名为xxx.c,即可以随便起名。

因为C语言规定声明在实现前,则对应实现xxx.h的xxx.c文件如果函数之间有调用就在之前#include “xxx.h”。 如果互相间没有调用,就不用includ任何文件。

之后用gcc -c编译所有.c文件,得到.o文件(.h文件不用编译)。Link时 指定.h文件的对应实现文件.o即可(不用一一对应,指出需要的.o文件即可)

这里有篇不错的讲解:
https://www.cnblogs.com/laojie4321/archive/2012/03/30/2425015.html

查看stdio.h文件,得到scanf的定义

extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。
在这里插入图片描述
通常为了不重复包含相同的头文件,会声明与自己头文件名类似的常量,作为已经包含此头文件的标识。

一般规则为大写,并用下划线代替. 在前面加下划线。 比如stdio.h 声明了 _STDIO_H ,
在这里插入图片描述
运行结果为:
在这里插入图片描述
则防止重复定义的方式为

#ifndef _STDIO_H

// 如果之前包含过stdio.h ,则此处 _STDIO_H 一定会有定义

#include <stdio.h>

#endif

测试:

test.h 文件
在这里插入图片描述
main.c 文件
在这里插入图片描述
输出 23

自己实现头文件时,注意引用时要写include “mylib.h”

尖括号< >直接去库中查找头文件,双引号“ ”先在源文件所在文件在寻找,再去库中寻找。

附录:

Linux 命令 locate find whereis which 的区别

find:在磁盘上查找文件。默认为在当前文件夹下查找。

find -name *.xml //当前目录递归查找文件名 *.xml

locate:系统维护一个数据库,在数据库中查找,效果比较好! // 数据库大约一周更新一次。

which:在PATH变量下寻找可执行文件。

whereis:也在数据库上寻找,但只能查找源代码,指令手册等。
在这里插入图片描述

一个例子

【1】源文件中带头文件的绝对路径/相对路径,而后直接编译:
–>#include “/home/zxc/TEST/include/test.h”
–>gcc test.c -o test

【2】源文件中带头文件名,编译是用-I参数指明包含头文件的路径:
–>#include “test.h”
–>gcc test.c -I /home/zxc/TEST/include -o test

【3】源文件中带头文件名,编译使用makefile

猜你喜欢

转载自blog.csdn.net/sinat_33408502/article/details/106127239