使用C

时间:2017-09-09 19:39:18

标签: c

我正在学习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 

这两个代码如何产生不同的结果?

5 个答案:

答案 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;

要使用的代码