数组与指针的区别

一个数组就是一个地址,一个指针就是一个地址的地址。

指针偏向于地址的处理,数组偏向于值的处理。

数组是连续分配一串单元,数目开始定义的时候就必须固定下来,看起来整洁,但是写的程序是死程序,容易浪费内存

指针存放一个地址值,表示指向某一个单元,可以用指针来索引单元。数组可以完成栈,堆,树等等的操作,它在编程时候的好处是非常的灵活,在构建思路的时候有很大的灵活性。

空间分配:

数组是静态分配的,指针是动态分配的。

数组分配的空间是连续的,指针分配的空间不一定连续。

数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而 不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。

指针在定义的时候,编译器并不会为指针所指向的对象分配内存空间,它只是分配指针变量的空间。除非以一个字符串常量对其进行初始化。

访问效率:对数组内存是直接访问的,访问效率高。而对于指针是间接访问的,访问效率低。

在C语言中,所有非数组形式的数据实参均以传值形式(对实参作一份拷贝传递给调用的函数,函数不能修改作为实参的实际变量的值,而是只能修改传递给他的那份拷贝)调用。然而,如果要拷贝整个数组,无论是在时间上还是空间上的开销都是很大的,而且在大多数情况下你并不需要拷贝整个数组,只要告诉函数那个地址就可以了。

安全性:指针可以随时指向任意类型的内存块,远比数组灵活,但也更危险。数组容易造成数组越界,指针容易造成内存泄漏。

函数形参:

所有作为函数参数的数组名总是可以通过编译器转化为指针。

标准规定,作为“类型的数组”的形参的声明应该调整为“类型的指针”。在函数形参定义这个特殊情况下,编译器必须把数组形式改写成指向该数组第一个元素的指针形式。编译器只向函数传递数组的地址,而不是整个数组的拷贝。

为什么C语言把数组形参当作指针 

把作为形参的数组和指针等同起来是出于效率原因的考虑。在C语言中,所有非数组形式的数据实参均以传值形式(对实参做一份拷贝并传递给调用的函数,函数不能修改作为实际参数的变量的值,而只能修改传递给它的那份拷贝)调用。同样的,函数的返回类型绝不能是一个函数数组,而只能是指向数组或函数的指针。 

C语言允许程序员把形式参数声明为数组(程序员打算传给函数的东西)或者指针(函数实际所接收到的东西)。编译器知道何时形参是作为数组声明的,但事实上,在函数内部,编译器始终把它当作一个指向数组第一个元素的指针(元素长度未知)。这样,编译器可以产生正确的代码,并不需要对数组和指针这两种情况作仔细区分。 

不管程序员实际所写的是哪种形式,函数并不自动知道指针所指向的数组共有多少个元素,所以必须要有个约定,如数组以NULL结尾(字符串数组)或者另外有一个附加的参数表示数组的范围(length)。 因此,很有意思的是,没有办法把数组本身传递给一个函数,因为它总是被自动转换为指向数组的指针。当然,在函数内部使用指针,所能进行的对数组的操作几乎跟传递原原本本的数组没有差别。只不过,如果想使用sizeof(实参)来获得数组的长度不正确了。因为函数内部的数组自动蜕化成一个指针了,对指针进行sizeof操作得到的结果是都是4。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值