*结构是非法的?

我试图编译以下代码,但编译器不会这样做,因为“*对于结构体来说是非法的”是真的吗?

struct String { int length; int capacity; unsigned check; char ptr[0]; } String; void main(){ char *s; String *new_string = malloc(sizeof(String) + 10 + 1); } 

要么使用typedef:

 typedef struct String { int length; int capacity; unsigned check; char ptr[0]; } String; /* now String is a type */ 

或者明确地说struct String

 void main(){ char *s; struct String *new_string = malloc(sizeof(struct String) + 10 + 1); } 

由于似乎没有人提到这一点,让我解释一下使用的代码究竟意味着什么。

你使用的是一种速记符号,它定义一个结构创建一个变量。 它相当于:

 struct String { int length; int capacity; unsigned check; char ptr[0]; }; struct String String; //creates a global variable of type "struct String" 

后来,

 String *new_string 

无法编译,因为没有名称为“String”的类型名称(仅限于“struct String”。有一个全局变量,其名称为“String”但在此表达式中没有意义。

你忘了typedef

 typedef struct String { int length; int capacity; unsigned check; char ptr[0]; } String; /* String is now a type, not an object */ void main(){ char *s; String *new_string = malloc(sizeof(String) + 10 + 1); } 

是的,它是真实的。 二进制*运算符(乘法)仅适用于算术类型。 在您的示例中,您声明了一个类型为struct Struct的变量Struct ,然后尝试将其乘以某个东西。 这没有任何意义。 您不能将struct对象相乘。 这就是编译器告诉你的。

另外:1。这是int main ,而不是void main 。 2. C语言不支持大小为0的数组声明。您可能希望更改结构类型中的数组声明。

使用此代码:

 struct String* new_string = malloc(sizeof(String)+10+1); 

你也可以考虑typedef

 typedef struct String sString; 

会让你使用你的代码片段:

 sString* mystring 

尝试:

  typedef struct String_t { int length; int capacity; unsigned check; char ptr[0]; } String; 

你的并没有完全宣布这样的类型。 更具体地说,它通过引入同名变量来隐藏您的类型。 这让编译器感到困惑…… 🙂

编辑:我现在看到原始问题被标记为C而不是C++ ,有人错误地将其标记为C++ (恢复了标记)。


正如其他人提到的,一种解决方案是在struct声明之前添加一个typedef ,但是因为这是C++ (根据问题的标签)而不是C ,更惯用和更简单的方法就是删除尾随的“String”

 struct String { int length; int capacity; unsigned check; char ptr[0]; }; 

这足以引入一个名为String的类型,原始代码不起作用的原因除了引入一个名为String的类型之外,还引入了一个名为String的变量来隐藏类型。

正如artelius先前所写,你的结构定义可能不是你想要的。 最简单的解决方法是:

 #include  struct String { int length; int capacity; unsigned check; char ptr[0]; }; int main(){ char *s; String *new_string = (String*)malloc(sizeof(String) + 10 + 1); return 0; } 

当我使用gcc和g ++进行测试时,这实际上也会编译。 如果您真的在使用C ++,那么您应该包含cstdlib而不是stdlib.h,或者正确地执行它(tm)并将您的字符串转换为类并使用new。