C++面试常见问题——01预处理与宏定义

C++面试常见问题--------01预编译和宏的使用

C++预处理器

预处理器是一些指令,它将指示编译器在实际编译之前需要完成的预处理。预处理必须要在对程序进行词法与语义分析、代码生成与优化等通常的编译过程之前进行,经过预处理的程序不再包含之前的预处理命令。

所有的预处理器指令都以#号开始,并且前面不可以出现除了空白字符以外的字符。预处理器指令不是C++指令,所以不需要以 结尾。所有的C++程序实例都有预处理器指令 #include,这个宏用于把头文件包含在源文件中。

预处理器指令是C++统一规定的,但不是C++本身的组成部分,因此编译器无法对其进行识别和编译。

#define预处理

#define预处理器指令用于创建符号常量,这个符号常量被称为宏。在预编译时,所有的宏都会被替换成相应的字符,

#define DEBUG       //DEBUG是宏
#define SQR(x)  x*x //求两个数的平方,注意陷阱
int a = 2;
cout<<SQR(a+1)<<endl;   //在预编译时会被替换为 2+1*2+1 ,结果是5而不是9
//若真的想求两个数的平方可以做如下改写
#define SQR(x)  ((x)*(x))
cout<<SQR(a+1)<<endl;   //此时会得到正确答案9

参数宏

C++可以用#define来定义一个带有参数的宏。

#define MIN(a,b)  (a<b?a:b)     

内联函数(inline)实现起来比带参数的宏更加方便与安全,因此带参数的宏已经较少使用了。

条件编译

一下指令可以是程序有选择的对部分源码进行编译

#ifdef DEBUG
//代码
#endif
//如果之前已经在上面定义了DEBUG,就会执行上面的代码部分,否则在预处理阶段就会直接跳过该部分,编译器也不会对其进行编译。

#和##运算符

###预处理器运算符在C++和C中都可用:#用于将宏的代替文本转换为用引号引起来的字符串,##用于连接两个参数。

#define STR(X)   #x
cout<<STR(hello world)<<endl;     //此时会直接输出hello world
#define PEW(a,b)  (int)(a##e##b)
cout<<PEW(2,2)<<endl;               //在预编译时被替换为2e2 ,最后结果是200

宏的优点

  • 提高程序的可读性也方便修改
  • 提高程序运行效率:宏在预处理时可以完成与函数调用相同的功能,同时又避免了函数的入栈与出栈操作,减小了系统开销,提高了运行效率。
  • 宏是由预处理器处理的,通过字符串操作能轻松的完成很多编译器无法实现的功能。(宏定义中的#与##
#include<iostream>
using namespace std;
#define FMALLY_CLASS(who)  class fmally_##who{};

#define ADD(arg_a,arg_b)  printf(#arg_a"+"#arg_b"=%d\n",arg_a+arg_b)
int main(){
    ADD(2,233);

    FMALLY_CLASS(mengziyue);
    fmally_mengziyue ziyue;

    FMALLY_CLASS(menglihua);
    fmally_menglihua lihua;
}

宏的缺点

  • 由于可能是直接嵌入的,代码量可能较多。
  • 嵌套定义肯能引起可读性较差,并且容易出错。
  • 对于带参数的宏来说,仅仅是字符的替换,且缺乏编译器的检测,可能称为错误的隐患。

参考链接:

  1. 菜鸟教程——C++预处理器
  2. 宏定义的优缺点

原文地址:https://www.cnblogs.com/ziyuemeng/p/12344945.html

时间: 2024-08-29 01:31:00

C++面试常见问题——01预处理与宏定义的相关文章

c 预处理的宏定义

概念 以“#”号开头的都是预处理命令 例如 #include <stdio.h>宏定义 宏定义无参数的宏名后不带参数# 表示这是一条预处理命令, define 为宏定义命令.“标识符”为所定义的宏名.“字符串”可以是常数,表达式.格式串等 举例: #define PI 3.1415926 作用: 就是用指定标识符PI来代替数3.1415926 对源程序作编译时, 将先由预处理程序进行宏代换, 即用3.1415926表达式去置换所有的宏名PI, 然后编译 #include <stdio.h

《黑马程序员》预处理指令(宏定义、条件编译、文件包含)(C语言)

宏定义的基本概念 ●  预处理指令都是以#开头 ●  预处理指令分为三种 1.宏定义 定义格式:#define  宏名   参数 2.条件编译 #if 条件语句     statement1; #elif 条件语句     statement2; #else     statement3; #endif       //条件编译结束必须加上此条语句,否则statement3以下的所有语句都将默认为不编译 3.文件包含 ●  预处理指令在代码翻译成0和1之前进行 ●  预处理指令的位置是可以写的

预处理指令--宏定义

预处理指令简介 •C语言在对源程序进行编译之前,会先对一些特殊的预处理指令作解释(比如之前使用的#include文件包含指令),产生一个新的源程序(这个过程称为编译预处理),之后再进行通常的编译 •为了区分预处理指令和一般的C语句,所有预处理指令都以符号“#”开头,并且结尾不用分号 •预处理指令可以出现在程序的任何位置,它的作用范围是从它出现的位置到文件尾.习惯上我们尽可能将预处理指令写在源程序开头,这种情况下,它的作用范围就是整个源程序文件 •C语言提供的预处理指令主要有:宏定义.文件包含.条

VC中预处理指令与宏定义详解

刚接触到MFC编程的人往往会被MFC 向导生成的各种宏定义和预处理指令所吓倒,但是预处理和宏定义又是C语言的一个强大工具.使用它们可以进行简单的源代码控制,版本控制,预警或者完成一些特殊的功能. 一个经典的例子 使用预处理与宏定义最经典的例子莫过于加在一个头文件中以避免头文件被两次编译.试想这种的情况,有一个文件headerfile.h 它被包含在headerfile1.h中,同时在headerfile2.h 中也被包含了,现在有一个CPP文件,implement.cpp 包含了headerfi

6、C_宏定义与预处理、函数与函数库

C语言预处理理论 由源码到可执行程序的过程 源码.c->(编译)->elf可执行程序 源码.c->(编译)->目标文件.o->(链接)->elf可执行程序 源码.c->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序 源码.c->(预处理)->预处理过的.i源文件->(编译)->汇编文件.S->(汇编)->目标文件.o->(链接)->elf可执行程序

unity平台的预处理(宏的定义)

在unity的跨平台中,我们常常会在各个平台游走,如安卓版,苹果版,PC版.在不同的平台上,我们要做不同的操作.然而我们可以使用unity的自带的宏定义来做平台的判断.Unity帮我们定义了例如以下平台预处理.(还有一些版本号的宏定义,这里没有写出来.) 我们使用#if #elif #endif进行宏命令的判断,unity会自己判断哪些条件成立,然后执行指定的代码.例子如下: 此外,我们还可以自己对宏命令进行定义:在edit-project settings-player中的设定栏可以添加属于自

黑马程序员----预处理指令(宏定义、条件编译、文件包含)

预处理指令共有三种: 宏定义: 条件编译: 文件包含: 一.预处理指令的执行时刻: 在代码翻译成0和1之前 二.预处理指令的特点: 1.预处理指令都是以#号开头: 2.预处理指令的位置可以随便写的: 3.预处理指令的作用域:从编写指令的哪一行代码开始,一直到文件结尾,或者遇到相应的#undef.... 三.宏定义(#define) 1.不带参数的宏定义: 例: #define COUNT 4      //  注意:这里没有分号 ....... #undef COUNT 注意: 1.宏名一般用大

预处理命令(宏定义,条件编译,头文件)

宏定义 <1>不带参数宏定义:#define PI 3.1415926 <2>带参数的宏定义: #define PI  3.1415926 #define S(r)  (PI*(r)*(r)) void main(){float  a=2,area;area=S(a); } 用宏可以得到几个结果: #define CIRCLE(R,L,S,V)  L=2*PI*(R);S=PI*(R)*(R);V=4.0/3.0*PI*(R)*(R)*(R) void main(){float r

C语言 预处理二(宏定义--#define)

//#define 宏定义(宏定义一般大写) //知识点一-->#define的作用域:从#define开始,从上往下,如果遇到#undef就到#undef处结束,如果没有就是作用于当前整个文件 #include<stdio.h> #include<stdlib.h> //知识点二-->宏定义作用 //宏定义作用1:起到替换作用,可以定义常量 #define X 10 //宏定义作用2:替换代码的任意部分(一般用于易语言,或者加密代码) #define 水乃万物之源 m