假设我们有以下数组:
char *names[]={"Abc", "Def", "Ghi", "Klm", "Nop"};
如果我们想创建一个指向上面数组的指针,我们为什么要使用两级指针,如下所示?
char **p1 = names;
感谢。
答案 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
中的第一个元素,对于大多数实际目的而言,喜欢指向数组(在内存中,数组是并置对象)。从技术上讲,你指的是第一个元素。