玩儿转C语言:数组和指针(2)

来源:互联网 发布:jeesz源码在哪下载 编辑:程序博客网 时间:2024/06/04 06:54

       前面讲的都是数组的基本属性,这里我们再深入一步对多维数组进行分析,讨论一下数组和指针之间的前世今生,呵呵!

1、通过指针反向分析多维数组,代码及结果如下:


分析:

       刚开始,建立了一个新的用户类型:指针类型,该指针指向一个拥有3个整型元素的数组。

       如何理解“数组名称其实就是指向第一个数组元素的地址”?“数组元素又该如何解释”?

       一维数组array3中,p1中的地址信息是array3的第1个变量的地址0x00318064。q1中的地址信息是array3中第2个变量的地址0x003118068。虽然“q1 = p1 + 1”,但q1中地址信息并不是0x003118065,而是增加了1个int变量的空间,指向了第2个元素。

       同理,二维数组array2中,p2中地址信息是array2第1个变量地址0x00318034,q2中的地址信息是array2第3个变量地址0x0031804c,这次增加的就不是2个int变量空间那么简单了,而是2 * 3 个int变量空间,这里3指的是一位数组"int (*array_type) [3]",这次的步进单位不再是一个int空间,而是一个有3个int变量的数组空间。

       array3(一位数组名称):可以直接赋值给int * 指针,则它指的数组元素是int变量。

       array2(二维数组名称):不能直接赋值给int*指针,只能直接赋值给一位数组指针(数组长度只能是3)的变量。

       那么“数组元素”就可以这样理解:一维数组中直接就是定义的数据类型;多维数组中是指除去最外围数组长度的剩余数组,即:array[4][5]数组元素:array[5],array[3][5][6]数组元素:array[5][6]。可以认为,多维数组中的各维度在计算时有优先级顺序。例如array[3][4]意思是“这个数组里边有3个元素,每个元素都是一个含有4个原子数据的数组”;而不能当做“数组里边有4个元素,每个元素都是一个含有3个原子数据的数组”(因为array表示的数组元素是array[4],而不是array[3])。各维度在计算时,有固定的参考顺序,否则系统就会混乱。

       如果指针指向数组中某一个元素,则该指针的加减运算是以它指向的数组元素为单位的。即:如果数组元素是int类型,则指针加1会指向下一个int值;如果数组元素是array[4]类型,则指针加1会指向下一个array[4]的首地址。


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

       

分析:

        无论几维数组,他的名称都表示指向该数组“起始元素”(原子类型、结构体、多维数组)的指针(常量,不可修改),唯一的例外就是数组名称作为sizeof的操作数时,结果是整个数组空间的大小,与“起始元素”无关。

       array3表示第一个元素(int)的指针,那么*array3就表示下标为0的元素引用,同理*(array3 + i)表示下标为i的元素引用,简写为array3[i],因为*(array3 + i)等价于*(i + array3),*(array3 + i)等价于array3[i],*(i + array3)等价于i[array3],则它们四个全部等价,上图也验证了这个结果,但是坚决不推荐i[array3]这种写法,这里只是实验需要,甚至*(i + array3)都不提倡。

       在函数调用中,传递一维数组的名称是传递数组元素集合的首地址,有了首地址函数就可以操纵任意长度的一维数组了,但是这个函数不知道该数组的长度,而且编译器也不对数组下标进行有效性检查,这样可能会造成数据溢出,必要时需要用一个单独的参数传递数组长度。