常量的哪个属性使其不可变?
今天我接受了一次采访,其中一个问题对我来说非常棘手。 采访者说“如何不断改变其价值?”
我回答“使用指针”,我向他展示了一个例子:
int main( void ) { const int a = 3; int *ptr; ptr = (int*)( &a ); printf( "A=%d\n", a ); *ptr = 5; printf( "A=%d\n", a ); return 0; }
但他说这很好。 但告诉我哪个属性不变不变? 他还说有一个属性我们可以改变并且不断改变。
有没有这样的财产? 它是如何工作的?
如果他说这很好,那么他就错了:尝试修改常量对象会产生不确定的行为。 在实践中,可能会发生以下三种情况之一:
- 常量变量的行为就像普通对象一样,你会看到它的值发生变化;
- 它存储在不可写入的内存中,程序因访问冲突而崩溃;
- 它的每次使用都被替换为硬编码值,并且您看不到它的变化。
该语言没有定义const
对象的任何运行时属性; 只是编译时检查,你不会意外修改它们。
也许你的面试官指的是“身体”财产:
如果变量位于程序的(只读)代码段中,则任何更改它的尝试都将导致运行时exception。
例如,以下代码段很可能使用在代码段中分配的字符串"abc"
进行编译:
char* str = "abc"; str[1] = 'x';
任何写入该字符串的尝试都将导致运行时exception。 为了防止这种情况发生(通过生成编译时错误),您应该将str
声明为const
。
这是一个更“现实”的例子:
我有一个为STM32(一个基于ARM的皮层)构建的程序。
当我通过JTAG将其加载到CPU中时,代码段被烧入EPROM,数据段被写入RAM。
代码部分包括所有代码以及所有const
变量。
数据部分包括所有全局和/或静态变量。
任何将const
指针转换为“常规”指针然后使用它以便写入内存的尝试都会立即导致内存访问冲突,因为CPU会尝试对EPROM地址执行RAM-Write操作。
我认为面试官期待你说const_cast <>()可以使代码中的常量声明变量可以改变。