数组和指针
问题导引
作为函数参数的数组名
问题1:我们可以使用任何一种声明,但哪一个更准确一些呢?
代码上看指针数组与数组指针
数组指针:指向数组的指针
数组指针的定义
方式一
方式二
方式三
指针数组:数组元素为指针
栈区指针数组
堆区指针数组
数组和指针
指针和数组并不是相等的。为了说明这个概念,请考虑下面两个声明:
声明一个数组时,编译器根据声明所指定的元素数量为数组分配内存空间,然后再创建数组名,指向这段空间的起始位置。声明一个指针变量的时候,编译器只为指针本身分配内存空间,并不为任何整型值分配内存空间,指针并未初始化指向任何现有的内存空间。
因此,表达式<code>*a</code>是完全合法的,但是表达式<code>*b</code>却是非法的。<code>*b</code>将访问内存中一个不确定的位置,将会导致程序终止。另外,如果是<code>b++</code>的话是可以通过编译的,而<code>a++</code>却不行,因为a是一个常量值。
当一个数组名作为一个参数传递给一个函数的时候发生什么情况呢?我们现在知道数组名其实就是一个指向数组第1个元素的指针,所以很明白此时传递给函数的是一份指针的拷贝。所以函数的形参实际上是一个指针。
此时,系统也会对指针进行拷贝,然后进行一系列函数操作,当对数据操作的时候,指针指向的仍然是原数据,操作的仍是原数据本身,所以这里的即使对指针拷贝也是当做实际参数。
但是为了使程序员新手容易上手一些,编译器也接受数组形式的函数形参。因此下面两种函数原型是相等的:
答案是指针形式。因为实参实际上是个指针,而不是数组。同样sizeof arr值是指针的长度,而不是数组的长度。
现在我们清楚了,为什么一维数组中无须写明它的元素数目了,因为形参只是一个指针,并不需要为数组参数分配内存。另一方面,这种方式使得函数无法知道数组的长度。如果函数需要知道数组的长度,它必须显式传递一个长度参数给函数。
表示:数组a中的元素都为int型指针
元素表示:<code>*a[i]</code> 、 <code>*(a[i])</code>是一样的,因为[]优先级高于*
表示:指向数组a的指针
元素表示:<code>(*a)[i]</code>
从代码声明中看的出来,他们俩只有一个括号的区分,那么下面我们来具体说明一下:
数组指针,它是指针,指向数组的指针。
它是指针,它是指针,它是指针。重要的事情说三遍。
数组的类型由元素类型和数组大小共同决定,例如:<code>int array[5]</code> 的类型为 <code>int[5]</code>;
c语言可通过typedef定义一个数组类型:
定义数组指针有一下三种方式:
输出:
指针数组,它是数组,数组中的元素为指针。
其实就是我们熟知的存数据的数组。
他又分两种:栈区指针数组(系统自动分配空间)与堆区指针数组(程序员通过malloc new分配空间)
不申请内存空间:
运行结果:
动态申请内存空间: