1.const在C++中的行为
在C++中,const常量的内存分配取决于它的使用方式。如果它只是用于替换一个常量值,那么编译器可能不会为它分配独立的内存空间,而是直接将常量值"折叠"进代码中,类似于#define的效果。但如果你对它做一些特殊操作,比如取地址或者定义为extern,那么编译器会为它分配内存空间。
示例 1:普通const不分配内存
#include <iostream>
const int value = 42; // 没有分配内存,编译器将其值内嵌到代码中
int main() {
std::cout << value << std::endl; // 直接使用常量,可能不分配内存
return 0;
}
编译器可以选择不为 value 分配内存,而是在使用它的地方直接替换为 42。
示例 2:取地址时分配内存
#include <iostream>
const int value = 42;
int main() {
const int* p = &value; // 取地址,编译器必须为它分配内存
std::cout << "Address of value: " << p << std::endl;
std::cout << "Value: " << *p << std::endl;
return 0;
}
由于我们取了 value 的地址,编译器必须为 value 分配内存空间。
示例 3:extern的const
#include <iostream>
extern const int value; // 声明一个外部的const
int main() {
std::cout << value << std::endl;
return 0;
}
如果一个const变量被声明为extern,它的定义就需要出现在另一个文件中,并且编译器会为它分配内存。
2.const在C中的行为
在C语言中,const总是分配内存,无论它是如何使用的。因此,即便它只是一个简单的常量,编译器也会为它分配内存。
示例 4:C语言中的const
#include <stdio.h>
const int value = 42; // 始终分配内存
int main() {
printf("%d\n", value); // 编译器必须为value分配内存
return 0;
}
在C语言中,编译器总是为 value 分配内存,无论你是否对它取地址。这样做的原因是C中的const并不像C++中那样灵活。
3.链接性:内部和外部连接
在C++中,如果const定义在所有函数之外(即在全局作用域中),它默认具有内部连接(internal linkage),这意味着它只能在定义它的文件中访问。而C++中的其他非const全局变量默认具有外部连接(external linkage),这意味着它们可以在其他文件中通过extern引用。
示例 5:C++中的内部连接
// file1.cpp
#include <iostream>
const int value = 42; // 具有内部连接,只在这个文件中可见
int main() {
std::cout << value << std::endl;
return 0;
}
// file2.cpp
extern const int value; // 错误!由于value是内部连接的,无法在另一个文件中访问
file1.cpp中的value不能被file2.cpp访问,因为它具有内部连接。
如果想让const在多个文件中可见,可以使用extern。
示例 6:extern使const具有外部连接
// file1.cpp
#include <iostream>
extern const int value = 42; // 通过extern声明,使其具有外部连接
// file2.cpp
#include <iostream>
extern const int value; // 可以访问来自file1.cpp的value
int main() {
std::cout << value << std::endl;
return 0;
}
extern使const在多个文件之间共享,编译器会为它分配内存。
总结
C++中的const:
- 只用于值替换时,可能不分配内存,编译器会将常量值内嵌到代码中。
- 如果取地址或使用extern,则会分配内存。
- const默认具有内部连接(只能在文件内访问)。
C中的const:
- 总是分配内存,无论如何使用。
- const在C语言中没有特殊的链接性,行为类似于全局变量。