C语言中的不寻常结构体

4

我该如何理解由两个字符串组成的数组?

static struct S1 {
    char c[3], *s;
} s1 = {"abc", "def" };

也许我的问题不正确,但我很难理解它是如何工作的


问题标题与问题内容不符。你确切想问什么? - rustyx
3
C11 6.7.9p14规定,只有在空间足够的情况下才包括空字符终止符。这不是未定义行为。 - KamilCuk
@durnovv,你有这个例子的来源提示吗? - Jörg Beyer
1
@KamilCuk 如果有人试图将这个数组用作字符串,那么可能会出现这种情况。 - 0___________
关于static struct S1 { char c[3], *s; } s1 = {"abc", "def" };的内容,字符串总是以一个NUL字节结尾。所以这些3个字节的字符串实际上是4个字节。建议修改为:static struct S1 { char c[4]; char *s; } s1 = {"abc", "def" }; - user3629249
4个回答

4

S1.c 有 3 个字节的空间,S1.s 是一个指向字符串的指针。

第一部分定义了这个结构:

struct S1 {
    char c[3], *s;
};

下一部分创建了该类型的实例,并使用几个值进行初始化:
static struct S1 s1 = {"abc", "def" };

static 不是结构体定义的一部分,它指的是实例变量的可见性。


这句话的意思是 S1.c = "abc"; 和 S1 -> s = "def"; 吗? - cellka
不,S1 是一个类型。s1 是 S1 类型的对象。一个对象使用点号(".")来引用组件。指针使用箭头("->")。 - Jörg Beyer
“static” 不是结构声明的一部分,而是变量 “s1” 的存储修饰符。 - KamilCuk
@KamilCuk,你是对的,我在答案中澄清了这一点。 - Jörg Beyer
请澄清您在答案中缺少什么,这样我就可以添加。如果您喜欢它,请接受答案(将为答案添加绿色复选标记)。 - Jörg Beyer
1
static 影响作用域、链接和生命周期,而不仅仅是作用域(可见性)。 - Eric Postpischil

2

第一个初始化器"abc"将这3个字符复制到成员char c[3]中。由于没有空间用于字符串终止符,因此它是一个简单的数组,不能被视为字符串。

第二个初始化器"def"将指针复制到成员char *s中。它指向放置在只读内存中的字符串文字"def"。它可以被视为字符串,但不能被修改。


1
无论“def”是否放置在只读内存中取决于实现,这不是C标准所要求的。 - Eric Postpischil

1
初始化程序{"abc", "def" }不是一个数组。在这种情况下,它用于初始化结构体的实例。

1
这不是相同的代码,但可以帮助理解正在发生的事情,首先它不是数组。该结构有2个元素。
#include <stdio.h>

struct S1 {
    char c[3];
    char* s;   
};

int main(void) {
    struct S1 s1 = { .c = "abc", .s = "def" };
    printf("s1.c: %.*s\n", 3, (char*) s1.c);
    printf("s1.s: %s\n", s1.s);
}

抱歉,为什么要通过指针访问数组“c”?我的意思是第一个打印语句中的星号。 - cellka
2
这个答案是C++代码,而不是问题标记的C语言。但这并不是我的DV,因为我也发布了一个答案。 - Weather Vane
我没有看到任何不是 C99 的东西? - Neil
1
@NeilEdelman 那条评论是在我将其改为C之前发布的。它之前使用的是std::stringstd::cout - Artyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接