C语言中数组与指针的区别

在C语言的代码中,经常会将数组的数组名当做指针来使用。通过地址的偏移来对数组的元素进行操作。
此时,认为数组名和指针是等同的。
但是数组与指针到底是什么关系?将指针和数组划等号,会不会有什么问题呢?
下文,将对数组与指针的区别进行说明。

在进行说明之前,先说明一个背景知识:在C语言程序运行时,是通过符号(label)的地址进行访问的。
也就是,经过编译和链接之后,程序中的符号(变量和函数)都会被替换成相应的地址。
此部分知识,可参考程序编译 相关书籍。

正因为是通过符号的地址进行访问,这就造成了指针和数组在使用上的最大区别:指针在进行访问时,需要多一次的地址提取!
下面举例进行说明:
  • 数组
char a[9] = "abcdefgh";
b = a[i];
此时, 编译器已知的是数组的地址,即数组的首地址。要取得a[i],需要进行如下两步操作:
  1. 将数组首地址加i;
  2. 通过步骤1中的地址,取得a[i]的值
  • 指针
char *p = "abcdefgh";
c = p[i];
此时, 编译器已知的是指针p的地址。要取得p[i],需要进行如下三步操作:
  1. 通过指针p的地址,取得p所指向的内容"abcdefgh"的首地址
  2. 将步骤1中的地址加i
  3. 通过步骤2中的地址,取得p[i]的内容
因此,上述的数组和指针操作中,看起来二者的操作没有区别,执行的结果也相同。
实际上, 指针在进行访问时,需要多一次的地址提取!

一个例子证明上述区别:
file1:
char ptr[] = "HELLO";
file2:
extern char *ptr;

char ch = ptr[3];
上面的程序执行结果是什么?程序应该会出现segment fault。有兴趣的,可以编译运行一下。
道理很简单,file1中定义了数组ptr。那么程序在编译时,符号的地址是已知的,即数组首地址已知。
file2中,将ptr声明为char型指针。这样的话,file2中对ptr进行操作时,是 将ptr的地址作为指针的地址来使用的。
那么,file2中会按照指针的访问的三个步骤进行操作。
程序的初衷是将ptr[3](字符'L')赋值给ch。但是,编译器将字符'L'当做一个地址。
把ASCII字符当做地址进行操作,显然会得到一个错误的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值