是否可以更改const全局变量或外部全局变量的值?通过指针?
你可以改变const局部变量的值。
答案 0 :(得分:2)
如果尝试通过use修改使用const限定类型定义的对象 如果是非const限定类型的左值,则行为未定义。
换句话说,您可以说const
限定对象不可修改
答案 1 :(得分:2)
我猜这将取决于。例如,对于这个程序
#include <stdio.h>
const int val = 12345;
int main(void)
{
printf("%d\n", val);
int *tmp = (int *)&val;
*tmp = 678;
printf("%d\n", val);
return 0;
}
程序(在Linux上使用gcc编译)会产生分段错误。但是如果'const'行在main函数内移动并改为创建局部变量,它似乎确实有效(没有启用任何优化)。
在使用objdump
检查可执行文件时,变量val
位于名为.rodata
的部分中,当程序尝试以某种方式更改内存时导致分段错误。
答案 2 :(得分:2)
虽然可能可能似乎在某些C实现中更改了const
对象的值,但这种外观可能是一种错觉,并且很难在受控制中执行因为:
const
定义的对象时,C标准未定义行为。const
对象的值构建到其他表达式中,以便x
中const int a = 10; int x = 2*a;
的初始化将x
初始化为20而不引用{{ 1}}。可能会发生{strong>某些使用a
引用为其分配的内存并使用更改后的值,如果您设法更改它,而a
的其他用途同一程序以内置方式使用原始值。显然,这会导致一个非常混乱的程序。a
个对象。在许多C实现中,常量全局数据存储在标记为只读的内存区域中。尝试修改它会导致异常,通常会终止您的程序。可以要求操作系统更改此保护,然后修改内存。但是,这样做可能会产生编译器产生的副作用,假设恒定数据不会发生变化。
当您能够修改自动对象(例如一个定义的而不是函数体)而不是静态对象(例如在任何函数外定义的对象)时,可能是因为静态对象保持有恒定的全局数据,标记为只读,但自动对象保留在堆栈中。堆栈包含不同内容的混合,在今天的处理器上不可能将堆栈的小部分标记为只读,而其他部分可写。因此,您可以通过物理访问来修改const
个自动对象。但是,您仍然没有C标准的许可证;行为未定义,可能会有隐藏的副作用会破坏您的程序。
另外,const
并不总是意味着对象是不变的。当一个对象定义与const
时,C标准不会定义尝试修改它的行为。但是,可以添加 const
指针并稍后将其删除。例如,这是合法代码:
const
这种行为是必需的,因为C语言最初是在没有int a = 3;
const int *b = &a;
int *c = (int *) b;
*c = 4;
的情况下设计的,因此它的语义不是为了适应它而设计的,并且在某些情况下如果const
始终不能正常工作执行。
答案 3 :(得分:1)
您仍然可以尝试使用mprotect功能将数据部分更改为RW而不是RO。
http://linux.die.net/man/2/mprotect
请参阅Self modifying code always segmentation faults on Linux
由于它是您自己的程序段,因此您不需要任何权限。此代码可能有效:
#include <stdio.h>
#include <sys/mman.h>
const int c = 1;
int main(int argc, char *argv[])
{
if(mprotect(&c, sizeof(int), PROT_READ | PROT_WRITE) == 0) c = 5;
printf("%d\n", c);
return 0;
}
答案 4 :(得分:0)
Const变量不能改变,这就是为什么它们是const。 其他变量可以更改,如果您可以访问变量本身,则不需要指针
答案 5 :(得分:0)
不能改变常数的值,因为它被称为常数。
答案 6 :(得分:0)
问题没有意义:变量没有值,只有对象和表达式。
您无法更改常量对象的值。
但是,您可以使用某种合适的“常量引用”类型的变量来评估不同的东西:
int a = 10;
const int * const b = &a;
int main()
{
print(b);
*a = 20;
print(b);
}
答案 7 :(得分:0)
是的,你可以:
#include <stdio.h>
const volatile int global = 10;
int main(void)
{
int *ptr = (int*) &global;
printf("Initial value of global : %d \n", global);
*ptr = 100;
printf("Modified value of global: %d \n", global);
return 0;
}
由于volatile
(take a look)
但正如其他人所建议的那样,不要这样做