C语言C语言&嵌入式

c编译和预处理

2019-02-26  本文已影响1人  霡霂976447044

编译预处理

编译预处理处于C程序编译第一步骤,基本操作就是提前处理C中以 # 开头的语句,将源代码里一些代码替换新的代码

主要分为:

宏定义

源码如下:

#include<stdio.h>
#define NAME "zhangsan"
int main() {
    printf(NAME);
    return 0;
}

用gcc -E命令可以得到预编译后的代码,如下:

...省略
extern FILE *popen (const char *__command, const char *__modes) ;
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
# 914 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 944 "/usr/include/stdio.h" 3 4
# 2 "example.c" 2
# 3 "example.c"
int main() {
 printf("zhangsan");
 return 0;
}

注意倒数第三行.NAME替换成为了 “zhangsan”
那么是因为我们写的源码:

#define NAME "zhangsan"

这个""双引号是自己写的还是预编译自己加的呢?更改为

#define NAME zhangsan

重复之前的gcc -E操作,得到

# 3 "example.c"
int main() {
 printf(zhangsan);
 return 0;
}

所以,以宏定义的预编译只是单纯的替换文本的操作。
注意:在”NAME” 引号包括起来则不会替换。
可以将宏定义的value定义为表达式巧妙的运算。

变量式宏定义

一般形式: #define 标识符 字符串

#include <stdio.h>
#define PI 2.1415926
#define C (2 * PI * radius)
int main() {
    int radius;
    float circlue;
    printf("Please enter the circle ridius: ");
    scanf("%d",&radius);
    circlue = C;//使用宏定义
    printf("Circle circlue: %f\n",circlue);
    return 0;
}

gcc -E a.e,tail a.e 查看

# 4 "define_variable.c"
int main() {
 int radius;
 float circlue;
 printf("Please enter the circle ridius: ");
 scanf("%d",&radius);
 circlue = (2 * 2.1415926 * radius);
 printf("Circle circlue: %f\n",circlue);
 return 0;
}

可以看到C被替换了。

函数式宏定义

一般形式: #define 标识符(参数列表) 字符串
把之前的C宏定义改一下:

#include <stdio.h>
#define PI 2.1415926
#define C(r) 2 * PI * r
int main() {
    int radius;
    float circlue;
    printf("Please enter the circle ridius: ");
    scanf("%d",&radius);
    circlue = C(radius);
    printf("Circle circlue: %f\n",circlue);
    return 0;
}

注意函数式宏定义宏名字后没有空格
gcc -E 得到预编译后的代码,tail查看后几行。

# 4 "define_variable.c"
int main() {
 int radius;
 float circlue;
 printf("Please enter the circle ridius: ");
 scanf("%d",&radius);
 circlue = 2 * 2.1415926 * radius;
 printf("Circle circlue: %f\n",circlue);
 return 0;
}

嵌套宏定义

#include <stdio.h>
#define A 1
#define B 2
#define ADD A+B 
#define C(r) 2 * PI * r
int main() {
    int i = ADD;
    printf(" %d\n",i);
    return 0;
}

多行宏定义

以\换行

#include <stdio.h>
#define exchange(a,b){\
    a = b-a;\
    b = b-a;\
    a = b+a;\
}
int main() {
    int i;
    int j;
    printf("Please enter first num:");
    scanf("%d",&i);
    printf("Please enter second num:");
    scanf("%d",&j);
    exchange(i,j);
    printf("Exchanged,First num: %d, second: %d\n",i,j);
    return 0;
}

文件包含

文件包含也是替换操作。
Test.h

#define DATA "Hello!"
void showData();

Test.c

#include "Test.h"
#include <stdio.h>
void showData() {
    printf(DATA);
}

Main.c

#include <stdio.h>
#include "Test.h"
int main() {
    printf("调用Test.h的showData方法:\n");
    showData();
    return 0;
}

根据以上几个文件得到预编译文件Main.i

......
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 944 "/usr/include/stdio.h" 3 4
# 2 "Main.c" 2
# 1 "Test.h" 1
# 2 "Test.h"
void showData();
# 3 "Main.c" 2
int main() {
 printf("调用Test.h的showData方法:\n");
 showData();
 return 0;
}

嵌套包含和条件编译

一般在头文件里定义的时候

#ifndef _TEST_H
#define _TEST_H
#define DATA "Hello!"
void showData();
#endif
上一篇下一篇

猜你喜欢

热点阅读