【问题标题】:* is illegal for a struct?* 对于结构来说是非法的吗?
【发布时间】:2009-10-25 22:38:17
【问题描述】:

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

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

void main(){

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

}

【问题讨论】:

  • 在您的代码中 Stringstruct String 类型的对象。
  • 那我该如何解决呢?
  • 在您的代码中,Stringstruct String 类型的对象。类似于:int a; void main() {; a *b = malloc(sizeof *b);}
  • 换句话说,结构声明末尾的String 声明了一个名为String 的String 实例。我猜你想去掉尾随的“字符串”。

标签: c struct pointers


【解决方案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);
}

【讨论】:

    【解决方案2】:

    由于似乎还没有人提到这一点,让我解释一下使用的代码的实际含义。

    你使用的是一种简写符号,它定义了一个结构并且创建了一个变量。相当于:

    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”的全局变量,但在此表达式中没有意义。

    【讨论】:

      【解决方案3】:

      你忘了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);
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          使用此代码:

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

          你也可以考虑typedef

          typedef struct String sString;
          

          会让你使用你的sn-p:

          sString* mystring
          

          【讨论】:

            【解决方案6】:

            试试:

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

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

            【讨论】:

              【解决方案7】:

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


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

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

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

              【讨论】:

                【解决方案8】:

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

                #include <stdlib.h>
                
                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。

                【讨论】:

                  猜你喜欢
                  • 2013-11-12
                  • 1970-01-01
                  • 2011-11-23
                  • 2022-12-20
                  • 2021-06-29
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多