在C中,习惯使用#define来定义常量,例如:
#define LIMIT 100
实际上,这种方法只是在预编译时进行字符置换,把程序中出现的标识符LIMIT全部置换成100。在预编译之后,程序中不再有LIMIT这个标识符。LIMIT不是变量,没有数据类型,不占用存储单元,而且容易出错。让我们看一个代码:
#include<iostream>
using namespace std;
#define N 100
int main() {
int n = N;
cout << n << endl;
return 0;
}
在执行的过程中,
我们能够发现计算机并没有给N分配地址,n=N这个过程中是直接把100(64h)直接给了n,这就说明不占用存储单元的,再让我们看一个题:
#include<iostream>
using namespace std;
#define add(a,b) a+b
int main() {
int a = 2, b = 3;
cout <<add(a,b)*10 << endl;
return 0;
}
现在让我们看这个程序的结果,我们要知道define是在预处理阶段进行字符串替换,那么这个add(a,b)*10就会变成2+3*10,并不是先就行a+b的运算,我们看结果:
因此在C++中,提供了一种更灵活、更安全的方式来定义常量,即使用const修饰符来定义常量,例如:
const int N=100;
这个常量N是有类型的,占用存储空间,有地址,可以用指针指向,但不能修改。
让我们具体看一下两者的区别:
我们可以发现define的确没有分配空间。再让我们试一试:
#include<iostream>
using namespace std;
int main() {
int a = 2, b = 3;
const int t = a + b;
cout << t*10 << endl;
return 0;
}
结果展示:
const与指针:
const也可以与指针一起使用,可归纳为三种:指向常量的指针、常指针和指向常量的常指针。
(1)指向常量的指针是指一个指向常量的指针变量,例如:
const char* name ="HXD";
这个语句的含义是定义一个名为name的指针变量,它指向一个字符型常量,初始化name为指向字符串"HXD"。由于使用了const,不允许改变指针所指地址中的变量,因此不能:
name[1]='Y'; ///这是错误的
但是由于name是一个指向常量的普通指针变量,不是常指针,因此可以改变name所指的地址,例如:
name="WY"; ///合法
该语句赋给了指针另一个字符串的地址,即改变了name的值。
(2)常指针是指把指针所指的地址为常量,而不是它指向的对象声明为常量,例如:
char* const name="HXD";
这个语句是声明一个名为name的指针变量,该指针是指向字符型数据的常指针,用"HXD"的地址初始化该指针。
创建一个常指针,就是创建了一个不能移动的指针,即不能修改这个指针指向的地址,但对它所指地址中的内容没有要求,因此我们可以修改里面的内容,但不能修改指针指向的地址。
name[1]="Y";///合法
name="WY";///不合法
(3)指向常量的常指针,就是常指针和指向常量的指针的结合,指向常量的常指针指针指向的地址不能改,指向的内容也不能改。例如:
const char * const name="HXD";
说明:
- 如果使用const定义一个整形常量,关键字int 可以省略。
- 常量一旦被建立,在程序的任何地方都不能被修改。
- 与#define定义的常量不同,const定义的常量可以有自己的数据类型。
- 函数的形参也可以用const说明,用于保证形参在该参数内部不被修改,大多数C++编辑器能够对const参数的函数就行更好的代码优化。