指针的理解(一)

    变量和一维数组的指针比较容易理解,但二维数组与函数的指针较难理解,后期容易混了,所以梳理一下二维数组和函数指针的一些要点。

一、回顾变量和一位数组的指针

        (一)变量的指针

        内存的每个内存单元大小为一字节(8比特位),每个内存单元都有自己的独有的地址。x86系统由32根地址总线(每个地址线可以看作一个比特位),在x86系统下,地址长度为32个比特位(即4个int大小);同理在x64系统下,由64根地址总线,也就是内存单元的地址长度为64个比特位(即8个int大小)。

        指针就是内存的地址,变量的指针就是这个变量存到的内存单元所对应的内存地址(4或者8个int大小)。

         指针变量是用来存储地址信息的一种变量,可以类比理解,整型变量是用来存放int类型数据的变量,字符型变量是用来存放char类型的数据。因此,指针变量是用来存放指针的变量。

           如上图, 指针变量有独特的表示方法,就是在定义指针变量时,用'*'来表示这个变量是个指针变量。如果有一个变量n,在它的前面加上'*',那就代表这个变量n是个指针变量,里面存储的数据类型是地址(4个或8个int长度的数据)。取地址运算符是'&',a是整型变量,&a意为取整型变量a的地址,*n=&a,意为将变量a的地址放到指针变量里。

        (二)一维数组的指针

        一维数组的地址就是数组名arr,如下图:

        arr指向的地址是数组首元素的地址,也就是指针指向了第一个元素'0'所在的地址,查看0的地址:            会发现arr[0]的地址和整个数组arr的地址是一样的,但是他们的类型是不一样的。&arr[0]的地址类型是int*,意为这个地址是个int类型变量的地址,&arr的地址类型是int[5]*,意思是这个地址是包含5个int类型变量的数组的地址。

        int[5]是什么意思?代表arr这个数组的类型(不是地址类型),是int[5],与数组地址类型int[5]*要区分开。

        都是同样一个地址,int*和int[5]*的区别在于,指针移动时的移动跨度,即移动1个单位,指针挪动多少个字节,如下图:

        会发现第一个元素移动了4个字节,正好一个整型int的距离,而数组地址移动的距离更大,移动了0x0000014(16进制)个字节,就是20个字节,5个整型int的距离。用一个图来说:

               由此可见,指针移动一个单位的距离,它的移动跨度是有指针的类型决定的。

二、二维数组的指针

        二维数组的指针理解起来更复杂一些。

        有一个二维数组arr[3][3],它的数组类型为int[3][3]。

        继续查看&arr[0](等同于数组名arr)的类型是int[3]*,也就是&arr[0]是一个指向包含3个int类型元素的指针;&arr地址类型intarr[3][3]*,这是一个指向3*3的二维数组的指针。虽然他们指向的地址都是0x010ff910,但是它们的类型不一样。

        再拿出&arr[0][0]看一下:

        地址也是0x010ff910,类型是int*,代表这个指针指向一个int类型的变量。

        接下来,让这3个指针都移动一个单位:

        由上图可知,arr[0][0],移动了4个字节,也就是移动了一个int类型的长度;arr[0]移动了12个字节(上图是16进制,算出来是地址增加了12),也就是移动了3个字节,正好一个一维数组的长度;arr移动了36个字节的长度(9个整型类型的长度),表示指针移动到了整个二维数组后的那个内存单元地址。

        指针移动如下图:

三、二维数组指针迷惑行为

        有一个数组int a = [3][4] = {0};运用关系操作放sizeof计算一些数据。

 (1)计算a[0][0]占用多少字节

(2)计算a[0]占用多少字节

(3)计算a[0]+1占用多少字节

(4)计算*(a[0]+1)占用的字节

(5)计算a+1占用的字节

(6)计算*(a+1)占用字节大小

(7)计算&a[0]+1占用的字节

(8)计算*(&a[0]+1)占用字节大小

(9)计算*a占用的字节

(10)计算a[3]占用的字节大小

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值