用户反馈 :: Feedback
文档排行 :: Top
焦点讨论 :: Focus
文档资料 :: Document
资源下载 :: Download
关于这里 :: About
听说 char a[] 与 char *a 是一致的,是不是这样呢?
答案与分析:
指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部 ,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。请看以下的例子:
上述两个变量的内存布局分别如下:
数组 a 需要在内存中占用 8 个字节的空间,这段内存区通过名字 a 来标志。指针 p 则需要 4 个字节的空间来存放地址,这 4 个字节用名字 p 来标志 。其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。目前这个 p 指向某地连续的 8 个字节,即字符串“Hello, world!”。
另外,例如:对于 a[2] 和 p[2],二者都返回字符‘i’,但是编译器产生的执行代码却不一样。对于 a[2],执行代码是从 a 的位置开始,向后移动 2 两个字节,然后取出其中的字符。对于 p[2],执行代码是从 p 的位置取出一个地址,在其上加 2,然后取出对应内存中的字符。
为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?如何定义?
答案与分析:
使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的优点,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在 高维需要动态生成情况下的多维数组。
定义例子如下: int (*pElement)[2]
下面是一个例子:
上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。
需要说明的是,按照我们在第四篇讨论过的,指针的步进是参照其所指对象的大小的,因此,pa++将整个向后移 动一个数组的尺寸,而不是仅仅向后移 动一个数组元素的尺寸。
有如下定义:struct UT_TEST_STRUCT *pTo[2][MAX_NUM]; 请分析这个定义的意义,并尝试说明这样的定义可能有哪些好处?
答案与分析:
前面我们谈了数组指针,现在又提到了指针数组,两者形式很相似,那么,如何区分两者的定义呢?分析如下:
数组指针是:指向数组的指针,比如 int (*pA)[5]。
指针数组是:指针构成的数组,比如int *pA[5]。
至于上述指针数组的好处,大致有如下两个很普遍的原因:
在实际编程中,选择使用指针数组大多都是想要获得如上两个好处。
在做一个文本处理程序的时候,有这样一个问题:什么样的数据结构适合于按行存储文本?
答案与分析: [p]首先,我们来分析文本的特点,文本的主要特征是具有很强的动态性,一行文本的字符个数或多或少不确定,整个文本所拥有的文本行数也是不确定的。 这样的特征决定了用固定的二维数组存放文本行必然限制多多,缺乏灵活性。这种场合,使用指向指针的指针有很大的优越性。
现实中我们尝试用动态二维数组(本质就是指向指针的指针)来解决此问题:
图示是一个指针数组。所谓动态性指横向(对应每行文本的字符个数)和纵向(对应整个文本的行数)两个方向都可以变化。
就横向而言,因为指针的灵活性,它可以指向随意大小的字符数组,实现了横向动态性。
就竖向而言,可以动态生成及扩展需要的指针数组的大小。
下面的代码演示了这种动态数组的用途:
指针和数组分别有如下的特征:
假设有一个整数数组 a,a 和 &a 的区别是什么?
答案与分析:
a == &a == &a[0], 数组名 a 不占用存储空间。需要引用数组(非字符串)首地址的地方,我一般使用 &a[0],使用 a 容易和指针混淆,使用 &a 容易和非指针变量混淆。
区别在于二者的类型。对数组a的直接引用将产生一个指向数组第一个元素的指针,而&a的结果则产生一个指向全部数组的指针。例如:
请问:如下定义是什么意思 int *pF1(); int (*pF2)();
答案与分析:
首先清楚它们的定义:
可知: