上一页 下一页

C 语言编程基础

在数组中使用指针

在 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 语言中的数组不同寻常,变量 ab 从技术上讲本身并不是数组。相反,它们是指向数组的永久指针。ab 永久指向它们各自数组的第一个元素——它们分别保存 a[0]b[0] 的地址。由于它们是永久指针,您无法更改它们的地址。因此,语句 a=b; 不起作用。

因为 ab 是指针,所以您可以使用指针和数组做一些有趣的事情。例如,以下代码有效:

#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);
}

for 循环开始执行前变量的状态。
十万个为什么.com

语句 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++);

如果您使用指针 pq 超出数组 ab 的末尾怎么办?C 语言并不会在意——它会漫不经心地递增 pq,随意地复制到其他变量上。在 C 语言中对数组进行索引时,您需要小心,因为 C 语言假定您知道自己在做什么。

您可以通过两种不同的方式将数组(例如 ab)传递给函数。假设有一个函数 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 函数可以接受可变大小的数组作为参数。