13.c/c++程序员面试宝典-宏定义
宏定义又称为宏代换、宏替换,简称宏。宏有时候并不是很受程序员的欢迎,但是它有一个最重要的作用就是可以自动产生代码。处理好宏定义很重要,使用宏定义可以防止出错,提高可移植性、可读性和方便性等。
面试题75 宏定义与操作符的区别**
分析:宏定义是c语言开始提供的3种预处理功能的其中一种。这3种预处理分别是:宏定义、文件包含和条件编译。
宏定义的语法格式为:#define<标识符><字符串>,其中的标识符就是所谓的符号常量,也称为“宏名”。预处理(预编译)工作也叫做宏展开,即将宏名替换为字符串。
单的宏定义将一个标识符定义为一个字符串,源程序中的该标识符均以指定的字符串来代替。预处理命令后通常不加分号。这并不是说所有的预处理命令后都不能有分号出现。由于宏定义只是用宏名对一个字符串进行简单的替换,因此如果在宏定义命令后加了分号,将会连同分号一起进行替换。
带参数的宏定义格式为:#define<宏名>(<参数表>)<宏体>,其中,<宏名>是一个标识符,<参数表>中的参数可以是一个,也可以是多个,视具体情况而定,当有多个参数的时候,每个参数之间用逗号分隔。<宏体>是被替换用的字符串,宏体中的字符串是由参数表中的各个参数组成的表达式。
宏定义与操作符的区别:宏定义是替换,不做计算,也不做表达式求解。另外宏定义的替换在编译前进行,所以它不占用内存。宏的展开不占运行时间,只占编译时间,而操作符则占运行时间。
【答案】宏定义时c++的预处理命令之一,它是一个替换操作,不做计算和表达式求解,不占用内存和编译时间。
面试题76 宏定义如何展开***
分析:具有宏调用的源程序被汇编时,汇编程序将对每个宏调用进行宏展开。宏展开实际上是用宏定义时设计的宏体去代替宏指令名,并且用实际参数一一取代形式参数。
一个宏展开的示例代码如下,原始的代码macro.cpp:
#include<iostream>
#include<cstdio>
#define TO_STRING_MACRO(x) #x
#define A_TESTING_MACRO(n) printf("a testing macro with a int argument n=%d!\n",n)
#define SHOW_MACRO_CONTENT(m) TO_STRING_MACRO(m)
//定义了3个不同的宏
using namespace std;
int main()
{
int a=10;
int *b=&a;
cout<<TO_STRING_MACRO(a)<<endl;
cout<<TO_STRING_MACRO(10+20)<<endl;
cout<<A_TESTING_MACRO(10+20)<<endl;
cout<<TO_STRING_MACRO(A_TESTING_MACRO(a))<<endl;
cout<<SHOW_MACRO_CONTENT(A_TESTING_MACRO(a))<<endl;
cout<<SHOW_MACRO_CONTENT(A_TESTING_MACRO(*b))<<endl;
*b=100;
A_TESTING_MACRO(*b); //使用宏
return 0;
}
以上代码在宏展开后的代码macro.i如下:
using namespace std;
int main()
{
int a=10;
int *b=&a;
cout<<"a"<<endl;
cout<<"10+20"<<endl;
cout<<printf("a testing macro with a int argument n=d!\n",10+20)<<endl;
cout<<"A_TESTING_MACRO(a)"<<endl;
cout<<"printf(\"a testing macro with a int argument n=d!\\n\",a)"<<endl;
cout<<"printf(\"a testing macro with a int argument n=d!\\n\",*b)"<<endl;
*b=100;
printf("a testing macro with a int argument n=d!\n",*b);
return 0;
}
【答案】宏展开是用宏定义时设计的宏体去代替宏指令名,并且用实际参数一一取代形式参数。