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