#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.2】而typedef有自己的作用域
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常量完全取代宏常量。