在数组中使用指针
在 C 语言中,数组和指针密切相关。要有效使用数组,您必须了解如何将指针与它们结合使用。完全理解两者之间的关系可能需要数天的学习和实验,但这绝对值得付出努力。
让我们从一个简单的 C 语言数组示例开始
广告
#define MAX 10 int main() { int a[MAX]; int b[MAX]; int i; for(i=0; i<MAX; i++) a[i]=i; b=a; return 0; }
输入这段代码并尝试编译它。您会发现 C 语言无法编译它。如果您想将 a 复制到 b 中,您必须输入类似以下的代码:
for (i=0; i<MAX; i++) b[i]=a[i];
或者,更简洁地说
for (i=0; i<MAX; b[i]=a[i], i++);
更好的方法是,使用 string.h 中的 memcpy 工具。
C 语言中的数组不同寻常,变量 a 和 b 从技术上讲本身并不是数组。相反,它们是指向数组的永久指针。a 和 b 永久指向它们各自数组的第一个元素——它们分别保存 a[0] 和 b[0] 的地址。由于它们是永久指针,您无法更改它们的地址。因此,语句 a=b; 不起作用。
因为 a 和 b 是指针,所以您可以使用指针和数组做一些有趣的事情。例如,以下代码有效:
#define MAX 10 void main() { int a[MAX]; int i; int *p; p=a; for(i=0; i<MAX; i++) a[i]=i; printf("%d\n",*p); }
语句 p=a; 有效,因为 a 是一个指针。从技术上讲,a 指向实际数组的第 0 个元素的地址。此元素是一个整数,因此 a 是指向单个整数的指针。因此,将 p 声明为整数指针并将其设置为等于 a 是有效的。另一种表达方式是,将 p=a; 替换为 p=&a[0];。由于 a 包含 a[0] 的地址,因此 a 和 &a[0] 的含义相同。
现在 p 指向 a 的第 0 个元素,您可以用它做一些相当奇怪的事情。变量 a 是一个永久指针,不能被更改,但 p 不受此类限制。C 语言实际上鼓励您使用指针算术来移动它。例如,如果您写 p++;,编译器知道 p 指向一个整数,因此此语句会按适当的字节数增加 p,将其移动到数组的下一个元素。如果 p 指向一个由 100 字节长结构组成的数组,那么 p++; 会将 p 移动 100 个字节。C 语言会处理元素大小的细节。
您也可以使用指针将数组 a 复制到 b 中。以下代码可以替换 (for i=0; i<MAX; a[i]=b[i], i++);
p=a; q=b; for (i=0; i<MAX; i++) { *q = *p; q++; p++; }
您可以将此代码缩写如下
p=a; q=b; for (i=0; i<MAX; i++) *q++ = *p++;
您还可以将其进一步缩写为
for (p=a,q=b,i=0; i<MAX; *q++ = *p++, i++);
如果您使用指针 p 或 q 超出数组 a 或 b 的末尾怎么办?C 语言并不会在意——它会漫不经心地递增 p 和 q,随意地复制到其他变量上。在 C 语言中对数组进行索引时,您需要小心,因为 C 语言假定您知道自己在做什么。
您可以通过两种不同的方式将数组(例如 a 或 b)传递给函数。假设有一个函数 dump,它接受一个整数数组作为参数,并将数组内容打印到标准输出。有两种方法可以编写 dump 函数:
void dump(int a[],int nia) { int i; for (i=0; i<nia; i++) printf("%d\n",a[i]); }
或
void dump(int *p,int nia) { int i; for (i=0; i<nia; i++) printf("%d\n",*p++); }
需要 nia(数组中的数字)变量以知道数组的大小。请注意,传递给函数的只是数组的指针,而不是数组的内容。另请注意,C 函数可以接受可变大小的数组作为参数。