我能够在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);
}
答案 0 :(得分:17)
是的,你可以用一点点黑客来做。
#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策略,因为它不是原始变量,但是反映了更改,因为它被称为指针的地址。
这适用于Borland C ++或Turbo C ++等旧版本,但现在没有人会使用它。
它&#34;未定义的行为&#34;,这意味着根据标准,您无法预测尝试此操作时会发生什么。根据特定的机器,编译器和程序状态,它可能会执行不同的操作。
在这种情况下,最常见的是答案是&#34;是&#34;。变量const或不变量只是内存中的一个位置,您可以破坏const的规则并简单地覆盖它。 (当然,如果程序的某些其他部分依赖于其常量数据,这将导致严重错误!)
但是在某些情况下 - 最常见的是常量静态数据 - 编译器可能会将这些变量放在只读的内存区域中。例如,MSVC通常将const静态int放在可执行文件的.text段中,这意味着如果你尝试写入操作系统将引发保护错误,程序将崩溃。
在编译器和机器的其他组合中,可能会发生完全不同的事情。您可以肯定的一点是,这种模式会让任何必须阅读您的代码的人烦恼。
试试这个并告诉我。
答案 1 :(得分:8)
如何修改const变量的值?
没有!您不应修改const
变量
拥有const
变量的重点是无法修改它。如果您想要一个您应该能够修改的变量,只需在其上添加const
限定符即可。
任何修改const
强制通过(指针)hackery的代码都会调用 Undefined Behavior 。
未定义行为意味着代码不符合C标准规定的标准规范,因此不是有效代码。这样的代码可以显示任何行为,并且允许这样做。
答案 2 :(得分:6)
通过将i
定义为const
,您承诺不会修改它。编译器可以依赖该承诺,假设它没有被修改。当您打印i
的值时,编译器只能打印10
而不是加载当前存储在i
中的任何值。
或者它可以选择加载值。或者,当您尝试修改i
时,它可能会导致程序崩溃。行为未定义。
您可能会看到gcc的不同行为,具体取决于优化选项(-O1
,-O3
)。
哦,void main()
不正确;它应该是int main(void)
。如果您的教科书要求您使用void main()
,那么您应该会得到一本更好的书。
答案 3 :(得分:2)
查看Can we change the value of an object defined with const through pointers?
长话短说,它是undefined behaviour
。它可以依赖于编译器/机器。
答案 4 :(得分:0)
如果您在gcc中编译此代码,则无法修改const
变量的值
error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
并显示未定义的行为
maiin的事情是,我们只能在没有地址的情况下访问地址时修改变量,我们无法做任何事情。注册存储类也是如此。