为什么要打扰预处理程序指令呢?

Zai*_*aid 21 c++ c-preprocessor

这个问题可能看起来很基本,但是来自工程(非计算机科学)背景,我不确定#某些C++代码中的代码片段是什么.

快速搜索使我得到了关于预处理器指令的简明扼要的cplusplus教程页面.

但是为什么要干扰预处理器指令的概念呢?是否不可能编写可以为常量赋值,定义子程序/函数/宏和处理错误的等效代码?

我想我最终想知道什么时候使用这样的预处理器指令是好的做法,当它不是时.

RC.*_*RC. 25

当您需要执行实际应用程序范围之外的操作时,可以使用预处理程序指令.例如,您将看到完成预处理以包含或不包含基于构建可执行文件的体系结构的代码.例如:

#ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
#include <windows.h>
#else
#include <unistd.h>
#endif
Run Code Online (Sandbox Code Playgroud)

预处理程序指令也用于保护包含,以便类/函数等不会被定义多次.

#ifndef MY_CLASS_6C1147A1_BE88_46d8_A713_64973C9A2DB7_H_
#define MY_CLASS_6C1147A1_BE88_46d8_A713_64973C9A2DB7_H_
    class MyClass {
    ....
    };
#endif
Run Code Online (Sandbox Code Playgroud)

另一个用途是在代码和库中嵌入版本控制.

在Makefile中你有以下几点:

-D MY_APP_VERSION=4.5.1
Run Code Online (Sandbox Code Playgroud)

在你的代码中

cout << "My application name version: " << MY_APP_VERSION << endl;
Run Code Online (Sandbox Code Playgroud)

  • `/ ^ _ [AZ] /`也是保留的,`/ __ /`也是如此.所以你不能拥有_MY_CLASS_H.在你提问之前,`/ ^ _ [az] /`在全局命名空间中保留,因此它也不适合用作宏.这就是为什么`#pragma once`非常有吸引力 - 从不介意编译速度,它可以节省你为包含守卫选择一个名字. (2认同)

bma*_*ies 9

答案1:条件代码必须根据其工作的计算机类型而变化.

答案2:启用和禁用编译时看到的语言扩展和兼容性功能.

预处理器来自C,那里有许多你无法表达的东西.好的C++代码发现使用它的理由比C代码少,但遗憾的是它没有用处.

  • 此外,由于C++具有"内联",因此不应在C++中使用#define宏来尝试速度.另请参见http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Preprocessor_Macros (2认同)

Dan*_*den 7

因为预处理程序指令在构建时执行,而您编写的代码将在运行时执行.因此,预处理程序指令有效地使您能够以编程方式修改源代码.

注意,C预处理器对于这种事情来说是一个相当粗糙的机制; C++的模板系统为编译时构造代码提供了更强大的框架.其他语言具有更强大的元编程功能(例如,Lisp的宏系统).

  • 稍微挑剔:预编译器指令在编译时执行. (3认同)

Mat*_*att 6

在编译代码之前进行预处理.它适用于以下情况

#ifdef WIN32
#include <something.h>
#elseif LINUX
#include <somethingelse.h>
#endif
Run Code Online (Sandbox Code Playgroud)

显然包括你想在编译时完成的头文件而不是运行时.我们不能用变量来做这件事.

另一方面.使用C++是一种很好的做法,并且极力鼓励替换常量表达式,如下例所示

#define PI 3.141592654
with
const double PI=3.141592654;
Run Code Online (Sandbox Code Playgroud)

原因是您获得了正确的类型转换和数据类型处理.

#define MAX(x,y) (x) > (y) ? (x) : (y)
Run Code Online (Sandbox Code Playgroud)

不是很好,因为你可以写

int i = 5
int max = MAX(i++, 6);
Run Code Online (Sandbox Code Playgroud)

预处理器将替换为:

int max = (i++) > (6) ? (i++) : (6);
Run Code Online (Sandbox Code Playgroud)

这显然不会给出预期的结果.

相反,MAX应该是一个函数(不是宏).如果它是一个函数,它也可以在参数中提供类型.

我已经看到预处理器用于各种有趣的事情.像语言关键字声明.在这种情况下,它有助于提高可读性.

简而言之,将预处理器用于必须在编译类型中发生的事情,例如条件包含指令.避免将其用于常量.避免使用宏,而是尽可能使用函数.


ale*_*xkr 5

它最常用于两件没有它的情况下难以组织的东西:

  1. 包括警卫.
  2. 不同平台的不同代码段.