【问题标题】:Structs in C Error [closed]C错误中的结构[关闭]
【发布时间】:2015-08-25 10:49:13
【问题描述】:

我不明白为什么下面的代码不起作用:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <math.h>

struct data 

{

    int age;

    char name[20];

};


int main()
{
    struct data element[2];
    for (int j = 0; j < 2; j++)
    {
        element[j] = (struct data) malloc(sizeof(struct data));
        printf("Enter fav number%d? \n", j);
        scanf("d", &element[j].age);
        printf("Enter fav word? \n");
        scanf("s", &element[j].name);
    }
    printf("\nThis is what you entered:\n");
    for (int k = 0; k < 2; k++)
    {
        printf("%d. Fav number: %d\n", k, &element[k].age);
        printf("%d. Fav word: %s\n", k, &element[k].name);
    }
    return 0;
}

编译器错误提示:

beispiele.c: In function ‘main’:

beispiele.c:199:51: error: conversion to non-scalar type requested

   element[j] = (struct data) malloc(sizeof(struct data));

                                                   ^
beispiele.c:201:3: error: too many arguments for format [-Werror=format-extra-args]

   scanf("d", &element[j].age);

   ^
beispiele.c:203:3: error: too many arguments for format [-Werror=format-extra-args]

   scanf("s", &element[j].name);

   ^
beispiele.c:208:3: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Werror=format=]

   printf("%d. Fav number: %d\n", k, &element[k].age);

   ^
beispiele.c:209:3: error: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char (*)[20]’ [-Werror=format=]

   printf("%d. Fav word: %s\n", k, &element[k].name);

   ^

cc1: all warnings being treated as errors

【问题讨论】:

  • scanf 使用%d 和%s 分别读取整数和字符串。此外,您不必将 &amp;string_variable 作为参数传递。你必须通过 string_variable 因为它本身就是一个指针
  • element[i] 是一种自动存储结构,因此它已经分配了内存。从代码来看,这里不要malloc,只需要已经存在的两个元素。
  • 请激活警告,它会告诉您“printf”和scanf参数中的哪一个与格式说明符不匹配。
  • @MOehm 警告实际上是按照“cc1:所有警告都被视为错误”来激活的
  • @CoolGuy:是的,警告就在那里。抱歉,仅从代码判断。

标签: c struct


【解决方案1】:

element[j] 不是指针,而是数组的成员,因此它已经静态分配了内存。

如果你需要分配内存然后有指针数组。

struct data *element[2];

【讨论】:

  • 然而,这不是代码中唯一的错误。
  • @Lundin 是的,不是唯一的,而是最大的 :)
  • 将结果转换为非指针类型是一个严重的错误。
  • 为什么要使用 malloc?乔的答案更好。
  • @Alnitak 是的,这取决于 OP 想要什么。如果 OP 只是想尝试动态分配,他可能想要 malloc() 我没有建议 malloc() 只是展示了它的使用方法
【解决方案2】:

不需要使用malloc(数组分配所有内存)。

注意,使用printf不需要变量的地址,所以&amp;必须在变量前省略。您可以使用scanf,因为您必须传递要写入的变量的地址以便可以对其进行修改(请注意scanf 中的%d 和%s)。但是,使用char[20],您不需要&amp;,因为数组是指向20 个字符序列开头的指针。

int main()
{
    struct data element[2];
    for (int j = 0; j < 2; j++)
    {
        printf("Enter fav number%d? \n", j);
        scanf("%d", &element[j].age);
        printf("Enter fav word? \n");
        scanf("%s", element[j].name);
    }
    printf("\nThis is what you entered:\n");
    for (int k = 0; k < 2; k++)
    {
        printf("%d. Fav number: %d\n", k, element[k].age);
        printf("%d. Fav word: %s\n", k, element[k].name);
    }
    return 0;
}

【讨论】:

    【解决方案3】:

    你有几个问题:

    1. 格式说明符以% 符号开头。所以改变

      scanf("d", &element[j].age);
      

      到

      scanf("%d", &element[j].age);
      

      和

      scanf("s", &element[j].name);
      

      到

      scanf("%s", element[j].name);
      

      想知道为什么我从上面的scanf 中删除了&amp;?这是因为数组名称被转换为指向其第一个元素的指针。

    2. 这些

      printf("%d. Fav number: %d\n", k, &element[k].age);
      printf("%d. Fav word: %s\n", k, &element[k].name);
      

      应该是

      printf("%d. Fav number: %d\n", k, element[k].age);
      printf("%d. Fav word: %s\n", k, element[k].name);
      

      因为printf 中的%d 需要值(int)而不是变量的地址(int*)。同样,%s 需要 char*,而不是 char(*)[20]

    3. 这里的演员完全错误,应该删除:

      element[j] = (struct data) malloc(sizeof(struct data));
      

      这样做是因为malloc 返回void*,它可以分配给任何指针类型而无需强制转换。

        1. 等 查看其他答案。

    【讨论】:

      【解决方案4】:

      您会遇到 3 种类型的错误:

      1. beispiele.c:199:51: error: conversion to non-scalar type requested
        element[j] = (struct data) malloc(sizeof(struct data));

        检查malloc 的文档 - 它返回一个指向已分配内存的 void 指针,然后您尝试将其强制转换为结构。该结构显然不是指针类型,因此出现错误消息。

        确切地说,错误消息告诉您正在尝试转换为不是scalar 的类型(粗略和错误地说,这不是“基本”语言类型)。 C 风格的演员表非常宽容,并且会很乐意执行许多演员表,例如,long long * 到 long long,甚至没有警告。

        记住你should not cast是你从malloc得到的指针。

        另外,as others have pointed out,此声明:

        struct data element[2];

        声明并且自动分配element变量。通过调用malloc,您要求编译器再次动态分配它。如果您对内存分配感到困惑,请查看here。

      2. beispiele.c:201:3: error: too many arguments for format [-Werror=format-extra-args]
        scanf("d", &amp;element[j].age);

        scanf 和 printf 使用的格式字符串使用以 % 符号开头的格式说明符,您的所有调用中都缺少该符号。在这个特定的调用中,您的格式字符串 "d" 包含 0 个格式说明符,因此 scanf 需要 0 个变量地址来存储值。但是您提供了 1 个地址,因此编译器会抱怨“参数太多”。

        另外,请注意scanf 需要一个变量的地址,因为参数是passed by value - 如果它取而代之的是变量本身,则它无法存储在scanf 调用返回后可访问的数据。相比之下,printf 不需要修改变量,所以它需要变量而不是它们的地址。

      3. ^ beispiele.c:208:3: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Werror=format=]
        printf("%d. Fav number: %d\n", k, &amp;element[k].age);

        这个错误信息是不言自明的。关于printf的论点参考上一点。

      【讨论】:

        【解决方案5】:

        malloc 返回指向分配数据的指针,而不是实际数据。你不应该转换 malloc 的结果。

        相应地修复代码:

         struct data* element[2];
         ...
         element[j] = malloc(sizeof(struct data));
         ...
         free(element[j]);
        

        【讨论】:

          【解决方案6】:

          malloc 返回一个指向已分配内存的指针,但您将指针转换为 struct data。这就是编译器抱怨的原因

          错误:请求转换为非标量类型

          此外,您根本不需要分配内存,因为您已经这样做了

          struct data element[2];
          

          所以,当你删除 malloc 行时,这个错误应该消失了。

          【讨论】:

            猜你喜欢
            • 2018-10-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-08-18
            • 1970-01-01
            • 1970-01-01
            • 2019-03-03
            相关资源
            最近更新 更多