我可以在 gcc 中更改 const
修饰变量的值,但不能在其他编译器中更改。
我在 gcc 上试过这段代码,它更新了 i
和 j
(11) 的值。用an online compiler , 我得到不同的值。
#include<stdio.h>
void main() {
const int i=10;
int *j;
j = &i;
(*j)++;
printf("address of j is %p address of i is %p\n",j,&i);
printf("i is %d and j is %d\n",i,*j);
}
是的,您可以通过一些技巧来完成。
#include <stdio.h>
int main(){
const int a = 0;
*(int *)&a = 39;
printf("%d", a);
}
在上面的代码中,a
是一个const int
。使用小技巧,您可以更改常量值。
更新:解释
在上面的代码中,a 被定义为一个const
。例如,a 有一个内存地址 0x01
,因此 &a
返回相同的内容。当它用 (int *)
转换时,它变成另一个变量,称为指向 const 的指针。当再次使用 *
访问它时,可以在不违反 const 策略的情况下访问另一个变量,因为它不是原始变量,但更改会反射(reflect)出来,因为它被称为指针的地址。
这将适用于 Borland C++ 或 Turbo C++ 等旧版本,但是现在没人使用它了。
这是“未定义的行为”,这意味着根据标准,您无法预测尝试此操作时会发生什么。根据特定的机器、编译器和程序的状态,它可能会做不同的事情。
在这种情况下,最常发生的情况是答案是"is"。变量,无论是否为 const,都只是内存中的一个位置,您可以打破 const 的规则并简单地覆盖它。 (当然,如果程序的某些其他部分依赖于其 const 数据是常量,这将导致严重的错误!)
但是在某些情况下——最典型的是常量静态数据——编译器可能会将此类变量放在内存的只读区域中。例如,MSVC 通常将 const static int 放在可执行文件的 .text 段中,这意味着如果您尝试写入它,操作系统将抛出保护错误,程序将崩溃。
在编译器和机器的其他一些组合中,可能会发生完全不同的事情。您可以肯定地预测到的一件事是,这种模式会惹恼任何必须阅读您的代码的人。
试试这个,让我知道。