三、指针类型(int **)的存储过程和原理
int **q;
q = &p;
printf("q = %d\n",q);
结果:q = 6618624存放的p的地址
int *p明白了,那么int **q呢?
首先: 先对数据类型和变量划分开
int **q; 变量名为q,数据类型为int **
int *中存放的是int类型数据的地址
int **中存放的是int类型数据的地址的地址
上述我们明白了,一个*是指一个int数值的地址,
p中存放的是个int数值的地址,p = 6618636,为a的地址。
那么我们可以推到,两个*q就是存放p的地址。
p存放a的地址,p本身也是一个变量,他的值为a的地址 ,
而内存也给他自己开辟了一片空间,让他存放而他的数值
q存放p的地址,q也是一个变量,
他们的指向关系如下 :
a<----p<----q
四、指针类型(int ***)的存储过程和原理
int ***m;
m = &q;
printf("m = %d\n",m);
结果:m = 6618616存放的q的地址
既然,int *和int **都懂了,那么int ***就迎刃而解了
同理,int*** 存放的是int **类型数据的地址
五、指针操作(*操作)
这块我们这说属于指针自己的操作
printf("p = %d\n",p);
printf("*p = %d\n",*p);
printf("q = %d\n",q);
printf("*q = %d\n",*q);
printf("**q = %d\n",**q);
printf("m = %d\n",m);
printf("*m = %d\n",*m);
printf("**m = %d\n",**m);
printf("***m = %d\n",***m);
结果:
p = 6618636
*p = 5
q = 6618624
*q = 6618636
**q = 5
m = 6618616
*m = 6618624
**m = 6618636
***m = 5
p、q和m都是上述例子中的变量
首先除了定义指针变量的时候,变量前面有*为定义类型,其他时候均为指针的取值操作,注意是取值,不是取址,拿的是指针变量中存放的值。
1.举个现实中栗子
举个现实中的例子,你比如说去银行开保险柜,其中*p操作比如开保险柜这个操作,你得先拿着你的柜子号在银行找到保险柜,然后拿着钥匙再打开保险柜取出里面的钱;就像是p中存放的是一个地址,你先拿着p中存放的地址,在内存中找到那块空间,然后再*p操作,取出那块空间中存放的值。
所以 * 操作就是取值操作,即取出指针变量存放的地址中所存放的数据。
2.*操作怎么去分析
上面几个例子都属于指针的取值操作,也就是也就是拿着指针变量中存的地址号去内存中找里面存的东西。
所以看这种连着好几个*后面跟个变量的表达式,需要从右往左依次抛开
即:***m ; 就是* ( * ( * m ))),看的时候需要从最里层一层一层抛开。
- *p ;
- 先看成*(p),再从里向外看,首先他有一个变量p,所有直接可以先从内存中拿到p存放的数据6618636(p中的数据),再找到内存中6618636那片内存,最后取出6618636中的存放数据5(具体数据)
- **q = 5 ;
- 先看成 *( * (q)),再从里向外看
- 先从内存中拿到q存放的数据6618624(q中的数据),再从内存中找到6618624那片内存,取出存放的数据6618636(*q中存放的数据),完成了 * (q)操作,再从内存中找到6618636那片内存,取出存放的数据5 ( *( *(q))中存放的数据 ),完成了 *(* (q))操作,再中的存放数据5(具体数据) (几个*查找几层)
- ***m = 5
- 先看成 *(*( * (m))),再从里向外看
- 先从内存中拿到m存放的数据6618616(m中的数据),再从内存中找到6618616那片内存,取出存放的数据6618624(*q中存放的数据),完成了 * (m)操作,再从内存中找到6618624那片内存,取出存放的数据6618636 ( *( *(m)) 中存放的数据),完成了 *(* (m))操作,再从内存中找到6618636 那片内存,取出存放的数据5( *(*( *(m))) 中存放的数据),完成了 *(*( *(m)))操作, (几个*查找几层)
补充:
1、理解指针必须先对进制 内存地址单元有个初步的了解,至少要明白二进制 八进制 十六进制的基本含义,1byte等于多少bits还有一个内存地址单元可存放一个字节的数据,最好明白程序运行时所有代码表示的数据都会被加载到内存中。
2、既然你的图中是以大端模式进行内存的数据排列那么应该有必要说明下计算机的大小端模式。
3、未进行声明的内存地址单元存放的值应该是不可预测的,至少在windows下如此
4、个人认为学习指针最好的方法应该是打开visual studio,写几行简单的指针变量代码,设断点,打开调试窗口下的监视和内存窗口,将移位操作、强制类型转换、结构体、sizeof、数组类型都亲自动手试一遍并对内存窗口下每个将要操作的内存地址单元的变化进行合理预测,这样来理解效果应该是比较清晰值观的
大佬的心得需要充分理解学习