宏和被const修饰的常量区别
1 引出const修饰的常量
知识点:
- 1、 c++,被const修饰的变量一般称为常量,而被const修改的常量还具有宏替换的作用。
- 其中宏替换就是在编译阶段,所有使用const常量的位置,用常量的值代替该常量(除&常量外)
- 2、c,const修饰的变量不能称为常量,只能称为不能修改的变量。
1.1 实例1:观察a和*pa的值
#if 0
int main(){
const int a = 10;
int* pa = (int*) &a;//&a结果的类型为const int*,表明该地址指向的空间中的内容不允许被更改。
*pa = 100;
printf("%d\n",a);//10
cout << a << endl;//10 ---在编译阶段,所有使用const常量的位置,用常量的值代替该常量(除&常量)
cout << *pa << endl;//100
}
#endif
1.2 实例2:观察a,b,MAX,*pa值
- a:c++中const修饰的常量
- b:变量
- MAX:宏
- *pa:指针
- *&a:a
#if 0
#define MAX 10 //宏
int main()
{
const int a = 10; //c++中const修饰的常量
int* pa = (int*)&a; // &a结果的类型 const int*--->表明该地址指向的空间中内容不允许被修改
*pa = 100 //指针
int b = 20; //变量b
//观察a,b,MAX反汇编,发现a和MAX没有进行内存访问,直接进行压栈,而b要先取变量的值再压栈
printf("%d\n", MAX); // *&a<==>a
printf("%d\n", a);
printf("%d\n", b);
printf("%d\n", *&a); //*&a结果就是a本身--->既然是a本身--->替换为10
cout << a << endl; //类似cout << 10 << endl;
cout << *pa << endl;
return 0;
}
#endif
注意:内存中a的值已经改为100了,但是a变量没有访问内存地址,所以即使内存数据改变,输出的数据也是没变的, *pa结果为100,因为其访问了内存空间。
2 C++中,使用const修饰的常量来取代C语言中的宏
2.1 宏
#if 0
#define MAX 10
int main()
{
// 宏在预处理阶段会被宏体来进行替换
int a = 100;
a = MAX; // 该条语句在预处理阶段已经被修改为:a = 10;
return 0;
}
#endif
2.2 const修饰的常量
#if 0
int main()
{
const int a = 10;
int* pa = (int*)&a;
printf("%d\n", a);
printf("%d\n", *pa);
return 0;
}
#endif
2.3 证明在c++中const修饰的变量为常量,不能被修改
#if 0
int main()
{
const int a = 10;
int array[a];
//a = 10;
return 0;
}
#endif在这里插入代码片
2.4 c++中,const修饰的常量相比于宏的优势
#if 0
// 宏的替换发生在预处理阶段----但是宏不会
// const修饰的常量替换发生在编译阶段---->而const修饰的常量是有类型的,因此会参与类型检测
// 宏不会进行类型检测,因为其在预处理阶段已经被替换
#define PI "3.14"
// pi的类型是double类型的 "3.14"是字符串类型 编译阶段知道类型不匹配而报错
const double pi = "3.14";
// 一般情况下:在C++中 更建议使用const修饰的常量来取代C语言中的宏
// 因为:const修饰的内容已经是常量了,而且会参与类型检测,比宏常量使用起来更安全
int main()
{
int r = 2;
double s = PI * r * r; // 宏替换:s = "3.14" * r * r;
double s = pi * r * r;
return 0;
}
#endif
2.5 宏的缺陷
#if 0
#define MAX(a, b) (a > b ? a : b)
int main()
{
int a = 10;
int b = 20;
cout << MAX(++b, a) << endl; //该条语句在预处理阶段被替换为: cout <<(a > b ? a : b)<< endl;
cout << MAX("hello", 100) << endl;
return 0;
}
#endif
解决宏的缺陷:
解决了宏的缺陷:结果为21
#if 0
inline int Max(int left, int right)
{
return left > right ? left : right;
}
int main()
{
int a = 10;
int b = 20;
int c = 0;
c = Max(++b, a);
cout << c << endl;
return 0;
}
#endif
往期链接:
cpp_4 引用
cpp_3 函数重载/传址调用/引用
cpp_2 输入输出/函数/重载
cpp_1 命名空间/输入输出