黑马程序员技术交流社区

标题: C语言指针和一维数组关系 [打印本页]

作者: 曦正    时间: 2016-2-19 10:51
标题: C语言指针和一维数组关系
C语言数组和指针对于初学者来言,指针是一个很大的坑,但是C语言能够那么多年来屹立不倒,也有赖于指针,没有指针C语言将什么也不是,下面简单分析一下C指针与数组的关系,笔记是自己整理的,如果有大牛发现有些不详尽或者有错误的话,欢迎补充指正,谢谢!也希望初学者能够学好指针,因为把指针搞懂了,后面那些什么Java、C++、OC等一些库函数的底层实现就比较好懂了。

C语言中,数组和指针密不可分,在系统内部实现上有着近乎一致的特性,只有在极少数情况下才需要人为区分;在C语言中只有一维数组的概念,多维数组在系统内部也是开辟一块平坦连续的空间,如果只看内存地址空间,是看不出多维数组的行列数的,比如array1,二维数组就是一个一维数组,数组内部元素是另一个数组,多维数组也是类似递归定义的。
数组有两个确定的参数:数组大小和下标为“0”的元素的地址。数组的下标操作实际上都是通过指针来进行的,数组和指针有一一对应的关系。

当输出array1[1][5]时,输出了“10”,在正常情况下,array1是没有[1][5]这个偏移的,但系统确实能正确的读取到相关的数值,就说明二维数值其实也就是一维数组;
array1[1][5]表示第2行的第6个数据,一行有4个数据,则4+6,切换到数组上就是array1[2][1],表示第3行的第2个数据,可以验证:数组内部数据是扁平化连续分布的,而且是内部转换成指针操作。
分析以上代码:
先建立一个新的用户类型:指针类型,该指针指向了一个拥有3个整型元素的数组;
如何理解数组名其实就是指向第一个数组元素的地址?
又如何解释数组元素?
一维数组array3中,p1的地址信息是array3的第1个变量的地址0x00318064,q1中的地址信息是array3中的第2个变量的地址0x000318068;虽然“q1=p1+1”,但是q1中地址信息并不是0x000318065,而是增加了1个int变量空间,指向了第2个元素。同理,二维数组array2中,p2中地址信息是array2第1个变量的地址0x000318064,q2中的地址是array2中第3个变量地址0x00031804c,这次增加的就不是2个int变量的空间那么简单了,而是23个int变量空间,这里的“3”指的是一维数组“int (array_type)[3]”,这次的步进单位不再是一个int空间,而是3个int变量的数组空间;

因为“int (*array_type)[3]”表示了一个拥有3个整型元素的数组,而array_type q2表示的是这一类“拥有3个整型元素的数组”的第0个元素,所以跨越了3个int变量的数组空间。

array3(一维数组名称)可以直接赋值给int指针,则它指的数组元素是int变量;
array2(二维数组名称)不能直接赋值给int
指针,只能直接赋值给一维数组指针(数组长度只能是3)的变量
那么,数组元素就可以这样解释:一维数组中直接就是定义数据类型;多维数组中是指除去最外围数组长度的剩余数组,即array[4][5]的数组元素:array[5],array[3][5][4]数组元素:array[5][4]。
可以认为,多维数组中的各维度在计算时是有优先级顺序。例如,array[3][4]意思是这个数组有3个元素,每个元素含有4个原子数据的数组;各维度在计算时,必须有固定的参考顺序,否则系统就会混乱。
如果指针指向数组中某一元素,则该指针的加减运算是以它指向的数组元素为单位的。即:如果数组元素是int类型,则指针+1会指向下一个int值;如果数组元素是以array[4]为类型,则指针+1会指向下一个array[4]的首地址。

一维数组和指针之间的微妙关系

分析:
无论几维数组,它的名称都表示指向该数组“初始元素”(基本类型、结构体、多为数组)的指针唯一的例外就是数组名称作为sizeof的操作时,结果时整个数组空间的大小,与起始元素无关;
array3表示第一个元素(int)的指针,那么array3就表示下标为“0”的元素引用,同理(array3+i)表示下标为i的元素引用,简写为array3,因为*(array3+i)等价于array3
在函数调用中,传递一维数组的名称时传递数组元素集合的首地址,有了首地址,函数就可以操纵任意长度的一维数组了,但是这个函数不知道该数组长度,而且编译器也不对数组下标进行有效性检查,这样可能会造成数据溢出,必要时需要用一个单独的参数传递数组长度。

也就是说,数组名其实就是数组第0个元素的地址,a就是获取数组a第0个元素地址里面的内容;而变量,则跟数组没有直接关系,需要去(&变量地址)才能取出变量地址里面的内容



作者: hpuie0703    时间: 2016-2-19 16:00
感谢分享.
作者: chuanzhang    时间: 2016-2-19 20:29
指针和数组 这是一个比较难的点
作者: 曦正    时间: 2016-2-19 22:14

可以交流一下
作者: 曦正    时间: 2016-2-19 22:15
chuanzhang 发表于 2016-2-19 20:29
指针和数组 这是一个比较难的点

是的,有什么问题也可以交流一下
作者: 梦想家z    时间: 2016-2-20 08:11
给力
作者: 曦正    时间: 2016-2-20 08:47

谢谢!!
作者: silenCetestifY    时间: 2016-2-20 09:49
可以可以
作者: chensc    时间: 2016-2-21 07:51
学习学习!
作者: Rodin05    时间: 2016-2-21 12:56
感谢分享呢
作者: 曦正    时间: 2016-2-21 13:43

不用客气
作者: XJJ    时间: 2016-2-21 14:45
写的很认真哦!!
作者: chensc    时间: 2016-2-22 06:10
学习学习!
作者: songzengyu    时间: 2016-2-22 07:38
谢谢分享
作者: 曦正    时间: 2016-2-22 13:05

金牌黑马
向金牌黑马学习才对
作者: 382502038    时间: 2016-2-22 16:36
顶贴顶贴顶贴
作者: superxc    时间: 2016-2-22 17:20
点赞~!            
作者: 大爱五花肉    时间: 2016-2-22 17:37
学习学习
作者: yatoutou    时间: 2016-2-23 08:44
谢谢分享




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2