c语言与预处理指令

时间:2021-11-14 01:13:15

预处理指令:在程序编译前执行,效率高,以符号#开头,没有';'结尾的编译指令,这些指令称为预处理命令,预处理命令属于C语言编译器,而不是C语言的组成部分,通过预处理命令可扩展C语言程序设计的环境,

例:

#include<stdio.h>

#include“stu.h”

#include <string.h>

系统文件用<>,自己写的用””

 

宏定义

文件包含

条件编译

定义常量

 

 

 

宏定义不仅在编译前执行,效率比较高,并且不会检测内存,如果替换之后会发生检测

#include<stdio.h>

#include"stu.h"

#include<string.h>

#define LENGTH 20 //length叫宏名,20为被宏名替换的字符串

int main(int argc,const char * argv[])

{

for (int i=0; i<LENGTH; i++) {

        printf("%i\n",i);

    }

    return0;

}

 

在编译之前会检查所有的LENGTH并把它替换为20

带参数的宏定义注意点,宏定义的参数只做替换操作并不会做计算操作

#include<stdio.h>

#include"stu.h"

#include<string.h>

#define calcSum(a,b) a*b

int main(int argc,const char * argv[])

{

int i=calcSum(2+2,3+6);  

替换过程

// calcSum(a,b) a*b

// int i=a+b; int i=2+2*3+6

return0;

}

所以宏定义的计算过程定义应该用括号就要采取以下定义方式

 

#include<stdio.h>

#include"stu.h"

#include<string.h>

#define calcSum(a,b) (a)*(b)

int main(int argc,const char * argv[])

{

int i=calcSum(2+2,3+6);  

替换过程

// calcSum(a,b) a*b

// int i=a+b; int i=2+2*3+6

int k=calcSum(2+2,3)/calcSum(1,2);

//int k=2+2*3/1*2

return0;

}

 

但是这种定义方式还是不完美存在某些bug,所以我们应该把计算结果也用括号包住,总之我们要记住因为它只是很笨拙的做了替换操作,所以我们在使用宏定义的时候要特别小心

#define calcSum(a,b) ((a)*(b)) //最终正确定义

 

条件编译由宏定义配合,条件中不能放变量,因为变量是程序运行时才会有,而条件编译是在程序编译之前运行

#include<stdio.h>

#include"stu.h"

#include<string.h>

#define LENGTH 20

int main(int argc,const char * argv[])

{

    int k=0;

    #if LENGTH>10

    k=sum(10,20);

    #elif LENGTH=20

    k=sumAndMin(15,15, &k);

    #else

    k=sumNum(2,5);

    #endif

 

    printf("%i",k);

    return0;

}

程序性能比普通函数中的if else条件判断提高,因为以上条件编译只会编译一行代码

注意:结尾一定要写#endif因为如果没有#endif标记条件编译结束,它会一直编译到程序结尾,这样就会编译不通过,很像sqlthen else

 

是否定义宏定义作为条件编译的条件

#if defined(LENGTH)

        printf("定义了宏名为LENGTH的宏定义");

#endif

   

#if !defined(LENGTH)

    printf("没有定义了宏名为LENGTH的宏定义");

#endif

上面的判断也可以用下面的方式

#ifdef LENGTH

    printf("定义了宏名为LENGTH的宏定义");

#endif

 

#ifndef LENGTH

    printf("没有定义了宏名为LENGTH的宏定义");

#endif

Inlcude指令很像JSP中的inclue,直接把包含文件中的内容拷贝过来,我们经常会再Java项目中定义一些公共的JS文件或者我们自己开发的公共组件用include包含进来

#include<文件名>

在C语言函数头文件所在目录中找

#include "文件名"

先在程序源程序的目录中找,如果找不到,会去path(也就是系统环境变量配置的path)路径找,如果还是找不到才会去C语言函数头文件所在目录中找

可以嵌套包含,a.h包含b.h,b.h包含c.h,但是不可以递归相互包含a.h包含b.h,b.h包含a.h。

因为头文件可以嵌套包含,所以也带来了一些问题,比如头文件重复包含,这个时候我们就要使用宏定义来处理,这也是我们在XCODE中创建头文件的时候,XCODE会自动生成一段宏定义代码的原因,降低重复编译,提高效率

#ifndef testc_Student_h //如果没有定义宏testc_Student_h

#define testc_Student_h //定义一个宏testc_Student_h

void test();

#endif

这样不管我们的头文件被包含多少次,但是程序只会编译一次头文件中的代码