#define宏定义详解

来源:互联网 发布:linux改变用户权限 编辑:程序博客网 时间:2024/06/06 02:39

#define宏定义

1.常规用法无参宏

#define PI 3.1415926

#define EN 1e5//定义指数1*10e5;

cout<<PI<<endl;//默认位有效数字3.14159

2.使用参数

(1)不使用括号

#define SQUARE(x)x*x

cout<<SQUARE(2)<<endl;//4

cout<<SQUARE(2+3)<<endl;//2+3*2+3=11

int x=6;

cout<<SQUARE(x+1)<<endl;//6+1*6+1=13

cout<<SQUARE(++x)<<endl;//7*8=56

(2)使用括号 很重要

#defineSQUARE(x) ((x)*(x))

cout<<SQUARE(2)<<endl;//4

cout<<SQUARE(2+3)<<endl;//(2+3)*(2+3)=25

int x=6;

cout<<SQUARE(x+1)<<endl;//49

cout<<SQUARE(++x)<<endl;//7*8=56

解决办法最简单的是:不要在有参宏用使用到++“–”,否则后一个的值会在前一个基础上+1或取负值。

(3)定义比较大的数据,如一年有多少秒?

#include <stdio.h>

#define SECONDS_PER_YEAR  60*60*24*365UL

int main(void)

{

    unsigned long int  a =SECONDS_PER_YEAR;

    cout<<a<<endl;

    return 0;

}

3.防止头文件被重复包含

#ifndef cTest_Header_h

#define cTest_Header_h

//头文件内容

#endif

4. #define #typedef的区别

1)修饰指针操作时,作用不同

#define INT1 int *

typedef int * INT2;

 

int main()

{

    int m=1,n=2;

    INT1 a1, b1;

    INT2 a2, b2;

    b1 =&m;//no  

    b2 =&n;//ok

    return 0;

}

因为 INT1 a1, b1; 被宏代换后为: int * a1, b1;即定义的是一个指向int型变量的指针 a1 和一个int型的变量b1.而INT2 a2, b2;表示定义的是两个变量a2和b2,这两个变量的类型都是INT2的,也就是int *的,所以两个都是指向int型变量的指针。

所以两者区别在于,宏定义只是简单的字符串代换,不做正确性检查,在预处理阶段完成。而typedef不是简单的字符串代换,而是在自己的作用域内给一个已经存在的类型一个别名,类型的别名可以具有类型定义说明的功能,在编译阶段完成的。

 

2)作用域不同

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

【例2.3.1没有作用域的限制,只要是之前预定义过就可以

void func1()  

  {  

       #define HW "HelloWorld";  

  }  

     

   void func2()  

   {  

       string str = HW;  

       cout << str << endl;  

 }  

【例2.3.2typedef有自己的作用域

   void func1()  

   {  

       typedef unsigned int UINT;  

   }  

     

   void func2()  

   {  

       UINT uValue = 5;//error C2065: 'UINT' : undeclared identifier  

   }  

在类中用typedef定义的类型别名还具有相应的访问权限,【例2.3.4】:

   class A  

   {  

       typedef unsigned int UINT;  

       UINT valueA;  

       A() : valueA(0){}  

   };  

     

   void func3()  

   {  

     A::UINT i = 1;  

     // error C2248: 'A::UINT' : cannot access private typedef declared in class 'A'  

 }  

而给UINT加上public访问权限后,则可编译通过。

【例2.3.5】:

   class A  

   {  

   public:  

       typedef unsigned int UINT;  

       UINT valueA;  

       A() : valueA(0){}  

   };  

     

   void func3()  

 {  

     A::UINT i = 1;  

     cout << i << endl;  

 }  

注意:宏不是语句,结尾不需要加“;”,否则会被替换进程序中。

      如果宏不止一行,则在结尾加反斜线“\”符号。

#define HELLO "hello \

the world"

 

5. #define #const的区别

1)编译器处理方式

define-在预处理阶段进行替换;

const—在编译时确定其值;

2)类型检查

define-无类型,不进行类型安全检查,可能产生意想不到的错误;

const—有数据类型,编译时会进行类型检查;

3)内存空间

define—不分配内存,给出的是立即数,有多少次使用就有多少次替换,在内存中就有多少拷贝,内存消耗大;

const—在静态存储区中分配内存,在程序运行过程中内存中只有一个拷贝;

4

宏定义的作用范围仅限于当前文件;

默认状态下,const对象只在文件内有效,当多个文件中出现了同名的const变量时,等同于在不同文件中分别定义了独立的变量。如果想在多个文件之间共享const对象,必须在变量定义之前添加extern关键字(在声明和定义时都要加)。

 

注意:C++程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。