在结构中初始化数组

Initialize array within a structure

在我的项目中,我被要求将我的二维单词数组存储在一个动态数据结构中,然后在其他函数中将它们用于其他目的,但我很困惑我应该怎么做。我明白,如何分别命名它们:

#include <stdio.h>
#include <stdlib.h>

typedef struct Names {
    char *name[5];
} Names;

void func(Names y) {
    printf("%s\n%s", y.name[0], y.name[1]);
}

int main()
{
    Names y;
    y.name[0] = "John";
    y.name[1] = "Luke";
    func(y);

    return 0;
}

但是,如果我想将其作为二维数组来执行怎么办。所以通常我会做 char names[][10] = {"John", "Luke", etc..}; 但我如何将它存储在结构中?我的意思是如果我这样做了

#include <stdio.h>
#include <stdlib.h>

typedef struct Names {
    char *name[5][10];
} Names;

void func(Names y) {
    printf("%s\n%s", y.name[0], y.name[1]);
}

int main()
{
    Names y;
    y.name[][10] = {"John", "Luke"};
    func(y);

    return 0;
}

那只会产生错误并且毫无意义。

我认为您可能遗漏的事实是 char *name[5]; 并不是真正的二维单词数组,它是一个包含 5 个指向 char 的指针的数组,然后您将该数组的前两个指针指向到两个字符串文字。在第二个表达式中,你有一个 5 x 10 的二维指针数组,这些指针中的每一个也可以指向它自己的字符串文字,所以表达式很自然:

y.name[][10] = {"John", "Luke"};

由于多种原因不正确,编译器需要知道数组的两个维度才能知道要将字符串文字分配给哪个指针,知道这一点后您会注意到分配的表达式毫无意义。

示例:

y.name[1][1] = "John"; 

在这里,您可以将字符串文字“John”分配给位于指针数组索引 [1][1] 中的指针。

现在,如果您想要一个包含 5 个单词的数组,每个单词包含 10 个字符,包括空字节,您只需使用:

char name [5][10]

请注意,在此配置中,您不能简单地分配字符串,您需要使用 strcpy.

之类的东西来复制它们
strcpy(y.name[0], "John");

这是官方的做法(参见Nested initialization in: Struct and union initialization):

#include <stdio.h>

typedef struct Names {
    const char *name[2][2];
} Names;

void func(Names* y) {
    printf("%s, %s\n", y->name[0][0], y->name[0][1]);
    printf("%s, %s\n", y->name[1][0], y->name[1][1]);
}

int main()
{
    Names y = { .name={{"John", "Luke"}, {"Jack", "Jim"}}};
    func(&y);

    return 0;
}

出于反向词兼容性原因,以下内容也适用:

#include <stdio.h>

typedef struct Names {
    const char *name[2][2];
} Names;

void func(Names* y) {
    printf("%s, %s\n", y->name[0][0], y->name[0][1]);
    printf("%s, %s\n", y->name[1][0], y->name[1][1]);
}

int main()
{
    Names y = {"John", "Luke", "Jack", "Jim"};
    func(&y);

    return 0;
}

上面是管理存储在const char指针中的字符串常量,对于最长为9chars的可变字符串,尾随零终止符,像下面这样的东西是可能的(我为 5 和 9 创建了编译时常量):

#include <stdio.h>

enum {
    NAME_COUNT = 5,
    NAME_LENGTH = 9
};
typedef struct Names {
    char name[NAME_COUNT][NAME_LENGTH+1];
} Names;

void func(Names* y) {
    for (int i=0; i<NAME_COUNT; ++i) {
        printf("%s\n", y->name[i]);
    }
}

int main()
{
    Names y = { .name={"John", "Olivia", "Luke", "Mary", "Jane" }};
    func(&y);

    return 0;
}