【问题标题】:Passing an Array to a structure in C将数组传递给C中的结构
【发布时间】:2014-11-26 15:20:37
【问题描述】:

为了用整数填充结构(然后在程序中进一步传递),我认为以下方法可行:

main() {
struct songs {int pitch[5], length[5];} songs[4];
int i[5]={1,22,23,14,52};
int k=0;
 songs[0].pitch=i;      
 for (k=0; k<5; k++) printf("%d\n",songs[0].pitch[k]);
}

但是这会出现错误“分配中的类型不兼容”

如果我不将此数组传递给结构,请使用以下内容:

main() {
int i[5]={1,22,23,14,52};
int k=0;   
 for (k=0; k<5; k++) printf("%d\n",i[k]);
}   

它会编译并显示数组的内容。

我意识到这可能有一个简单的解决方法,但任何帮助都会很棒!

提前致谢

【问题讨论】:

  • 添加了 C89 标记,因为您依赖于在 C99 中删除的“默认为 int”规则。
  • 不能像在 C 中那样分配数组。您需要循环将数组的每个元素复制到另一个数组或按照答案中的建议使用memcpy

标签: c arrays struct c89


【解决方案1】:

C89 不允许您将一个数组分配给另一个数组。这是 C99 中的相关位,但 C89 中的文本大致相同,只是提到了 C99 唯一类型 _Bool。 (我只有C89的纸质版)

数组不符合任何这些条件——它们不是算术类型,它们不是结构或联合类型,它们也不是指针1。因此,您不能对它们使用赋值运算符。

但是,您可以使用memcpy。如果你替换这一行:

songs[0].pitch=i; 

用这一行:

memcpy(songs[0].pitch, i, sizeof(i));

你会得到你期望的行为。 (当然首先包括&lt;string.h&gt;


1 从技术上讲,6.3.2.1/3 说数组在被operator= 看到之前被转换成rvalue 指针,但是这样的赋值仍然是禁止,因为 6.5.16/2 要求赋值的左侧是 左值

【讨论】:

  • 如果我错了请纠正我,但你告诉他复制 4 个字节,地址为isizeof(i) 是 4,因为它只是一个指针;即使你说sizeof *i,那仍然是4,因为*iint
  • afaik,在 C 中,当您声明一个数组时,该变量实际上是指向前面类型名称的指针。它确实指向“数组”的第一个条目,但没有什么“是数组”。 afaik,C 中没有这样的东西。它只是一个指向内存块的指针。
  • @Hame:不,它不是这样工作的。数组可以隐式转换为指向其第一个元素的指针,但这并不意味着它是指向其第一个元素的指针。 ideone.com/MvwVVc
  • @mafso 你有关于为什么会发生这种转换的标准参考吗?本节非常具体地说明了实际类型而不是转换后的类型。如果你有参考,我会更新答案。
  • 6.3.2.1 p3 似乎表明了这一点,尽管我并不完全确定。您是对的,将您引用的约束解释为指的是左值转换类型是没有意义的。所以这两个约束似乎都被违反了。
【解决方案2】:

由于 C 处理数组的方式,您无法将其分配给这样的数组。您需要单独或通过memcpy(或类似功能)复制这些值。示例:

for (k=0; k<5; k++){
    songs[0].i[k] = i[k];
}

或:

memcpy(songs[0].i, i, sizeof i);

请注意,memcpy 要求您包含 &lt;string.h&gt;

【讨论】:

    【解决方案3】:

    您需要单独复制数组元素。此外,主函数确实应该返回一个 int。

    int main( void ) {
    struct songs {int pitch[5], length[5];} songs[4];
    int i[5]={1,22,23,14,52};
    int qq, k=0;
     for( qq=0; qq<5; qq++) {
       songs[0].pitch[qq]=i[qq];      
     }
     for (k=0; k<5; k++) printf("%d\n",songs[0].pitch[k]);
    return 0;
    }
    

    【讨论】:

    • @Billy ONeal-sure,真正的代码也不应该乱扔幻数。但我认为这很好地展示了这个概念。
    • 当然,这就是我没有 -1 的原因。但认为评论仍然值得:)
    【解决方案4】:

    C 不允许您将数组复制到数组中。您必须逐个元素地复制。

        struct songs {int pitch[5], length[5];} songs[4];
        int i[5]={1,22,23,14,52};
        int k=0;
        for (k=0; k<5; k++) songs[0].pitch[k] = i[k];
        for (k=0; k<5; k++) printf("%d\n",songs[0].pitch[k]);
    

    【讨论】:

      【解决方案5】:

      当你声明一个数组时,你有两个选择:

      int * i;     // #1; you do this when you don`t know the size
      int i[size]; // #2
      

      您不能将一个数组分配给另一个数组。

      正如其他人所建议的,您需要做的是一个一个地复制数组的所有元素:

          for (int j = 0; j < 5; j++) {
              songs[0].pitch[j] = i[j];
          }
      

      请记住,使用索引运算符 [] 与取消引用指针相同。

      更重要的是,当您说pitch[j] 时,您实际上将指针 j 位置向前移动并取消引用它;就像你会说*(pitch+j)

      【讨论】:

        【解决方案6】:
        the following, compiles, runs, works.
        
        notice the correction to the declaration of main
        notice the addition of #include string.h to support memcpy function
        notice the proper return statement at the end
        
        and most importantly,
        notice the correct method of copying an array
        
        as a side note:
        making the struct tag name and the instance name the same
        is very bad programming practice
        
        #include <stdio.h>
        #include <string.h>
        
        int main()
        {
            struct songs
            {
                int pitch[5];
                int length[5];
            } songs[4];
        
            int i[5]={1,22,23,14,52};
            int k=0;
            memcpy( songs[0].pitch, i, sizeof( i ) );
            for (k=0; k<5; k++) 
            {
                printf("%d\n",songs[0].pitch[k]);
            } // end for
        
            return(0);
        }
        

        【讨论】:

          【解决方案7】:

          问题来了,

          songs[0].pitch=i;
          

          在结构体中使用int*,不能将一个数组赋值给另一个数组以及结构体名称和结构体对象。

          这会起作用。

          struct Songs {int* pitch, length[5];} songs[4];
          

          【讨论】:

          • 这与 OP 最初发布的代码具有非常不同的语义。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 1970-01-01
          • 2014-05-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多