我正在学习C并发现我们可以通过使用指针来改变常量变量的值。 我尝试使用以下代码执行此操作:
Int main (void)
{ const int i = 10;
int *ptr;
*ptr = &i;
printf("value before : %d",i);
*ptr = 50;
printf("value after : %d",i);
return 0;
}
Output
Value before : 10
Value after : 10
价值没有改变
但是当我这样做时
Int main (void)
{ const int i = 10;
int *ptr = &i; //notice the change here
printf("value before : %d",i);
*ptr = 50;
printf("value after : %d",i);
return 0;
}
Output
Value before : 10
Value after : 50
这两个代码如何产生不同的结果?
答案 0 :(得分:2)
const int i = 10;
int *ptr;
*ptr = &i; // this line is wrong
你在这里犯了一个与const
没有任何关系的错误。当您声明指针时,您编写TYPE *ptr
,但该星号不是指针名称的一部分。当您编写*ptr = EXPRESSION;
时,这意味着将EXPRESSION的值存储在ptr
指向的位置。但是你没有将ptr
设置为指向任何特定的东西,所以程序会出现故障。
要设置位置,这就是您要尝试做的事情,您必须改为编写没有星标的ptr = EXPRESSION
:
int *ptr;
ptr = &i; // corrected
在第二个测试程序中,您改为
int *ptr = &i;
声明指针并在一步中设置其位置。它是上面“更正”代码的简写。
这是您在学习C时必须记住的一件事。
独立于所有这些,当你有
时const int i = 10;
您可以编写看起来像的代码,它使用非常量指针修改i
的值,但该代码 - 但是它是结构化的,但是指针指向了点到i
- 不正确。 “更好”的编程语言会拒绝编译该代码。几乎完全出于历史原因,C实现通常会编译该代码,如果你很幸运可能会发出警告,但是你得到的程序被认为具有“未定义的行为” - 它可能完全按照它的样子行事,它可能表现得如果你从未修改过常量变量,它可能会崩溃,它可能会让恶魔飞出你的鼻子,这些都不会被认为是错误的。
(“解除引用”尚未设置为指向任何内容的指针也会产生具有未定义行为的程序。)
答案 1 :(得分:0)
当你制作一个"指针=地址"在创建指针时,你说地址是相同的。在您的第一个程序中,您正在取消引用指针并将值设置为等于i地址,这对于您的研究案例没有任何意义。
int main (void)
{
const int i = 10;
int *ptr;
//*ptr = &i; <<< VALUE of pointer PTR is EQUAL to i ADRESS
//ptr = &i; <<< ADRESS of pointer PTR is EQUAL to i ADRESS
printf("value before : %d\n",i);
*ptr = 50;
printf("value after : %d",i);
return 0;
}
答案 2 :(得分:0)
你的代码“工作”只是因为auto变量通常(在实现级别上)RW。但你有一些警告(除非你没有把它们关掉太烦人),或者(最有可能)你忽略了它们(编译器试图说: 老兄,我以为你知道你是什么正在做 - 但编译你的代码我停下来确定 )。但是如果你将变量设为全局变量,它很可能会被置于RO区域,并且很可能有一个SEGFAULT。
const const_i = 5;
int foo(int f)
{
const int a = 3;
int *ptr = &a;
*ptr = f;
return a;
}
int main(int argc, char **argv)
{
int *ptr = &const_i;
printf("%d\n", foo(255));
*ptr = 10;
printf("%d\n", const_i);
}
答案 3 :(得分:0)
First Part:-
Int main (void)
{ const int i = 10;
int *ptr;
*ptr = &i;
printf("value before : %d",i);
*ptr = 50;
printf("value after : %d",i);
return 0;
}
Consider i address as 100 where value 10 is store.
Consider p address as 200 which will store the address of integer variable.
And value will be acess by *.
/* Meaning of below statement*/
*ptr = &i;
This means you are trying to store some value in this case 100(since address of i is 100) to address which is pointed by ptr which is currently invalid.
if you will try to acess *ptr this itself is invalid.(it will give u invalid *ptr = 50;read/write with valgrind).
Since there is no change in value store in i address.So it will print proper value.
------------------------------------
second case:-
int *ptr = &i; //notice the change here
Here you are storing address of i in ptr ,suppose address of i is 100.ptr will also store 100.so if you do any change it will be reflected .
------------------------------------
In place of *ptr=&i;
if you write ptr =&i;
This will reflect the value now you are storing address of i in p.
-----------------------------------------
答案 4 :(得分:-2)
在你的第一段代码中,常量变量的地址永远不会分配给指针,因此它的值永远不会改变 您的代码应该是
int *ptr;
ptr = &i;
要使用的代码