C++ 第一课:预处理命令

#,##

和 ## 操作符是和#define宏使用的. 使用# 使在#后的首个参数返回为一个带引号的字符串. 例如, 命令

#define to_string( s ) # s

将会使编译器把以下命令

cout << to_string( Hello World! ) << endl;

理解为

cout << "Hello World!" << endl;

使用##连结##前后的内容. 例如, 命令

#define concatenate( x, y ) x ## y
    ...
    int xy = 10;
    ...

将会使编译器把

cout << concatenate( x, y ) << endl;

解释为

cout << xy << endl;

理所当然,将会在标准输出处显示'10'.


#define

语法:

#define macro-name replacement-string

define命令用于把指定的字符串替换文件中的宏名称 . 也就是说, #define使编译器把文件中每一个macro-name替换为replacement-string. 替换的字符串结束于行末. 这里是一个经典的#define应用 (至少是在C中):

#define TRUE 1
    #define FALSE 0
    ...
    int done = 0;
    while( done != TRUE ) {
       ...
    }

define命令的另外一个功能就是替换参数,使它 假冒创建函数一样使用. 如下的代码:

#define absolute_value( x ) ( ((x) < 0) ? -(x) : (x) )
    ...
    int x = -1;
    while( absolute_value( x ) ) {
       ...
    }

当使用复杂的宏时,最好使用额外的圆括号. 注意在以上的例子中, 变量"x"总是出现在它自己的括号中. 这样, 它就可以在和0比较,或变成负值(乘以-1)前计算值. 同样的, 整个宏也被括号围绕, 以防止和其它代码混淆. 如果你不注意的话, 你可能会被编译器曲解你的代码.


#error

语法:

#error message

error命令可以简单的使编译器在发生错误时停止. 当遇到一个#error时,编译器会自动输出行号而无论message的内容. 本命令大多是用于调试.


#if, #ifdef, #ifndef, #else, #elif, #endif

这些命令让编译器进行简单的逻辑控制. 当一个文件被编译时, 你可以使用这些命令使某些行保留或者是去处.

#if expression

如果表达式(expression)的值是"真"(true),那么紧随该命令的代码将会被编译.

#ifdef macro

如果"macro"已经在一个#define声明中定义了, 那么紧随该命令的代码将会被编译.

#ifndef macro

如果"macro"未在一个#define声明中定义, 那么紧随命令的代码将会被编译.

一些小边注: 命令#elif是"elseif"的一种缩写,并且他可以想你所意愿的一样工作. 你也可以在一个#if后插入一个"defined"或者"!defined"以获得更多的功能.

这里是一部分例子:

#ifdef DEBUG
      cout << "This is the test version, i=" << i << endl;
    #else
      cout << "This is the production version!" << endl;
    #endif

你应该注意到第二个例子比在你的代码中插入多个"cout"进行调试的方法更简单.


#include

语法:

#include <filename>
  #include "filename"

本命令包含一个文件并在当前位置插入. 两种语法的主要不同之处是在于,如果filename括在尖括号中,那么编译器不知道如何搜索它. 如果它括在引号中, 那么编译器可以简单的搜索到文件. 两种搜索的方式是由编译器决定的,一般尖括号意味着在标准库目录中搜索, 引号就表示在当前目录中搜索. The spiffy new 整洁的新C++ #include目录不需要直接映射到filenames, 至少对于标准库是这样. 这就是你有时能够成功编译以下命令的原因

#include <iostream>

#line

语法:

#line line_number "filename"

line命令是用于更改__LINE__ 和 FILE__变量的值. 文件名是可选的. __LINEFILE 变量描述被读取的当前文件和行. 命令

#line 10 "main.cpp"

更改行号为10,当前文件改为"main.cpp".


#pragma

pragma命令可以让编程者让编译器执行某些事. 因为#pragma命令的执行很特殊,不同的编译器使用有所不同. 一个选项可以跟踪程序的执行.


#undef

undef命令取消一个先前已定义的宏变量, 譬如一个用#define定义的变量.


预定义变量

语法:

__LINE__
  __FILE__
  __DATE__
  __TIME__
  _cplusplus
  __STDC__

下列参数在不同的编译器可能会有所不同, 但是一般是可用的:

  • LINEFILE 变量表示正在处理的当前行和当前文件.
  • DATE 变量表示当前日期,格式为month/day/year(月/日/年).
  • TIME 变量描述当前的时间,格式为hour:minute:second(时:分:秒).
  • _cplusplus 变量只在编译一个C++程序时定义.
  • STDC 变量在编译一个C程序时定义,编译C++时也有可能定义.

测试例子:

#define studyDefine_string(s) #s;  //使用#表示将传入的任何内容都当作字符串类型并返回。
#define studyDefine_concatenate(x,y) x##y;//使用##表示将两个值拼接成新的变量。
#define studyDefine_absolute(x)((x)<0?-1*(x):(x));//使变量"x"总是出现在它自己的括号中. 这样, 它就可以在和0比较,或变成负值(乘以-1)前计算值. 同样的, 整个宏也被括号围绕, 以防止和其它代码混淆.
#include <iostream>

using namespace std;

int main()
{
    /*宏定义例子,语法: #define macro-name replacement-string*/
    //demo 1 
    std::string s = studyDefine_string(my name is sindrol);
    cout << "n" << (s == "my name is sindrol");//结果返回 1 或者 true.
    //demo 2
    int ab = 3;
    cout << "n" << studyDefine_concatenate("a", "b"); //结果返回字符串"ab"。
    cout << "n" << studyDefine_concatenate(a, b); //结果返回ab变量的值,将返回3。
    //demo 3
    cout << "n" << studyDefine_absolute(1 - 5); //结果返回ab变量的值,将返回3。

    /*预定义变量例子*/
    cout << "nCurrent line:" << __LINE__; //变量表示正在处理的当前行
    cout << "nCurrent file:" << __FILE__; //变量表示当前文件. 
    cout << "nCurrent date:" << __DATE__; //变量表示当前日期,格式为month/day/year(月/日/年). 
    cout << "nCurrent time:" << __TIME__; //变量描述当前的时间,格式为hour:minute:second(时:分:秒).
    cout << "nCurrent is c++:" << __cplusplus; //变量只在编译一个C++程序时定义. 
    cout << "n";
}

输出结果:

C++ 第一课:预处理命令

原文链接: https://www.cnblogs.com/songxingzhu/p/5945748.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/241835

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午9:55
下一篇 2023年2月13日 下午9:56

相关推荐