水滴石穿C语言之指针、数组和函数

2008-02-23 05:26:23来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

 基本解释

  1、指针的本质是个和地址相关的复合类型,他的值是数据存放的位置(地址);数组的本质则是一系列的变量。

  2、数组名对应着(而不是指向)一块内存,其地址和容量在生命期内保持不变,只有数组的内容能够改变。指针能够随时指向任意类型的内存块,他的特征是“可变”,所以我们常用指针来操作动态内存。

  3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。

  问题:指针和数组

  听说char a[]和char *a是一致的,是不是这样呢?

  答案和分析:

  指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针和数组确实具备一定的一致性,但这只是一种比较特别的情况而已,在本质上,两者是有区别的。请看以下的例子:

char a[] = "Hi, pig!";
char *p = "Hi, pig!";

  上述两个变量的内存布局分别如下:

  数组a需要在内存中占用8个字节的空间,这段内存区通过名字a来标志。指针p则需要4个字节的空间来存放地址,这4个字节用名字p来标志。其中存放的地址几乎能够指向任何地方,也能够哪里都不指,即空指针。现在这个p指向某地连续的8个字节,即字符串“Hi, pig!”。

  另外,例如:对于a[2]和p[2],二者都返回字符‘i’,但是编译器产生的执行代码却不相同。对于a[2],执行代码是从a的位置开始,向后移动2两个字节,然后取出其中的字符。对于p[2],执行代码是从p的位置取出一个地址,在其上加2,然后取出对应内存中的字符。

  问题:数组指针

  为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?如何定义?

  答案和分析:

  使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的长处,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在高维需要动态生成情况下的多维数组。

  定义例子如下: int (*pElement)[2]。

  下面是个例子:

int array[2][3] = {{1,2,3},{4,5,6}};
int (*pa)[3]; //定义一个指向数组的指针
pa = &array[0]; // '&'符号能够体现pa的含义,表示是指向数组的指针
printf ("%d", (*pa)[0]); //将打印array[0][0],即1
pa ; // 猜一猜,他指向谁?array[1]?对了!
printf ("%d", (*pa)[0]); // 将打印array[1][0],即4

  上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。

  需要说明的是,按照我们在第四篇讨论过的,指针的步进是参照其所指对象的大小的,因此,pa 将整个向后移动一个数组的尺寸,而不是仅仅向后移动一个数组元素的尺寸。

  问题:指针数组

  有如下定义:

struct UT_TEST_STRUCT *pTo[2][MAX_NUM];


  请分析这个定义的意义,并尝试说明这样的定义可能有哪些好处?

  答案和分析:

  前面我们谈了数组指针,现在又提到了指针数组,两者形式很相似,那么,如何区分两者的定义呢?分析如下:

  数组指针是:指向数组的指针,比如 int (*pA)[5]。

  指针数组是:指针构成的数组,比如int *pA[5]。

  至于上述指针数组的好处,大致有如下两个很普遍的原因:

  a)、各个指针内容能够按需要动态生成,避免了空间浪费。

  b)、各个指针呈数组形式排列,索引起来很方便。

  在实际编程中,选择使用指针数组大多都是想要获得如上两个好处。



[1] [2] 下一页

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 水滴石穿C语言之指针综合谈

下一篇: 水滴石穿C语言之内存使用

热门词条
热门标签