为什么这个C代码示例使用指向指针的指针?

时间:2014-10-05 15:16:34

标签: c pointers

以下代码示例演示了指针和数组之间的相似之处。在第二种方法中,作者将cur_name声明为指针的指针。我的问题是,为什么这有必要?为什么他声明一个新指针而不是仅使用原始指针,名称?我应该注意,当我摆脱cur_name并使用名称时,代码编译并运行正常,所以它是风格而不是函数的问题?任何解释都将不胜感激。

#include <stdio.h>

int main(int argc, char *argv[])
{
    // create two arrays we care about
    int ages[] = {23, 43, 12, 89, 2};
    char *names[] = {"Alan", "Frank", "Mary", "John", "Lisa"};

    // safely get the size of ages
    int count = sizeof(ages) / sizeof(int);
    int i = 0;

    // first way using indexing
    for(i = 0; i < count; i++) {
        printf("%s has %d years alive.\n",
                names[i], ages[i]);
    }

    printf("---\n");

    // setup the pointers to the start of the arrays
    int *cur_age = ages;
    char **cur_name = names;

    // second way using pointers
    for(i = 0; i < count; i++) {
        printf("%s is %d years old.\n",
                *(cur_name+i), *(cur_age+i));
    }

    printf("---\n");

    // third way, pointers are just arrays
    for(i = 0; i < count; i++) {
        printf("%s is %d years old again.\n",
                cur_name[i], cur_age[i]);
    }

    printf("---\n");

    // fourth way with pointers in a stupid complex way
    for(cur_name = names, cur_age = ages;
            (cur_age - ages) < count;
            cur_name++, cur_age++)
    {
        printf("%s lived %d years so far.\n",
                *cur_name, *cur_age);
    }

    return 0;
}

3 个答案:

答案 0 :(得分:4)

代码使用指向指针的指针来表示指向C字符串数组的指针。即,cur_name是指向名为names的C字符串数组的指针。由于C中的字符串本身由指向char的指针表示,因此指向此类指针数组的指针将成为指向指针的指针。

  

为什么他声明一个新指针而不只是使用原始指针names

因为names不是指针,所以它是一个指针数组(请参阅声明后的方括号?这就是使names成为一个数组。前面的单个星号与数组元素的类型,在此程序中为char*

创建数组会增加间接级别:指向需要int的{​​{1}}数组,但要指向int*数组,需要{{1}指针。

答案 1 :(得分:2)

如果你有一个类型为T的数组,如下所示

T a[N];

然后如果要定义指向其第一个元素的指针,则必须编写

T *p = a;

现在用T代替定义为

的数组names的元素类型
char *names[] = {"Alan", "Frank", "Mary", "John", "Lisa"};

你会得到

typedef char * T;
T names[] = {"Alan", "Frank", "Mary", "John", "Lisa"};

所以指向数组第一个元素的指针看起来像

T *cur_name = names;

如果您现在将进行反向替换,您将获得

char * *cur_name = names;
^^^^^^
  T   

答案 2 :(得分:0)

作者确实在第四种方法中增加它们,所以他需要临时性,但你是正确的,在第二种方法中没有必要。也许他正在使用作业展示他们的等价?

我认为如果每个方法都在自己的函数中实现,那么示例会更清楚。