首先是指针变量的定义:指针是一种保存变量地址的变量。
指针中最容易出现理解错误的地方就是指针为什么一定要先初始化,下面我将递进式的讨论这个问题。
一,先说明只要是指针类型如果不利用已有的指针变量赋初始值,则必须要进行初始化,不然会出现会出现很多问题。
如果是普通的指针变量,则可以用 指针变量名=&普通变量名 赋初始值,如果是结构体指针,则需要用new动态分配内存空间。
其实我之前写过java中的引用和c/c++中的指针差不多里面都存了一个指向数据的地址,只不过c中的指针是自己主动定义的,而java中的引用是有固定的的数据类型(对象,数组,接口),而且java中引用必须要用new分配实体。
二,首先定义指针*p1;此时p1中保存的必须是一个地址,下面这段代码是非法的,因为赋初始值时p1必须指向一段地址。
int a=5;
int *p1;
p1=a;
三,下面这段代码和和上面代码的区别就是让*p1=a
,而不是p1=a,按照优先级也就是(p1)=a,这里就牵扯到指针最难理解的地方。p1内存放的是一段地址,而*""**的含义则是指向p1内存放的地址中的数据。当我们定义p1时它没有被初始化(此时指针被叫做悬浮指针或野指针),那么程序就不知道它指向哪里,它可能指向一个非法地址,这时,程序会报错。它也可能指向一个合法地址,这种情况更危险,你的程序或许能正常运行,但是这个没有被初始化的指针所随机指向的那个位置的值可以被修改,而你可能并无意去修改它。
所以下面的代码会出现两种情况
第一种情况:p存放的是一个非法地址,此时**"*p"也就是将a赋值给p1内存放的地址中的数据,此时程序是不合法的(大部分是这种情况)
第二种情况:p指向的是一个随机的合法地址,此时"*p"**就是将a赋值给p1内存放的地址中的数据,此时程序虽然是合法的,但你有可能修改了其他你不想修改的数据数据。
所以综上所述下面这段代码也是不合法的。什么时候这段代码就是合法的了呢?请看四。
int a=5;
int *p1=a;
四,那么正确的写法是下面
int a=5;
int *p1;
p1=&a;
//或
int *p1=&a;
这段代码不用多解释,就是先定义指针*p,然后将a的地址赋给p1;
要说明的是,当你给指针初始化以后下面的代码就合法了,此时p里存放的是a的地址,*p
指向a地址内的数据,也就是将a的值变为了6。
int a=5;
int *p1;
p1=&a;
int *p1=6;
五,当我们初始化完指针变量之后,之前的第二个问题中的代码就合法了
1int a=5,b=6;
2 int *p1;
3 p1=&a;
4 *p1=b;
上面的代码我们第三行对指针进行了初始化,然后第四行让*p1=b,此时代码是合法的,因为对指针进行初始化之后,第四行的意思就是将b的值6覆盖p1中存放的地址中原来的数据5,但p1中存放的地址并没有改变(还是初始时a的地址),但地址里的数据也就是a的值却改变了,变成了b里的数据。你们可以思考一下次数输出a,b,&a,&b,p1,&p1的值是多少,有哪些是相等的
六,最后再来说一个例子
数据结构顺序栈入栈代码如下
1Status Push(Sqstack &S,Elemtype e)
2{//入栈
3 if(S.top-S.base==stacksize) //判断栈满
4 return OVERFLOW;
5 *S.top++=e;
}
其中的第五行代码就是把e的值赋给S.top中存放的内存指向的数据,之所以可以使用这句话就是因为之前栈的初始化已经给top进行了初始化。