指针初始化的问题

例子(1)
#include"stdio.h"
 int main()
 {
   int a,c,*t; 
   int *p=&a,*q=&c;
    *t=*p;
    *p=*q;
    *q=*t;
   return 0;
 }
 例子(2)
 #include"stdio.h"
  int main()
  {
     int a,c,*t=0;
     int *p=&a,*q=&c;
     *t=*p;
     *p=*q;
     *q=*t;
     return 0;
  }
  //请问这两个例子有什么区别吗?为什么有的书上写着第一种情况如果p指向了某一个重要的数据,那么就会被改变,
  //我初始化的概念不太清楚,是不是定义的时候才算初始化,第一种情况是不是比较危险,那第二种方法会不会更好点呢?


慕粉1600176492
浏览 1853回答 3
3回答

朕日理万机

两个实现其实都非常危险。不知道这个例子是不是你为了简化代码自己删减了,还是教科书上原本就这么写的。先说第二个。int *t = 0,在现代编译器里,意思是把空指针赋值给t,空指针是不允许解引用的,你如果运行一下你第二个代码,应该会得到一个segmentation fault。(感谢@onemoo 网友指出,C语言标准中把0赋值给指针,相当于把NULL赋值给指针。C++11引入了nullptr关键字,从此建议用它作为空指针)。总之空指针唯一的作用是用来比较,其他操作都应该避免。你可以把指针初始化为空,然后在运行时把某个地址赋给它,然后要操作时先判断是否为空。然后说第一个变量默认初始化,如果是静态或者全局变量,比如不属于任何函数体中的变量,int会初始化为0,指针会初始化为空指针。而你的代码,不管a, c, *t都是函数中声明的局部变量(存在于栈上),会用某些不确定的值去初始化它们。a和c还好一点,它们会有不确定的值,你如果后面不依赖于a和c做什么重要的事情就没关系。而t会指向某个不确定的地址,它可能关系到别的代码,你在中间改变t指向的地址的值,就是很危险的事情,可能会影响别的调用。所以真正危险的不是p,而是t。

onemoo

抱歉,题主,我之前的回答有误,谢谢 @朕日理万机 指出错误。你可以看帖子中我们俩的讨论。具体来说,我回答中的“但是你在真正使用 t 之前就向 t 赋予了适当的值(通过 p 使其指向 a)”说错了!*t=*p  并不是让 t 指向 a,这语句只是在 t 所指的内存中存入 p 所指的值(也就是 a 的值)。那么在第一例中,这时 t 还没有适当的值,所以可能会引起严重的问题。而在第二例中,t 是个NULl指针,解引用NULL指针会直接引起segmentation fault。要使用指针,一定要确保其指向适当的、有意义且安全的地址。对于你这里的代码,如果一定要通过指针来交换a、b值,那么也要先让 t 指向一个安全可使用的内存,比如:你可以再定义一个int c,然后让 t 指向 c也可以用 malloc(sizeof(int)) 申请一块内存,让 t 指向这里这样就可以确定 t 指向的是安全可用的内存,然后再利用 *t 来交换 *p *q 就没问题了。最后,请采纳 @朕日理万机 的回答。

慕婉清5044891

JEGPFIRGNWMNVRHXMJYAKFSHPTWFUXZCESUWZBENJLUXBRGCYGDFVKHJZIRZCENJZNTJLUQZCCLPLJSOQMBLADZPVFODZBDMNJZGOXTIYGJFTVWGVRGPSUWGVSBJSVKNPFBFOJZCPLUQZCEEGOXTVYHDMPGCYNVEMIRIXPZBXZCEHDTPKMPFUKTPSORWLHQMVXNWGWTIEAWFUJSVRMIYNXAJYHQGWYHWSUQTIXGHDFBQZIETJSMJEOQMPQLOECFIZHDSOXAPYAQMODMPLBXVRRAKZPLHKNCYTKTWSTPYUOWSIKMCENDSQYHXMVKLULNUPRHQSNDMIQDSCYUDYOLHOACXNCENQSBXZVKAUJFUKZVXAIRBQTCYNWXMIKTPYHDZIXZBRTIRIXAHOXGJETPEHMHVRACZILHCZICSAXMCRNPFOCMHRZWLHRHQUWLHEGCRHDGETISGPLBXNJQHWMPLIXADLPXDDWCZCOSFQXSBRTCRUQTAWYHJLHWSDZWSAEAVRZILBZCRNCFIYBDYPRGWMBDFBLLIKHDSHQGVTBAWLBJGVPSIRNUDFIKAWFOQYNIYHDGPRSBNPYNWFIXAIFQMIXGIYHVKNNPRZBDMVYUWNWLZBSHDZCLYUWSVETPLHWOKEHQZWYBEHLFOLAWTWRORQSBRACZWMILGCROKMVRODOILNLHCRNDTWBJSCLIYGQFJRTVYOEUDZPRENJNWSHWMJZQSPLNDMILPYTPRAKSOKHKNLNJMBRALGXGMIDZORUDGWZQNDTQGXTPYWVYADUJTWMCLEUWMPYOXUDTEMISHQLUXNXSNWGAQSXAJNVYAWSNCFBRIJMURTEAQZILEZNQFPEBKADHRTWLOLBRHBZIKNWSWNCYI

onemoo

就这两个简单的代码来说,没有区别!例子1中,你先定义了int指针 p,随后 p = &a; 把变量 a 的地址赋值给 p,也就是 p 会指向 a。 像这样在定义时没有指定初值的话,p 的值是不确定的!也就是 p 指向什么是不确定的。你这时不应该使用 p 的值,当然你后面为 p 赋了确定的值后就没有关系了。例子2中,你在定义指针 p 的同时提供了初值,所以定义好的 p 的初值就是指向 a 的。所以从结果来看这两个例子并没有什么区别。“第一种情况如果p指向了某一个重要的数据,那么就会被改变”——这个代码中显然 p 开始时并没有指向重要数据。另外,假如 p 之前指向了什么,那么“就会被改变”,这指的是什么被改变??  p 被改变吗? 那当然了,p=&a 这就是为 p 赋值啊,当然会改变 p 的指向了。 但这并不会改变被 p 所指的对象的值!  所以也没什么关系。 而且你既然已经要为 p 赋值了,就说明你已经打算让 p 指向新的东西了,原来所指的东西重不重要跟 p 也没关系了。
打开App,查看更多内容
随时随地看视频慕课网APP