我能够做到这一点:
char * months[] = {"empty","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
unsigned short int month_index = 4;
printf("The %dth month of the year is \"%s\".\n", month_index, months[month_index]);
但是,如果我尝试使用双指针:
char ** months = {...};
它无法使用excess elements in scalar initializer
构建。这到底是什么意思,我将如何使用指向指针的指针初始化以上内容?
答案 0 :(得分:2)
类型控制所有内容
char *months[] = {"empty","jan",...};
将月份声明为char
的指针数组,其中初始化程序完成类型,提供 array < / strong>(“多少?”信息),并初始化每个指针以指向有效字符串的开头。完整类型为char *[13]
(由13个指针组成的数组。
如果您只是想声明:
char *months[];
您的编译器会抛出错误,抱怨months
是不完整类型。
在声明和初始化months
之后,通过C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)的操作,在访问时,月份的类型与char**
兼容,因为第一级间接转换为指针到第一个元素,则导致char**
的访问时间为几个月(以规则中的4个例外为准)。
为什么我不能仅仅声明char **months = {"empty","jan",...};
?
使用 pointer-to-pointer-to-type 完全不涉及数组。声明了多少个指针?尽管使用char *months[]...
数组的初始化程序 可以完成类型并提供 array 中元素的数量,但是使用char **months
,您只需有一个(指针)到指针,根本不涉及数组。以下声明的含义:
char **months;
months
只是一个未初始化的指针,其中包含一些不确定的地址。尝试更改不确定的内存位置的内容会导致 Undefined Behavior (可能是SegFault)。 C标准完全没有像 Array 那样提供指针对指针的初始化。 C11 Standard - 6.7.9 Initialization
它无法使用
excess elements in scalar initializer
构建。什么 到底是什么意思,以及如何使用 指针指向指针?
该错误虽然有些微妙,但却十分合理。声明时只有一个指针:
char **months;
如果您尝试使用初始化器列表(例如
)初始化单个指针char **months = { "empty", "jan", "feb", ... };
初始化器 ...
中有很多多余的元素您有两种方法可以初始化指针到指针的类型。 (1)您可以分配所需数量的指针,例如
char **months = malloc (13 * sizeof *months); /* allocate 13 pointers */
,然后为字符串中的第一个字符分配一个有效地址,或将其分配给13个指针中的每个指针,例如months[0] = "empty"; months[1] = "jan", ...
;或
(2),您可以分配与指针类型兼容的(单个)对象的有效地址,例如
char **my_months = months;
然后,您可以使用my_months[0]
访问每个单独的字符串,因为指向指针的指针现在指向有效存储,并且类型完整,使得my_months + 1
指向当前字符串之后的下一个字符串。例如:
#include <stdio.h>
int main (void) {
char *months[] = { "empty", "jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec" };
char **my_months = months;
size_t n = sizeof months / sizeof *months;
for (size_t i = 0; i < n; i++)
printf ("my_months[%2zu] : %s\n", i, my_months[i]);
}
使用/输出示例
$ ./bin/my_months
my_months[ 0] : empty
my_months[ 1] : jan
my_months[ 2] : feb
my_months[ 3] : mar
my_months[ 4] : apr
my_months[ 5] : may
my_months[ 6] : jun
my_months[ 7] : jul
my_months[ 8] : aug
my_months[ 9] : sep
my_months[10] : oct
my_months[11] : nov
my_months[12] : dec
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:1)
恐怕您想做的事是不可能的。 这不是C的工作方式,当涉及类型时,char **和char * [n]是两种不同的事物,因此您将无法使用char * [n]类型的实体来初始化char **。
与char **情况等效的是:
PCollection<Temperature> tempData = p.apply(AvroIO
.read(AvroAutoGenClass.class)
.from("gs://my_bucket/path/to/temp-sensor-data.avro")
PCollection<WindSpeed> windData = p.apply(AvroIO
.read(AvroAutoGenClass.class)
.from("gs://my_bucket/path/to/wind-sensor-data.avro")
PCollection<WindSpeed> tempDataWithWindSpeed = ?
如果只需要初始化,则使用char * [n]使其保持不变,这是正确的声明方式。
无论如何,您始终可以将其称为char **。
答案 2 :(得分:0)
这里是将指针数组分配给双指针的一种方法,希望这是您要寻找的:
<ul>
<li>one</li>
<li>two</li>
<li>
<ol>
<li>three</li>
<li>four</li>
<li>five</li>
</ol>
</li>
</ul>
输出:
#include<stdio.h>
int main()
{
char *arr[]={"hello","world"};
char **ptr=arr;
printf("%s\n",ptr[1]);
return 0;
}