有木有同学思考过为什么我们在进行数组参数传递的时候为什么不止需要传递数组或者数组指针,还需要传递一个表示数组长度值的一个数值呢?
例如这样:
#include <iostream>
using namespace std;
//int p[]或者int* p
void show(int p[], int n){
for (int i = 0; i < n; i++){
cout << p[i] << " ";
}
cout << endl;
}
int main(){
int *p = new int[10];
for (int i = 0; i < 10; i++){
p[i] = i + 1;
}
show(p, 10);
return 0;
}
运行结果:
为了解释这个问题,我们需要看一下如下示例:
#include <iostream>
using namespace std;
int main(){
int a[10];
int *p = new int[10];
cout << sizeof(a) << endl;
cout << sizeof(p) << endl;
//sizeof(a)计算的是整个int数组的空间
cout << sizeof(a) / sizeof(a[0]) << endl;
//sizeof(p)计算的是p指针的内存空间
cout << sizeof(p) / sizeof(p[0]) << endl;
return 0;
}
运行结果:
在我们理解的都是数组,为什么一个数组长度为10,另一个却为1呢???
这样可以看出:数组名并不完全等价于指针,虽然它们都是通过指针访问数组。那么现在回到上上个问题。
数组在作为函数参数传递的过程中,会被自动退化为指针,因此我们在将数组或者指针作为参数传递时候,同时还需要一个表示数组长度的值。
下面我们对指针和数组的区别进行一个讲解:
1)指针变量存储的是一个地址,用来简介访问数据,一个指针变量一般占用4个字节,指针可以指向任何空间;那么数组呢?编译器根据数组元素的类型和个数在内存中开辟一段连续的内存空间,因为连续,所以经常方便通过指针访问;
2)指针和数组访问时候的区别:
在讲这个部分之前,我们先来看看一下代码:
file1.c
char p[6]="abcde";
file2.c
#include <iostream>
using namespace std;
extern char* p;
int main(){
cout<<p[1]<<endl;
return 0;
}
猜猜这个部分会输出什么?
意外吧!!!我们在后面将进行一个详细描述,这个问题的原因。
指针:
char *p="abcde";
char c=*p;
数组:
char a[6]="abcde";
char c=a[0];
可以看到过通过数组访问的话,数组的地址就是实际存放元素的地址,而指针呢,指针在内存空间中占开辟一个空间,用来存放指针,该内存空间一般为4个字节,有其地址,里面存放的值也是一个地址,指向数组首元素的地址。
好了,现在让我们看看上面代码的问题出在哪里:
file1.c中声明char c[]数组,在内存中开辟了一段6个字节的连续区域,file2.c中却声明为char* c指针,导致编译器从内存中取出char[]数组的前4个字节作为c的地址,所以注定做错;
如果我们考虑将file1.c中声明为数组,而file2.c中定义为指针呢?哈哈,同样有问题啦!因为file2.c中定义的如果是指针的话,则指针p内保存的是4个字节的数组元素首地址,然而file1.c中的数组如何匹配呢?会将char*指针值即数组元素首地址当做4个char字节数组进行匹配,所以同样会有问题的。
3)应该注意的地方
- sizeof计算所占空间时的区别,对于数组,sizeof计算的是真个数组所占的空间,而sizeof指针的时候一般都是4;
- 数组名不可以作为左值,而指针却可以作为左值进行赋值;
- 指针可进行自增自减运算,但是数组不能;
- 理解char*p=”abcde”和char str[]=”abcde”的区别;
参考:http://www.cnblogs.com/dolphin0520/archive/2011/11/09/2242138.html