前列腺炎如何食疗,孙隽圣,杰克逊-马丁内斯
C标准定义了如下五个预处理符号
__FILE__//进行编译的源文件名称 __LINE__//文件当前行号 __DATE__//文件被编译的日期 __TIME__//文件被编译的时间 __STDC__//如果编译器遵循ANSI C,值为1,否则未定义
在文件输入输出以及输出日志等场合下我们会用到这些预处理符号,比如
#include #include #define LOG fprintf(pf,"%d %d %d %d\n",\ __FILE__,__LINE__,__DATE__,__TIME__,__STDC__) int main() { int i = 0; FILE* pf = fopen("log.txt","w");w if(pf == NULL) { printf("open failure!\n"); exit(EXIT_FAILURE); } for(i = 0; i < 5; i++) { LOG; } fclose(pf); return 0; }
\+回车 : 续行符,转义字符,后面不能加任何除回车之外的字符,否则会报错
#define有两个作用,一个是定义标识符,第二个是定义宏
//#define name stuff #define MYINT int //typedef stuff name typedef int MYINT;
不要在define定义的标识符里加分号
#define机制包括一个规定,允许把参数替换到文本中,这种实现通常叫做宏或定义宏
//#define name(parament-list) stuff #define MAX ((a)>(b)?(a)(b)) int a = MAX(11+2,11-2);//int a = ((11+2)>(11-2)?(11+2):(11-2));
宏定义永远不要吝啬括号,防止因为优先级的问题导致出现不可思议的后果 宏不能实现递归 宏只文本替换,并不简化计算 字符串中的内容不会发生宏替换
#define X 100 printf("X");//不会宏替换#和##
编译器会自动就两个相邻字符串自动连接成一个
#:把参数插入到字符串中
#a -> “a”
#define PRINT(x,format)\ printf("the value of "#a" is "#format"\n",x) //printf("the value of ""x"" is""format""\n",x) int a = 10; PRINT(x,"%d");
##可以把位于它两边的符号拼成一个符号
#define CAT(x,y) ((x)##(y)) int num5 = 10; CAT(num,5);//=num5
没有类型检查是宏的一大特点(但同时也是不安全的隐患),可以完成很多函数不可能做到的功能
#define MALLOC(n,type)\ (type*)malloc(n*sizeof(type))
但是当逻辑复杂并且代码量巨大时,调用和返回的开销和运算的时间相比微乎其微,可以省略
宏的参数如果是一个表达式,只会文本替换,不会进行计算
总结:各有千秋,小代码量使用宏,大代码量使用函数,C++中摈弃宏这一概念,使用内联,基于优缺点,最好不要使用宏
int a = 10;int b = 0; b = a+1; b = a++;//带有副作用的表达式,使a发生改变
不要给宏参数传入带有副作用的参数
宏:全部大写
函数: 不全部大写
例外
//getchar()由库函数实现还是由宏实现是编译器决定的 #define getchar() getc()
#undef name //取消宏标识符name的定义
#define __DEBUG__ 1 #ifdef __DEBUG__ 语句; #endif
#if 常量表达式(为真编译,为假,不编译) 语句; #endif
#if 常量表达式 语句; #elif 常量表达式 语句; #elif 常量表达式 语句; #endif
#ifndef __DEBUG__ //==>#if !defined(__DEBUG__) #ifdef __DEBUG__ //==>#if defined(__DEBUG__)
预处理指令可以进行嵌套
pragma onec //新式防止头文件被多次引用 //繁琐 #ifndef __TEST_H__ #define __TEST_H__ #endif //__TEST_H__
#include //直接去库目录下查找 #include "filename" //先查找当前工作目录下查找,然后去库目录查找
遇到#error便会产生一个编译错误
源字符串必须以’/0’结束,返回目标字符串地址
且这个函数不管目标空间是否放得下返回的目标字符串
善用断言,头文件为
这次函数的返回值可以作为下一个函数的参数,达到链式反应的效果
printf(“%d\n”,strlen(strcpy(p,”hello world!”)));
编译型错误
直接看编译器错误提示信息即可 链接型错误
函数名,变量名写错,库文件使用错误(第三方库) 运行时错误
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
如何在没有core文件的情况下用dmesg+addr2line定位段错误
用QT制作3D点云显示器——QtDataVisualization
网友评论