c编译和预处理

作者: 霡霂976447044 | 来源:发表于2019-02-26 14:12 被阅读1次

编译预处理

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

主要分为:

    1. 宏定义,一般格式:#define name value
      1. 变量式宏定义
      1. 函数式宏定义
    1. 文件包含
      #include <filename>
      #include "filename"
    1. 条件编译
    1. assert宏

宏定义

源码如下:

#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

相关文章

  • 基础C语言知识串串香11☞宏定义与预处理、函数和函数库

    六、C语言宏定义与预处理、函数和函数库 6.1、编译工具链 源码.c->(预处理)->预处理过的.i文件->(编译...

  • 2019-03-12 计算机二级C语言程序设计之编译预处理和动态

    编译预处理 在C语言中,凡是以#号开头的,都称为“编译预处理”命令行。所谓“编译预处理”就是在C编译程序对C源程序...

  • C/C++源代码到可执行程序的过程详解

    源代码-->编译预处理-->编译-->优化-->汇编-->链接-->可执行文件 1.编译预处理 读取c/c++源程...

  • C++详解预处理

    C/C++编译系统编译程序的过程为预处理、编译、链接。预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进...

  • C语言学习笔记

    1. C程序编译 C程序的编译可以简单分为4个步骤:预处理,编译,汇编,。 预处理 展开头文件·删除注释,条件编译...

  • C 语言编译流程

    C语言编译四个阶段: 预处理、编译、汇编、链接。 预处理阶段:预处理器cpp根据字符#开头的命令,修改C程序。通常...

  • C语言学习笔记

    1. C的预处理器 .h头文件 #include是C语言的预处理指令,C语言编译器在编译前会对源码进行预处理工作。...

  • 预处理和内存管理

    预处理和内存管理 1. 什么是预处理? 预处理是 C 和 C++ 语言独有的特色,它允许开发人员定义宏,编译器在编...

  • 【OC梳理】预处理指令

    预处理指令,就是我们常说的宏定义。在编译器对 C或者 objective-c 进行编译前,编译器会对这些预处理命令...

  • 【C++】gcc编译过程

    【C++】gcc编译过程 C++编译过程主要分为,预处理、编译、汇编、链接四个过程。如下图所示: 第一步:预处理 ...

网友评论

    本文标题:c编译和预处理

    本文链接:https://www.haomeiwen.com/subject/oseayqtx.html