https://www.toutiao.com/a6706669049226461447/
谢谢邀请。
很多C语言初学者在学到指针时,都会遇到“数组指针”和“指针数组”这两个名词,然后就一脸懵逼了,其实在考虑C语言中的数组指针和指针数组时,只需多加几个字,一切就清晰许多了:
数组指针 -> 数组类型的指针,所以数组指针是一个指针。
指针数组 -> 指针类型的数组,所以指针数组其实是一个数组。
指向数组的指针
在讨论数组指针之前,先来看一段C语言代码,如下:
C语言中的指针不仅有加法运算,还有减法运算,不过乘除运算就是非法的了。编译并执行上述C语言代码,可以得到如下输出:
其实,访问指针 p 指向的数值,除了“* ”运算符外,也可以以数组的形式,本例中 p[N] 和 *(p+N) 是等价的:
相信有读者已经注意到 p[-1] 了,这似乎与C语言数组下标不能为负的语法相悖,那为何这里能够编译通过,并正常运行呢?鉴于该问题与主题无关,这里不再赘述,感兴趣的读者可翻阅我之前的文章。
数组指针
如果题主觉得上面的C语言代码示例没有难度,其实你已经会用数组指针了。在上面的例子中,p 就是一个数组指针。p 是一个 char* 型的指针,它指向数组,所以叫“数组指针”。数组指针就是指向数组的指针,就像 int 型指针就是执行 int 型变量的指针一样。
数组指针就这么简单。其实,记住数组指针就是指向数组的指针这句话后,再复杂点的情况也能轻松应对。请看下面的例子,我们先用C语言定义一个二维数组,用来存三个人名:
name[3][6] 中的 3 表示 name 数组一共有 3 行,6 表示每行最多有 6 个 char 型数据。现在,我想用数组指针指向这三个人名,可以如下定义:
() 优先级高,说明 p2 首先是个指针,什么类型呢?括号里的内容看过了,现在忽略它,那显然,p2 是一个指向 char [6] (6元素数组类型)的指针,name 就是一个 char [6] 型的数据,所以可以直接把 name 赋值给 p2:p2 = name;
如果题主看过我之前的文章,应该知道指针的加法运算结果受指针的类型影响,那如果 p2 指向的地址为 0, p2[1] (即p2+1) 指向的地址为多少呢?
答案是 6,因为 p2 是一个 char [6] 类型的指针。对于 name 而言,一行为 6 字节,因此 p2[N] 恰好指向的是 name 的每一行,因此数组指针又被称作“行指针”。 如果执行以下C
语言代码:
实际上就是把 name 记录的三个人名打印出来。以数组的形式访问也是一样的:
编译并执行,得到如下输出:
指针数组
讨论完了数组指针,再来看看指针数组。其实,指针数组就是一个数组,只不过这个数组里存放的都是指针而已。就跟我们说int数组是一个存放 int 的数组一样。在C语言中指针数组的定义也很简单:char *p3[3];
[] 的优先级高于 * ,说明 p3 首先是个数组,什么类型的数组呢?char* 型的,char* 表示一个指针类型,所以 p3 就是一个指针数组。
如果使用指针数组指向 name,就不能直接把 name 赋值给 p3 了,因为类型不同。但是,p3 里存放的都是 char* 型的指针,即 p3[0],p3[1],p3[2] 是 char* 型的指针,而 name[0], name[1],name[2] 也是 char* 型的指针,所以可以把 name[N] 赋值给 p3[N],请看如下C语言代码:
编译并执行,可以得到如下输出:
与预期一致。这样,我们就使用了C语言中的指针数组访问了 name 数组。
小结
到这里,C语言中的数组指针和指针数组两者的区别就豁然开朗了,数组指针是一个指针变量,它占有内存中一个指针的存储空间。指针数组是多个指针变量,也即数组,以数组形式存在内存当中,占有多个指针的存储空间。
欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。
https://www.toutiao.com/a6706669049226461447/