语言宏定义与预处理、函数和函数库
目录
1、C语言预处理理论
2、C语言预处理代码实战
3、宏定义1
4、宏定义2
5、.函数的本质
6、.函数的基本使用
7、递归函数
8、函数库
9、字符串函数
10、数学库函数
11、自己制作静态链接库并使用
12、自己制作动态链接库并使用
1、C语言预处理理论
1.1、由源码到可执行程序的过程
过程:源码.c->(预处理)->预处理过的.i源文件->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序
预处理用预处理器,编译用编译器,汇编用汇编器,链接用链接器,这几个工具再加上其他一些额外的会用到的可用工具,合起来叫编译工具链。gcc就是一个编译工具链。
1.2、预处理的意义
编译器本身的主要目的是编译源代码,将C的源代码转化成.S的汇编代码。编译器聚焦核心功能后 ,就剥离出了一些非核心的功能到预处理器去了。预处理器帮编译器做一些编译前的杂事。
1.3、编程中常见的预处理
(1)#include(#include <>和#include ""的区别)
(2)注释
(3)#if #elif #endif#ifdef
(4)宏定义
1.4、gcc中只预处理不编译的方法
1、gcc编译时可以给一些参数来做一些设置,譬如gcc xx.c -o xx可以指定可执行程序的名称;譬如gcc xx.c -c -o xx.o可以指定只编译不连接,也可以生成.o的目标文件。
2、gcc -E xx.c -o xx.i可以实现只预处理不编译。一般情况下没必要只预处理不编译,但有时候这种技巧可以用来帮助我们研究预处理过程,帮助debug程序。
(1)预处理前源代码
#define pchar char *
typedef char * Tpchar;
int main(void)
{
pchar p3;
Tpchar p2,p1;
return 0;
}
(2)在linux的命令窗口中输入:gcc -E xx.c -o xx.i
(3)得到预处理后的代码
typedef char * Tpchar;
int main(void)
{
char * p3;
Tpchar p2,p1;
return 0;
}
预处理后的现象有:
第一,宏定义语句本身不见了(可见编译器根本就不认识#define,编译器根本不知道还有个宏定义);
第二,typedef重命名语言还在,说明它和宏定义是有本质区别的(说明typedef是由编译器来处理而不是预处理器处理的);
2、C语言预处理代码实战
2.1、头文件包含
1、#include <>和#include""的区别:
<>专门用来包含系统提供的头文件(就是系统自带的,不是程序员自己写的),更深层次来说:<>的话C语言编译器只会到系统指定目录(编译器中配置的或者操作系统配置的寻找目录,譬如在ubuntu中是/usr/include目录,编译器还允许用-I来附加指定其他的包含路径)去寻找这个头文件(隐含意思就是不会找当前目录下),如果找不到就会提示这个头文件不存在。
""用来包含自己写的头文件。""包含的头文件,编译器默认会先在当前目录下寻找相应的头文件,如果没找到然后再到系统指定目录去寻找,如果还没找到则提示文件不存在。
总结+注意:规则虽然允许用双引号来包含系统指定目录,但是一般的使用原则是:(1)如果是系统指定的自带的用<>。(2)如果是自己写的在当前目录下放着用""。(3)如果是自己写的但是集中放在了一起专门存放头文件的目录下将来在编译器中用