C语言(数组与指针)

数组
  1. 数组的元素在内存中连续存储
  2. 各数组元素具有同一类型(大小相等)
  3. 数组名代表数组的首地址(第一个元素的地址)

数组与地址
  • 地址做加法与整数做加法是有区别的,地址做加法时,是以地址的类型大小为单位进行相加的。
  • 以int arr[5]为例,arr 代表了int 类型元素的地址,由于int 类型占用4 个字节,那么,arr 加1,实际上是数值增加的是4,这样,就可以通过*(arr + 1)的方式访问第二个数组元素了。

指针
  • 与定义整型变量一样,p 本身也存储在程序的栈空间上,在32 位操作系统下,所有指针都占用4 个字节大小
  • 指针是一种结合数据类型,它希望存储的是它所结合的数据类型的地址,即使你存入别的任何数据,也会被当作该类型的地址对待。

数组与指针的关系

数组就是数组,指针就是指针,它们之间没有任何关系。

  • 指针变量在32 位系统下,永远占4 字节,其值为某一个内存的地址,指向一块存储区域。
  • 数组代表的是一片连续的存储单元。

关于数组名
名称含义
&a[0]取数组第一个元素的地址
a数组名,只在sizeof(a)和&a 时代表整个数组,其他情况下和&a[0]等价,表示数组第一个元素的地址
&a表示整个数组的首地址
a + 1a 在此处表示数组第一个元素的地址,该地址值加上sizeof(int),表示数组下一个元素的地址
&a + 1&a 表示整个数组的首地址,该地址值加上sizeof(a)的值,得到下一个数组的首地址,显示,该地址相对当前数组已经是越界。

注:a 表示数组第一个元素的地址,&a 表示整个数组的首地址,虽然它们的值一样,都是数组的首地址,但是含义完全不一样。举个例子,浙江省的省政府在杭州,杭州市的市政府也在杭州,两个政府都在杭州,但其代表的意义完全不同。


指针数组
  • 指针数组本质还是数组,只不过它存储的成员是指针。
  • int *p[3] = {&a, &b, &c};
    p[0][0] -> a
    *(*(p + 0)) -> a

野指针问题

指针未指向某一合法地址时,严禁使用*运算符对该地址进行读写:

int *p; //未初始化,存储的地址可能是任意值
*p = 100; //访问的有可能是任意的地址

这种错误称为访问野指针(悬垂指针suspended pointer)。为了防止以该方式访问导致不可预知的错误,通常在定义指针的时候,要将指针赋值为NULL,指向系统的0 地址处,如下:int *p = NULL;


指针的运算

当p1、p2 指向同一个类型的地址时,两个指针可以进行运算,运算的规则如下:

  • 指针加(p1 + a):地址偏移量为a*sizeof(指针类型)
  • 指针减(p1 – a):地址偏移量为-a*sizeof(指针类型)
  • 指针相加(p2 + p1):无意义
  • 指针相减(p2 – p1):两个指针之间相差的元素个数
  • 指针比较(p2 > p1):比较指针的数值大小
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值