二维字符串数组的复合文字
Compound literal for two-dimensional array of strings
我在结构中有一个二维字符串数组,我希望能够在编译时使用复合文字而不是动态地使用 malloc() 对其进行初始化。
这个字符串数组的意思是它是一个项目数组,每个项目有三个字符串(一个是项目的名称,一个是描述,另一个是URL) .
是的,我知道我可以改用三个数组,但我更愿意将它打包成一个二维数组。
我试着这样写(请注意,我只是初始化项目的名称,而不是描述或 URL...这是故意的,因为我假设指针根据描述,URL 将根据指定的初始化行为自动初始化为 NULL——当你不初始化一个字段时,它变为零)
我的尝试:
enum labelkind {
L_NAME,
L_DESCRIPTION,
L_URL,
L_NUMKINDS};
struct labeltype{
int someval;
size_t nlabels;
char **labels[L_NUMKINDS];
};
static struct labeltype mylabel = {
.someval=10,
.nlabels=3,
.labels=(char *[][L_NUMKINDS]){
[0][L_NAME]="First name",
[1][L_NAME]="Second name",
[2][L_NAME]="Third name"
}
};
用 clang 编译它,我收到这些警告:
main.c:266:10: warning: incompatible pointer types initializing 'char **' with an expression of type 'char *[3][3]'
[-Wincompatible-pointer-types]
.labels=(char *[][L_NUMKINDS]){
^~~~~~~~~~~~~~~~~~~~~~~
main.c:266:10: warning: suggest braces around initialization of subobject [-Wmissing-braces]
.labels=(char *[][L_NUMKINDS]){
^~~~~~~~~~~~~~~~~~~~~~~
{
所以,根据这些警告,我想我做错了什么。
执行此操作的正确语法是什么?
结构定义不正确:按照定义,labels
是一个数组 L_NUMKINDS
指向 char
的指针。您可能希望 labels
指向一个 nlabels
数组 L_NUMKINDS
指向 char
的数组。定义应该是 char *(*labels)[L_NUMKINDS];
或更好的 const char *(*labels)[L_NUMKINDS];
因为你想使用字符串常量作为初始值设定项。
这是带有测试程序的修改版本:
#include <stdio.h>
enum labelkind {
L_NAME,
L_DESCRIPTION,
L_URL,
L_NUMKINDS
};
struct labeltype {
int someval;
size_t nlabels;
const char *(*labels)[L_NUMKINDS];
};
static struct labeltype mylabel = {
.someval = 10,
.nlabels = 4,
.labels = (const char *[][L_NUMKINDS]) {
[0][L_NAME] = "First name",
[1][L_NAME] = "Second name",
[2][L_NAME] = "Third name",
[3][L_NAME] = "Fourth name",
}
};
static void pstr(const char *name, const char *s) {
printf("%s: ", name);
if (s)
printf("\"%s\"", s);
else
printf("null");
}
static void print_labels(const struct labeltype *lp) {
for (size_t i = 0; i < lp->nlabels; i++) {
printf("{ ");
pstr("name", lp->labels[i][L_NAME]);
printf(", ");
pstr("description", lp->labels[i][L_DESCRIPTION]);
printf(", ");
pstr("url", lp->labels[i][L_URL]);
printf(" }\n");
}
}
int main() {
print_labels(&mylabel);
return 0;
}
输出:
{ name: "First name", description: null, url: null }
{ name: "Second name", description: null, url: null }
{ name: "Third name", description: null, url: null }
{ name: "Fourth name", description: null, url: null }
我在结构中有一个二维字符串数组,我希望能够在编译时使用复合文字而不是动态地使用 malloc() 对其进行初始化。
这个字符串数组的意思是它是一个项目数组,每个项目有三个字符串(一个是项目的名称,一个是描述,另一个是URL) .
是的,我知道我可以改用三个数组,但我更愿意将它打包成一个二维数组。
我试着这样写(请注意,我只是初始化项目的名称,而不是描述或 URL...这是故意的,因为我假设指针根据描述,URL 将根据指定的初始化行为自动初始化为 NULL——当你不初始化一个字段时,它变为零)
我的尝试:
enum labelkind {
L_NAME,
L_DESCRIPTION,
L_URL,
L_NUMKINDS};
struct labeltype{
int someval;
size_t nlabels;
char **labels[L_NUMKINDS];
};
static struct labeltype mylabel = {
.someval=10,
.nlabels=3,
.labels=(char *[][L_NUMKINDS]){
[0][L_NAME]="First name",
[1][L_NAME]="Second name",
[2][L_NAME]="Third name"
}
};
用 clang 编译它,我收到这些警告:
main.c:266:10: warning: incompatible pointer types initializing 'char **' with an expression of type 'char *[3][3]'
[-Wincompatible-pointer-types]
.labels=(char *[][L_NUMKINDS]){
^~~~~~~~~~~~~~~~~~~~~~~
main.c:266:10: warning: suggest braces around initialization of subobject [-Wmissing-braces]
.labels=(char *[][L_NUMKINDS]){
^~~~~~~~~~~~~~~~~~~~~~~
{
所以,根据这些警告,我想我做错了什么。
执行此操作的正确语法是什么?
结构定义不正确:按照定义,labels
是一个数组 L_NUMKINDS
指向 char
的指针。您可能希望 labels
指向一个 nlabels
数组 L_NUMKINDS
指向 char
的数组。定义应该是 char *(*labels)[L_NUMKINDS];
或更好的 const char *(*labels)[L_NUMKINDS];
因为你想使用字符串常量作为初始值设定项。
这是带有测试程序的修改版本:
#include <stdio.h>
enum labelkind {
L_NAME,
L_DESCRIPTION,
L_URL,
L_NUMKINDS
};
struct labeltype {
int someval;
size_t nlabels;
const char *(*labels)[L_NUMKINDS];
};
static struct labeltype mylabel = {
.someval = 10,
.nlabels = 4,
.labels = (const char *[][L_NUMKINDS]) {
[0][L_NAME] = "First name",
[1][L_NAME] = "Second name",
[2][L_NAME] = "Third name",
[3][L_NAME] = "Fourth name",
}
};
static void pstr(const char *name, const char *s) {
printf("%s: ", name);
if (s)
printf("\"%s\"", s);
else
printf("null");
}
static void print_labels(const struct labeltype *lp) {
for (size_t i = 0; i < lp->nlabels; i++) {
printf("{ ");
pstr("name", lp->labels[i][L_NAME]);
printf(", ");
pstr("description", lp->labels[i][L_DESCRIPTION]);
printf(", ");
pstr("url", lp->labels[i][L_URL]);
printf(" }\n");
}
}
int main() {
print_labels(&mylabel);
return 0;
}
输出:
{ name: "First name", description: null, url: null }
{ name: "Second name", description: null, url: null }
{ name: "Third name", description: null, url: null }
{ name: "Fourth name", description: null, url: null }