#define用法

1. 定义简单的常数:定义常量,便于修改

#define N 1000

2. 定义简单的函数:注意多使用括号

define可以像函数那样接受一些参数,如下:

#define max(x,y) (x)>(y)?(x):(y)

这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。但是这样做的话存在隐患,例子如下:

#define Add(a,b) a+b;

在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了

c*a + b*d

const常量与define宏定义的区别

编译器处理方式不同:

define宏是在预处理阶段展开。const常量是编译运行阶段使用。

类型和安全检查不同:

define宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查。

存储方式不同:

define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。

const常量会在内存中分配(可以是堆中也可以是栈中)。

C++的const比C语言#define更好的原因?

首先,它能够明确指定类型,有类型检查功能。

其次,可以使用C++的作用域规则将定义限制在特定的函数或文件中。

第三,可以将const用于更复杂的类型,比如数组和结构。

C语言中也有const,其与C++中const的区别是:一是作用域规则不同;另一个是,在C++中可以用const值来声明数组长度。C编译器不能把const看成一个编译期间的常量,即C编译器不知道它在编译时的值。

===========================================================

对宏定义的使用要非常小心,特别要注意两个问题:

(1)谨慎地将宏定义中的“参数”和整个宏用括弧括起来。如定义最小宏:#define MIN(A,B) ( (A) <= (B) ? (A) : (B) ) ,所以,严格地讲,下述解答:

#define MIN(A,B) (A) <= (B) ? (A) : (B) ////// #define MIN(A,B) (A <= B ? A : B ) 都应判0分;

(2)防止宏的副作用。对MIN(*p++, b)的作用结果是:((*p++) <= (b) ? (*p++) : (*p++)) ,这个表达式会产生副作用,指针p会作三次++自增操作。

typedef用法

简化复杂的类型声明

简化复杂的类型声明,或给已有类型起一含义明确的别名;如:

typedef bool (*FuncPointer)(int, double); //声明了一个返回 bool 类型并带有两个(int和double)形参的函数的指针类型FuncPointer

FuncPointer pFunc; //声明了一个FuncPointer类型的函数指针对象pFunc

定义与平台无关的类型

定义与平台无关的类型,屏蔽不同平台的类型差异化;如:

用typedef来定义与平台无关的类型。

比如定义一个叫 REAL 的浮点类型,在目标平台一上,让它表示最高精度的类型为:

typedef long double REAL;

在不支持 long double 的平台二上,改为:

typedef double REAL;

在连 double 都不支持的平台三上,改为:

typedef float REAL;

也就是说,当跨平台时,只要改下 typedef 本身就行,不用对其他源码做任何修改。

标准库就广泛使用了这个技巧,比如size_t。另外,因为typedef是定义了一种类型的新别名,不是简单的字符串替换,所以它比宏来得稳健。

与struct的结合使用

在C++中,struct与class的作用相同,就是默认的访问权限不同,struct默认为public,而class默认为private的。

但是在C语言中,struct的定义和声明要用typedef。如果没有typedef就必须用struct Person person;来声明

typedef与#define的区别

执行时间不同

关键字typedef在编译阶段有效,由于是在编译阶段,因此typedef有类型检查的功能。

#define则是宏定义,发生在预处理阶段,也就是编译之前,它只进行简单而机械的字符串替换,而不进行任何检查。

功能有差异

typedef用来定义类型的别名,定义与平台无关的数据类型,与struct的结合使用等。

#define不只是可以为类型取别名,还可以定义常量、变量、编译开关等。

作用域不同

#define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用。

而typedef有自己的作用域。

参考:http://blog.csdn.net/luoweifu/article/details/41630195

#define const typedef的更多相关文章

  1. C++ —— 非类中使用const定义常量的初始化,以及#define和typedef的区别

    总结一下在非类中使用const关键字定义常量时的初始化问题,亲测VS2015.顺便记录#define宏和typedef的区别. 1 首先对const声明的常量的初始化做简单小结: , w2 = , w ...

  2. #define与typedef

    #define(宏定义)只是简单的字符串代换(原地扩展),它本身并不在编译过程中进行,而是在这之前(预处理过程)就已经完成了. typedef是为了增加可读性而为标识符另起的新名称(仅仅只是个别名), ...

  3. 【C语言笔记】#define与typedef的区别

    1.#define define是预处理指令,在编译时不进行任何检查,只进行简单的替换 宏定义的一般形式为: #define 宏名 字符串 这里所说的字符串是一般意义上的字符序列,不要和C语言中的字符 ...

  4. define和typedef的区别

    define和typedef的区别 define是单纯的字符替换,typedef是重新定义了新的类型 #include <stdio.h> #define CHAR1 char* type ...

  5. c语言define和typedef区别和使用

    define完全可以理解替换,typedef代表别名.听着差不多的意思,那2者区别在哪? 先来个简单例子查看基本使用. //define和typedef区别 #define DB double //替 ...

  6. #define 与 typedef

    1.#define:预编译指令,在预编译的时候,进行文本替换. 2.typedef:编译时处理,为类型取一个别名. 3.#define与typedef的顺序是相反的,记住typedef就行了.type ...

  7. void指针意义、Const、volatile、#define、typedef、接续符

    1.C语言规定只有相同类型的指针才可以相互赋值. Void*指针作为左值用于接收任意类型的指针, void*指针作为右值赋给其他指针时需要强制类型转换. 2.在C语言中Const修饰的变量是只读的,本 ...

  8. #define 和typedef的区别

    typedef和define的详细区别 2011-04-19 15:11 firnow firnow 字号:T | T 对于都可以用来给对象取一个别名的Typedef和define来说,是有区别的.本 ...

  9. define与typedef 区别

    1)     #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错.例如:#define PI 3. ...

随机推荐

  1. Java基础-字符串连接运算符String link operator

    Java基础-字符串连接运算符String link operator 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 字符串链接运算符是通过“+”进行拼接的. 一.使用“+”进行字 ...

  2. Shell记录-Shell命令(文件权限)

    chmod命令用于改变linux系统文件或目录的访问权限.用它控制文件或目录的访问权限.该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1. 命令格式 ch ...

  3. HTML面试基础问题

    1.Doctype作用?严格模式与混杂模式如何区分?它们有何意义?   1)<!DICTYPE>声明位于文档中的最前面,处于<html>标签之前,告诉浏览器的解析器,用什么文档 ...

  4. 来自一个Backbone的Hello,World!

    MVC写这种程序真是够大材小用的了,可没想到居然这么抽象! // 这是一个管理者视图/控制/模型 的全局类 var App = { Models: {}, Views: {}, Controllers ...

  5. spring框架学习(六)AOP事务及spring管理事务方式之Template模板

    概念 1.事务 1)事务特性:ACID 原子性 :强调事务的不可分割. 一致性 :事务的执行的前后数据的完整性保持一致. 隔离性 :一个事务执行的过程中,不应该受到其他事务的干扰. 持久性 :事务一旦 ...

  6. 超厉害的CSS3图片破碎爆炸效果!

    var fx  = { buffer : function(obj, cur, target, fnDo, fnEnd, fs){ if(!fs)fs=6; var now={}; var x=0; ...

  7. .NET 下第一次接触Redis数据库

    关于Redis 1.简介 Redis是著名的NOSQL(Not Only SQL)数据库,是键值对结构.(我只用过键值对结构的) 他为存储键值对做了优化,在大型网站中应用广泛.Redis提供了数据的自 ...

  8. backup服务器之rsync服务

    backup服务器之rsync服务   rsync是开源的.快速的.多功能的可实现全量及增量的本地或远程数据同步备份的优秀工具.它拥有scp.cp的全量复制功能,同时比scp.cp命令更优秀.更强大. ...

  9. 87.在ModelSim中添加Xilinx ISE仿真库

    在ModelSim中添加Xilinx ISE仿真库 说明: l ModelSim一定要安装在不带空格的目录下,即不要安装在“Program Files”目录下.如作者是安装在D:\softwares\ ...

  10. gcc编译选项【转】

    转自:https://blog.csdn.net/rheostat/article/details/19811407 常用选项 -E:只进行预处理,不编译-S:只编译,不汇编-c:只编译.汇编,不链接 ...