指针深度解刨《二》(指针指向自己)
今天我们继续指针下相关的内容学习。
今天有很多左值右值相关使用,不懂的点这里哦-------》左右值问题
今天也要心情愉悦的学习哦。
目录
指针的内存布局
解引用深度理解
首先解引用的作用:
深度理解引用
指针可以自己指向自己吗?
直接寻址和间接寻址
直接寻址
间接寻址
下期预告:
指针的内存布局
我们知道指针就是地址了就是一个字节的地址,如果有很多字节,那么&地址到底取的是哪一个地址呢?看个例子:
int a = 10;int *p = &a;
因为是小端存储,就是低权值位放在低地址处,内存是低地址向高地址排列的。我们一般取地址取得是最低的地址。所以取得就是内存中0a处的内存值。
只取出了一个字节的地址,那么怎么才能访问到四个字节呢?
这时就是类型起作用了,因为p是 int * 型的指针,所以解引用访问4个字节。如果强制类型转换,就是起始地址不变,访问的字节数发生变化。
解引用深度理解
首先解引用的作用:
"*"的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,“解”就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为“解引用”。也就是说,解引用是返回内存地址中对应的对象。
举个例子:
int a = 10;int *p = &a;int b = *p;*p = 20;
留个问题:(最后解答)
*p:*是一个操作符,*p是表达式,*p中使用的是p的左值还是右值呢?
简单分析下:一共三个变量,a b p,a和p不在分析,对于b分析,*p充当了右值,即*p(a)的值赋值给了b,所以b = 10; *p = 20中 *p充当了左值,即提供了(a)空间,所以a = 20。
*p因为充当左值右值不同,所以意义也不尽相同。这样也太过于复杂了,一个小结论:
在同类型中(不考虑强制类型转化),对指针解引用代表指针所指向的目标。
看个例子,来进一步理解下结论:
这里可以看到是直接访问了指针变量的右值,换句话说,我们对指针变量进行解引用,就是直接拿出该变量的地址,直接去访问该地址指向的内容。这也就对应了上述的结论。
上面遗留的问题也能解答了,*p中使用的是指针变量 p 的右值。
深度理解引用
那么看个例子更深度理解下 * 解引用吧。
int a = 0;int* p = &a;*p = NULL;p = NULL;
p = NULL 和 *p = NULL有什么区别呢,首先 *p 就是 a,就是把a的值变成NULL,因为NULL在数字层面上是0,所以a就等于0,p是一个指针变量,使用的是左值,即把p的指向变了,由原来的&a,指向了NULL。
指针可以自己指向自己吗?
指针是可以自己指向自己的。
看个例子:
int* p = NULL;p = (int *)&p;*p = 10;p = 20;
首先定义了指针变量p,然后把指针变量p的地址(强转为int *)赋给指针变量p本身,此时p变量的内容是p的地址,p变量的地址没变。
对*p进行解引用,因为*p 就是 p,所以p变量的值变成了10
然后p = 20,是把20赋给了p(变量的左值)的空间,所以p变量的地址为20
我们看下最终打印的结果把,深刻理解下,指针自己指向自己的结果。
直接寻址和间接寻址
直接寻址
直接寻址就是直接写地址,进行操作。
看个例子:
*(int *)0x11223344 = 10;printf("%d\n", *(int *)0x11223344);
这就是直接寻址 ,直接写出地址,但是会有访问冲突,一般不允许写入。
间接寻址
间接寻址就是给出变量,访问变量的地址。
看个例子:
int a = 0;int *p = &a;*p = 1111;printf("%d\n", a);
这样通过变量的形式,访问地址,叫间接寻址,这是最常用的。
下期预告:
下期讲数组相关的概念,后续再把指针数组对比讲解。
下期更精彩~!~!~!