C语言——程序实现过程( 二 )


该符号在定义宏时并不常见,这里也是分享一下该符号 。
在给函数或者宏传参时,传参也是有讲究的,在参数中还有带着副作用的参数!我们在传递参数时,是根据该参数是否会改变而判断他是否会对函数产生副作用 。
#include#define MAX(a,b,c) (d=(a)>(b)?(a):(b))>(c)?d:(b)int main(){int a=2;int b=3;int c=4;int max=MAX(a++,b++,c++);printf("%d",max);return 0;}
如此乱的关系,真的是难以处理,所以在给宏传参时,应该避免使用带有副作用的参数 。
程序的预处理

C语言——程序实现过程

文章插图
其实在程序编译期间会出现一个程序预处理阶段,在这个阶段我们会对#定义的一些预处理符号进行替换和判断,例如
#undef
#undef STRINGNAM//取消对该字符的所有定义
该指令是用于取消上一条宏定义的 。如果你需要将宏取消又不想删除他,可以用该指令,而这种指令又被称为条件编译 。
在编译一个程序时,当我们觉得该代码无用或者是只适用于调试阶段,不想让该代码消失我们就可以使用条件编译,最常用的条件编译如下:
#if 常量表达式(满足条件执行,不满足退出)#endif //结束时一定要加该条件//常量表达式与预处理一起使用#define _expression_#if _expression_//……执行#endif//多分支#if 常量表达式//……执行#elif//……执行#else//……执行#endif
常见使用方法
#include#define ADDint main(){ #if 1>3printd("hello");#elif 3>1printf("hi");#elseprintf("world");#endif//这里否定要加ed#if !defined(ADD)printf("add");#endifreturn 0;}
文件包含方法也会影响程序
在我们使用库函数时,经常性的会使用一些头文件的包含,头文件的包含方法有两种,一种是使用,还有一种是使用“ ”,前者这是我们最常用的头文件包含方法,而后者虽然我们现在不常用,但是在开发时是会经常使用的 。
这两种头文件的包含分别有什么不同,两者的索引方式不同,使用" "引用的头文件在查找相关文件时会先在所在文件目录中查找是否含有该头文件,然后再会去库函数目录下查找 。而由包含的文件会直接去库函数中查找 。两者之间的效率不言而喻 。有时候我们会因为方便引用将一些头文件放到一个文件中,在引用时不小心调用了很多次,为了避免这类事件发生,我们可以用到:
//判定是否定义,如果没有定义则执行#ifndef#define#endif
案例:
#include#define ADD(a,b) ((a)+(b))int main(){#ifndef ADD//如果没有定义ADD#define ADD(a,b) ((a)+(b))//则定义#endif // !ADDint a = 2;int b = 2;printf("%d", ADD(a, b));return 0;}
当你上机调试后就可以发现这个条件编译符,他既可以判定#也可以对头文件进行判定 。
#ifndef stdio.h#include#endif如果没有定义ADD#define ADD(a,b) ((a)+(b))//则定义#endif // !ADDint a = 2;int b = 2;printf("%d", ADD(a, b));return 0;}
当你上机调试后就可以发现这个条件编译符,他既可以判定#也可以对头文件进行判定 。
#ifndef stdio.h#include#endif