C++宏的作用与C#里宏的代替(一)

来源:互联网 发布:阿里云域名未备案 编辑:程序博客网 时间:2024/06/05 16:30

研究生前两年做过不少项目,以前一直觉得自己水平还可以,然而今天去参加了腾讯的面试,问的问题都很基础,然而竟没有一个完完全全的回答上来,感觉自己好菜,唉,回来好好总结,为了offer继续努力。

C++中的宏有什么作用,由于在C#中取消了C++中的宏,那么C++中宏的那部分作用在C#中是如何实现的呢?

一、C++中宏的作用

1、使用宏定义常量

 示例:#define  MAXSIZE 200

宏定义不是C/C++严格意义上的语句,所以定义后不加分号,使用define后的标示符来代替常量,当我们需要在程序中多次使用200这个值,比如定义数组的长度等,并且可能在以后对该值做出修改时,

使用宏定义,我们仅需要改变宏定义所表示的值即可,而不需要到程序中去寻找哪些地方使用了200。

需要提到的是,在C++中 const也可以用来定义常量。那么const与宏定义的区别在哪儿呢?

(1)const定义常量是需要指出类型,而宏定义则不必:

#define  MAXSIZE 200 //宏定义;

const int MAXSIZE=200;//const定义;

两种方法可以实现相同的功能,即用MAXSIZE来代替常量200;

由于const在定义时需要指出类型,因此,

编译器会对const定义的常量进行静态类型安全检查,

而#define宏定义则是简单的替换,不会进行安全检查,并且可能会产生边界效应,

带来想不到的后果。

例如:#define N 100

#define M N+300

如果在程序中使用M*N,则结果会是100+300*100;

原因就在于定义M的时候是N+300而不是(M+300);

宏定义只是做简单的替换。

而const定义需要检查类型安全,如定义const float PI=3.141592653;

而实际得到的值却是PI=3.141593;这是由float的数据的长度所决定的。

(2)、当定义局部变量时,const所定义的变量的作用域,

仅限于const定义所在的函数段;

而使用宏定义#define,其作用域不仅限于定义所在的函数段,

而是从定义点到整个程序的结束。

(3)、const定义的常量在编译时会为该变量分配存储空间,而宏定义是在预编译时编译,

不分配存储空间(对于C语言,编译器会为const常量分配存储空间,但对于C++,

有些书上说编译器不会为const常量分配存储空间,而只是将其放在符号表中,

还有的说对于基本类型,不分配存储空间ADT等较大的对象要分配存储空间)

有些集成化的工具可以对const进行调试,但却不能对宏定义进行调试

(具体用什么工具,怎么调试我就不太清楚了)。


2、防止多重包含

预处理器变量:在编写头文件时,我们需要引入一些额外的预处理设置,

预处理器允许我们自定义变量。预处理器变量的名字在程序中必须是唯一的。

任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量,而避免冲突,

预处理器变量一般使用大写的英文字符表示。预处理器变量有两种状态:

已定义和未定义。#define接收一个标识符,并定义该标识符为预处理器变量。

#ifndef检测指定的预处理器变量是否定义,如果未定义,则执行跟在其后的所有指令,

直到出现#endif。

在头文件的开头加上 如下代码

#ifndef  _HEAD_H_ //如果没有定义_HEAD_H_

#define _HEAD_H_//定义_HEAD_H_

然后在头文件的结束出加上#endif就可以避免该头文件被多次引用。


需要注意的是,防止头文件被重引用,还可以使用#pragma once来解决。

使用#pragma once 后,在编译时,编译器只对该文件编译一次;

与宏定义相比,#pragma once具有更快的速度和更高的效率,但是需要指出的是,

#pragma并不是所有的编译器都支持,可移植性较差。


有点晚了,明天继续...

0 0
原创粉丝点击