两级指针

时间:2015-08-04 09:24:48

标签: c pointers

假设我们有以下数组:

char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};

如果我们想创建一个指向上面数组的指针,我们为什么要使用两级指针,如下所示?

char **p1 = names;

感谢。

5 个答案:

答案 0 :(得分:4)

您的names[]的数组char *,即指向char的指针数组。

同时p1是一个指针指向char的指针,即指向char *的指针。您可以为其分配names,因为数组会衰减到指向其第一个元素的指针,而names的第一个元素是指向char的指针,因此names会衰减到char *指向char **的指针。这是同一类型 - p1 - 与names相同,因此它们是兼容的。

(另一方面,const char *names[]的元素类型不正确;字符串文字是常量,因此它应该是p1,类似const char**应该是const char } - 指向$('#CheckAll').change(function () { ($(this).is(":checked") ? $('.checkboxes').prop("checked", true) : $('.checkboxes').prop("checked", false)) });的指针。)

答案 1 :(得分:1)

你可以这样看,当你需要指向一个整数数组时,你需要使用指向int 的指针。

int arr[];
int* a;

a = arr;

因此,在此上下文中,您需要一个指向数组names[]中元素的指针。该数组中的元素是什么。它的char*。所以你需要一个指向char*指针。这转换为指向char 指针的指针。 那是

char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};

char **p1 = names;

答案 2 :(得分:0)

如果要创建指向数组的指针

char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};

然后你必须写

char * ( *p1 )[sizeof( names ) / sizeof( *names )] = &names;

如果你想创建一个指向数组元素的指针,那么你确实应该写

char **p1 = names;

在这种情况下,指针p1由字符串文字"Abc"的第一个字符的地址地址初始化。

因此,例如,表达式*p1将包含数组names的第一个元素的值,而该值又是(值)是字符串文字"Abc"的第一个字符的地址,类型为char *

如果您将第二次应用解除引用**p1,您将获得字符串文字的第一个字符_le 'A'

例如

printf( "%c\n", **p1 );

为了更清楚,让我们考虑一般情况。 如果您的数组中包含类型为T的元素

T a[N];

然后表达式中的这个数组被转换为指向其第一个元素T *的指针。所以如果你想自己声明这样的指针,你应该写

T *p1 = a;

此记录相当于

T *p1 = &a[0];

在原始示例中,类型T对应于类型char * - 阵列名称元素的类型。因此,在char *代替T后,您将获得

char * *p1 = names;
^^^^^^
  T

答案 3 :(得分:0)

你没有创建指针数组的指针。它实际上是指向数组第一个指针的指针。

如果你想创建一个指针数组的指针,写下这样的东西 -

char *names[MAX];
char* (*p1)[MAX] = &names;

答案 4 :(得分:-1)

编辑:由于注释,数组实际上绑定在此处:因为编译器可以从初始化器中推断出它的大小。

从其声明中,names是:指向char的指针数组。绑定数组衰减指向其第一个元素的指针。 names的元素是char的指针,当在表达式names中使用时,它被隐式转换为指向char的指针。

这就是为什么你可以在第二行分配names

char **p1 = names;

所以p1指向names中的第一个元素,对于大多数实际目的而言,喜欢指向数组(在内存中,数组是并置对象)。从技术上讲,你指的是第一个元素。