一级指针和二级指针的区别

指针的认识

这是一个可以执行的代码
#include <stdio.h>
int main()
{
    int a = 10;
    int *p = &a;(p指向的是a的值,p保存的值是a的地址)
    int **ptr = &p;(**ptr不能简单的理解为**ptr = **ptr),将p的地址赋给*ptr,这样的理解是错的;
                    指针是一种数据类型 p本身就是指针,如果进行赋值操作,&p的数据类型是二级指针,
                    需要一个二级指针去声明,**ptr = &p, 就是p的地址赋给ptr,ptr保存的值是p的地址)
    printf("%d %d %d %d %d", **ptr, *ptr, p, *p, a);
}
上述代码有部分困惑的点
困惑1
int *p = &a;(p指向的是a的值,p保存的值是a的地址)
*p = &a;

这种写法是让我觉得不合理;
心中正确的写法应该是这样的:

int *p = NULL;
p = &a;

看了些资料,大概的意思就是说编译器做了优化,在C中这样写是可以的。

困惑2
 int *p = &a;
 int **ptr = &p;

本来的理解

*p = &a

是将a的地址赋给了p, 即p = 0x00001234(a 在内存中的内存地址)

**ptr = &p

是将 p的地址赋给了 *ptr,即 *ptr = 0x00001235(指针p在内存中的内存地址)

**ptr = *(*ptr)= *(0x00001235)= 0x00001234(即获取的是a在内存中的地址)

这样的理解是不对的,跟困惑1有相似之处;

int **ptr = &p;

上述的写法,我觉得本质还是一级指针的使用;

int *ptr = &p;(这样写便于理解,但是这种写法是有问题的,不符合定义规范)

&p 这种写法中p本身就是指针,&p(取指针p的地址)的数据类型则是二级指针,因此必须定义一个二级指针的变量去声明&p;
二级指针的本质还是一个指针,它主要便是让我们知道它目前所指的位置是一个指针;
数据类型限制了二级指针的发挥;
对于C中的数据类型

  • 出现一个变量肯定需要一个数据类型去描述,通常来说变量属于描述的数据类型的子类;
    int a = 3 ; 3属于整型类
    对于指针来说又有什么数据类型来描述呢?
    C中只有二级指针去描述一级指针
    二级指针实在是没有办法,它指的是个一级指针,如果指的不是一级指针,那它肯定愿意去做一个一级指针而不是一个二级指针;
  ptr = 0x00001235
 *ptr = 0x00001234
**ptr = *(*ptr) =  *(0x00001234) = 10

在代码中最常用的理解方式是赋值操作,指针也可以这样去理解

 int *p = &a;   <=> 将0x00001234的值赋值给p <=> p = 0x00001234; 
 *p <=> *(0x00001234) = 10
 int **ptr = &p;  <=>  将0x00001235的值赋值给 ptr <=> ptr = 0x00001235(指针p在内存中的地址)
 **ptr = *(*ptr)= *(*(0x00001235)) = *(0x00001234) = 10

总结 : 指针来看,* 只需要理解为取值的动作,看懂 * 后面变量所对应的值是什么才最关键;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值