我有一段代码,当我try 编译它时它不能工作:

#include <stdio.h>

struct s{
    char a;
}s1 = 'A';

int main(){
    struct s *ptr = &s1;
    printf("%c", ptr->a);
}

但是,当我try 使用数组运行类似的代码段时,它工作得非常好:

#include <stdio.h>

struct s{
    char *q;
}s1[]= {"A"};

int main(){
    struct s *ptr = &s1;
    printf("%s", ptr->q);
}

为什么当我在 struct 中使用指针而不是普通的字符时,它会起作用,不是用来访问 struct 变量的成员的箭头操作符吗?

我原以为第一段代码会给出与第一段代码类似的输出,但它给出了一个错误,提示我"初始化无效".我只是不明白为什么它可以与数组和指针一起工作,而不是简单的字符.

推荐答案

您需要像初始化第二个 struct 的对象一样,将整型字符常量括在大括号中

struct s{
    char a;
}s1 = { 'A' };

来自C标准(6.7.9初始化)

否则,具有Aggregate或 联合类型应该是用大括号括起来的初始值设定项列表 元素或命名成员.

使用字符串文字作为可以不带大括号的字符数组的初始值设定项是不允许的.

例如,这些声明是等价的

char s[] = { "Hello" };

char s[] = "Hello";

然而,第二个方案也是不正确的.

您声明了一个 struct 类型的对象数组

struct s{
    char *q;
}s1[]= {"A"};

该声明相当于

struct s{
    char *q;
}s1[1]= {"A"};

Such an initialization is valid due to the C St和ard (6.7.9 Initialization)

20 If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace 和 its matching right brace initialize the elements or members of the subaggregate or the contained union. Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.

表达式&s1具有类型struct s( * )[1],但它被赋给类型struct s *的指针

struct s *ptr = &s1;

这些指针类型之间不存在隐式转换.

编译器应该发出警告.您不应忽略编译器警告.

该代码之所以有效,是因为 struct 类型的对象的地址等于其第一个数据成员的地址.

C++相关问答推荐

需要大整数和浮点数.使用long long int和long double

为什么GCC可以调用未定义的函数?

两个连续的语句是否按顺序排列?

如果包含路径不存在,我的编译器可以被配置为出错吗?(GCC、MSVC)

Linux不想运行编译后的文件

每个 struct 变量在C中都有自己的命名空间吗?

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

在函数外部使用内联ASM时无法指定操作数

判断系统命令返回值的正确方法

我可以创建适用于不同endian的 colored颜色 struct 吗?

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

如何在MSVC中使用intSafe.h函数?

C中的数组下标和指针算法给出了不同的结果

在同一范围内对具有相同类型的变量执行的相同操作在同一C代码中花费的时间不同

GCC认为这是一个VLA是对的吗?

模仿 memmove 的行为

可以从指针数组中的值初始化指针吗?

C 预处理器中的标记分隔符列表

当 a 是代码块时使用逗号运算符 (a, b)

当最大成员是原始类型时,联合是否可以大于最大成员?