指针与数组的区别于联系

转载 2013年12月03日 15:18:28

1.把数组作为参数传递的时候,会退化为指针
数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;
很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。
所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

典型的情况是

void func(int A[])
{
      //sizeof(A)得到的是4bytes
}

int main()
{
    int a[10]; //sizeof(a) 得到的结果是40bytes
    funct(a);
}
2、数组名可作为指针常量

  根据结论2,数组名可以转换为指向其指代实体的指针,所以程序1中的第5行数组名直接赋值给指针,程序2第7行直接将数组名作为指针形参都可成立。

  下面的程序成立吗?

   int intArray[10];
   intArray++;

  读者可以编译之,发现编译出错。原因在于,虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。

  而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,在WIN32平台下,sizeof操作的结果都是4。
顺便纠正一下许多程序员的另一个误解。许多程序员以为sizeof是一个函数,而实际上,它是一个操作符,不过其使用方式看起来的确太像一个函数了。语句sizeof(int)就可以说明sizeof的确不是一个函数,因为函数接纳形参(一个变量),世界上没有一个C/C++函数接纳一个数据类型(如int)为"形参"。

3

对于问题:为什么用strcpy()函数时,
用----------------
char a[3] = "abc";
strcopy(a,"end");
-------------------没有错。
用-----------------
char *a = "abc";
strcopy(a,"end");
------------------运行时就有错呢?

解释如下:

char *a = "abc";   
abc"是一个字符串常量,有它自己的存储空间,因为分配在只读数据块,我们无法直接访问。
这样赋值后,a只能读,不能写
所以strcpy(a, "end")不行
只有当你为a分配非常量的存储空间后才行
如:
char *a = new char[4];
strcpy(a, "end");   
printf("%s", a);
delete []a;

4//main.cpp
int array[3] = {7, 8, 9}; //全局变量
int main()
{
Test1();
Test2();
return 0;
}

//Test1.cpp
extern int array[3];
void Test1()
{
cout << array[1] << endl;
}

//Test2.cpp
extern int *array; //这个地方是不同的
void Test2()
{
cout << array << endl;
cout << array[1] << endl;
}

Test1()和Test2()的输出结果相同吗?

编译一下再看看,就发现执行Test2会有奇怪的结果,第一条语句的输出是7, 第二条语句会死机。而Test1()却一切正常。
这是为什么?
原因在编译器。在Test1.cpp中,由于使用了extern所以编译的时候要先用占位符将array标志一下,在连接的时候用main.cpp中的array进行
替换。当编译器给变量赋值的时候,他认为这个值是该变量的地址。就好比:int i = 5;在编译器中编译后会把5的地址0x8291记录
而不是5,在i需要值的时候去0x8291这个地址去取出值给i(这里的i是全局的或者静态变量,这时候才能在编译阶段确定地址)。
所以在Test1.cpp中,把array的地址给了array,假设这个地址是0x34fe,但是由于数组的特性array == &array,所以这里是正常的。
而在Test2.cpp中,array是个指针,所以会去0x34fe中取出值给array,所以array = 0x0007(数组的第一个值,这里要做地址,因为是给指针用)
这就是看到的Test2()的输出结果。显然array[1]会死机,因为0x0007地址是没有被分配的,并且是给操作系统用的而不是给用户用的。

5数组和指针的分配]

数组是开辟一块连续的内存空间,数组本身的标示符代表整个数组,可以用sizeof取得真
实的大小

指针则是只分配一个指针大小的内存,并可把它的值指向某个有效的内存空间

[空间的分配]

[全局的和静态的]
char *p= "hello ";
一个指针,指向只读数据块(section)里的 "hello ",可被编译器放入字符串池(也就是说,
你在写一个char *q= "hello ",可能和p共享数据)

char a[]= "hello ";
一个数组,分配在可写数据块(section),不会被放到字符串池中

[局部]
char *p= "hello ";
一个指针,指向只读数据块(section)里的 "hello ",可被编译器放入字符串池(也就是说,
你在写一个char *q= "hello ",可能和p共享数据),另外,在函数中可以返回它的地址,也就
是说,指针是局部变量,他指向的数据却是全局的.

char a[]= "hello ";
一个数组,分配在堆栈上,初始化由编译器进行(短的话直接用指令填充,长的就从全局字
符串表拷贝),不会被放到字符串池中(但是却可能从字符串池中拷贝过来),也不应该返回
它的地址.

[代码中的字面字符串]
printf( "%s/n ", "hello ");
这两个字面常量( "%s/n "和 "hello "),都在只读数据块里

[用途]
全局指针
用于不需要修改内容,却可能会修改指针的情况(当然,不修改也没人反对)

全局数组,用于不需要修改地址,却需要修改内容的场合

既需要修改指针,有需要修改内容怎么办呢?定义一个数组,在定义一个指针指向它就可
以了

函数中如果不需要修改字符串的内容,应该尽量用char*p= "xxx "这种写法.初始化的局
部字符数组影响效率,一般应该尽量避开(应该使用的情况下则不要犹豫)

相关文章推荐

C语言中指针与数组的区别与联系

好久不写东西了,从毕业以来,整个人都懒散了很多。今天终于鼓起勇气,来写一点儿东西…… 指针与数组对于C语言程序员来说肯定不会陌生,一说起这个话题,我就想起了曾经被内存、地址、地址里的内容这些概念狂虐时...
  • cyfcsd
  • cyfcsd
  • 2017年02月03日 17:29
  • 2089

字符数组与字符指针的区别与联系

1.字符指针可以指向一个字符串。 我们可以用字符串常量对字符指针进行初始化。例如,有说明语句: char *str = "This is a string."; 是对字符指针进行初始化。此时,字...

浅析数组与指针的联系与区别1

以前总感觉数组和指针冥冥之中有点联系,最近发现不只是有点点联系,甚至可以说是基本等价。...

字符串数组和字符串指针的区别联系

一、区别1、初始化char x[10]="abc"; char* q="abc";在VS2013编译器下,字符串数组和指针均可以按照如上方式进行初始化赋值,但对内存的方式不尽相同,参照下面的例子进行记...

初步探讨数组和指针的区别与联系

在学习和使用指针与数组的时候,我总对指针和数组的关系充满疑惑,因此,以现有的知识和理解,我对它们做了一些归纳.首先说一个结论,数组名不是指针常量. 从编译器的角度来看 当程序员定义了一个指针int...

c语言==数组和指针间的联系与区别(10)

数组与指针的联系例如,在某个函数的形参里,会有char ptr[100],这时编译器会将它默认看成是char * ptr,在函数里面可以自增,即ptr++。类似地,char src[3][100]也可...

c语言中数组和指针的区别与联系

本文参考 1.引例1: extern int *x; extern int x[]; 以上两句代码可以看出什么区别么?或许你觉得都一样嘛。但是这里还是得强调,不一样。 第一句,声明了一个类型...
  • cdkd123
  • cdkd123
  • 2012年04月10日 17:55
  • 849

C语言——数组与指针区别与联系

今天重拾了一会C语言,看了两章《C专家编程》有关数组与指针的内容。看完感觉收获还是蛮多的,一些以前零碎的知识点一下子被串了起来,估计以后不会那么轻易就遗忘喽,!言归正传,接下来我想把C语言中数组与指针...

c语言中数组名与指针的区别与联系

今天在工作中定义数组的时候习惯性的使用char型指针后直接等于字符串,但在编译通过后运行的时候产生了段错误,因为着急就(整个函数代码还是比较多的)没仔细看代码,只是抱着试试看的心态,将定义换成了数组后...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:指针与数组的区别于联系
举报原因:
原因补充:

(最多只允许输入30个字)