C语言高级-预处理、函数、函数库

第一点

关于预处理

程序执行的过程

(1)源码.c->(编译)->elf可执行程序
(2)源码.c->(编译)->目标文件.o->(链接)->elf可执行程序
(3)源码.c->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序
(4)源码.c->(预处理)->预处理过的.i源文件->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序

什么是预处理

编译器本身的主要目的是编译源代码,将C的源代码转化成.S的汇编代码。编译器聚焦核心功能后,就剥离出了一些非核心的功能到预处理器去了。预处理器帮编译器做一些编译前的杂事。

常见的预处理

(1)#include(#include <>和#include ""的区别)

  如果是系统指定的自带的用<>,如果是自己写的在当前目录下放着用"",如果是自己写的但是集中放在了一起专门存放头文件的目录下,将来在编译器中用-I参数来寻找,这种情况下用<>。
(2)注释  给人看的,编译器不知道注释;
(3)#if #elif #endif        #ifdef

#ifdef XXX判定条件成立与否时主要是看XXX这个符号在本语句之前有没有被定义,只要定义了(我们可以直接#define XXX或者#define XXX 12或者#define XXX YYY)这个符号就是成立的。#if (条件表达式),它的判定标准是()中的表达式是否为true还是flase,跟C中的if语句有点像。
(4)宏定义

右边这种带参宏隐患很大,因为运算符优先级的关系,因此在宏定义时,尽量把参数都用括号括起来(左边);

C语言高级-预处理、函数、函数库_第1张图片C语言高级-预处理、函数、函数库_第2张图片

第二点

宏定义实战

MAX宏 :得出两数较大者

C语言高级-预处理、函数、函数库_第3张图片

预处理后:

C语言高级-预处理、函数、函数库_第4张图片

SEC_PER_YEAR:表示一年有多少秒

常规表达:这种写法是大家最能想到的,但是是错的,因为数字超过了int类型存储的范围!

 ​​​​​​正确写法:

带参宏、带参函数、内联函数

带参宏:宏定义,是在调用宏的地方原地展开,没有返回参数和返回值。因此,他的调用开销比较少,而且他是在预处理阶段就完成的,根本不用进入到编译器阶段;这种就适合代码量少(可能一两句的情况)

带参函数:带参函数,是在编译器阶段去识别使用的,编译器会自动的帮我们去做参数的静态类型检查。当有错误时,他会报警告!当调用函数的时候,就转到函数中去执行,等到执行完,就返回到调用的地方。这种调用开销比较大,适合那种代码多,又不影响效率的情况。

内联函数通过函数定义前加inline关键字去实现;它的本质是函数,所以他有函数所有的优点(编译器给静态类型检查)。同时他又有带参宏的优点(原地展开,调用开销小);

第三点

函数

递归函数

递归函数就是函数中调用了自己本身这个函数的函数,但是递归不等于循环,通常用于解决的问题就是求阶乘、求斐波那契数列

C语言高级-预处理、函数、函数库_第5张图片

递归函数原理

递归函数实际上是在栈内存上递归执行的,所以一定要有收敛性,不然的话会栈溢出,最终执行段错误。

你可能感兴趣的:(C语言学习感想,c语言,linux)