【问题标题】:Allocating memory to an array and changing a value in将内存分配给数组并更改其中的值
【发布时间】:2021-08-22 17:19:16
【问题描述】:

我编写了非常简单的代码,我曾经对此充满信心,但它不起作用。我不知道我做错了什么,或者我的 vscode 有问题。我已经为整数和字符数组分配了内存,然后我使用 scanf 来读取我想要保存在所述数组中的值。但是当我使用 printfs 进行调试时,它似乎将这些值保存为垃圾值。

对于上下文:tamanhos = 大小,应该是 p、P、g 或 G,而 quantidades 应该是整数

#include <stdio.h>
#include <stdlib.h>
#define professores 7
int main () {
    int quantidade, total, holder;
    char tamanho;

    total = 0;

    int * quantidades = (int*)malloc(professores*sizeof(int));
    char * tamanhos = (char*)malloc(professores*sizeof(char));

    for (int i = 0; i < 7; i++){
        scanf(" %d", &quantidade);
        scanf(" %c", &tamanho);
        quantidades[i] = quantidade;
        tamanhos[i] = tamanho;
    }

    printf("%d", total);

    for (int i = 0; i < 7; i++ ){
        if (tamanhos[i] == "P" || tamanhos[i] == "p") {
            holder = quantidades[i];
            total = total + quantidades[i]*10;
        }
        else if (tamanhos[i] == "G" || tamanhos[i] == "g") {
            total = total + quantidades[i]*16;
        }
    }
    printf("%d\n", total);
    int xprof = total / 7;
    printf("%d", xprof);

    free(quantidades);
    free(tamanhos);

    return 0;
}

【问题讨论】:

  • 旁注,在循环控件和除数中使用professores 而不是硬编码7
  • 同时避免强制转换 malloc 的输出 (cf stackoverflow.com/questions/605845/…)
  • 我发现你的代码有问题。您的 scanf 语句正在使用 & 运算符。结果不是 *quantidades,而是得到 **quantidades,它是指向指针的指针。删除 & 它应该可以正常工作。 & 是运算符的地址,它提供了相关项的内存地址。由于您的变量已经是指针,因此无需使用它。

标签: arrays c


【解决方案1】:

在 C 和 C++ 中,单引号标识单个字符,而双引号创建字符串文字。您正在比较字符,因此请使用单引号而不是双引号。

#include <stdio.h>
#include <stdlib.h>
#define professores 7
int main () {
    int quantidade, total = 0, holder;
    char tamanho;    
    int * quantidades = (int*)malloc(professores*sizeof(int));
    char * tamanhos = (char*)malloc(professores*sizeof(char));

    for (int i = 0; i < 7; i++){
        scanf(" %d", &quantidade);
        scanf(" %c", &tamanho);
        quantidades[i] = quantidade;
        tamanhos[i] = tamanho;
    }
    printf("%d\n", total);
    for (int i = 0; i < 7; i++ ){
        if (tamanhos[i] == 'P' || tamanhos[i] == 'p') {
            holder = quantidades[i];
            total = total + quantidades[i]*10;
        }
        else if (tamanhos[i] == 'G' || tamanhos[i] == 'g') 
            total = total + quantidades[i]*16;
    }
    printf("%d\n", total);
    int xprof = total / 7;
    printf("%d", xprof);

    free(quantidades);
    free(tamanhos);
    return 0;
}

【讨论】:

    【解决方案2】:

    在您的代码中...

    scanf(" %d", &quantidade);
    scanf(" %c", &tamanho);
    

    不要在scanf(" %d, &amp;quantidade); 中使用空格

    你也可以直接在数组中插入值...

    scanf("%d", &quantidades[i]);
    scanf("%c", &tamanhos[i]);
    

    如果我没记错,那么你的编译器一定会在这里给你一个警告......

    if (tamanhos[i] == "P" || tamanhos[i] == "p") {
    

    这里..

    else if (tamanhos[i] == "G" || tamanhos[i] == "g") {
    

    您在这里仅比较单个字符,因此请仅使用单个冒号...

    【讨论】:

      【解决方案3】:

      主要问题:

      • tamanhos[i] == "P"char 与“指向字符串文字的指针”进行比较。您可能打算使用单引号,即tamanhos[i] == 'P'

      小改进:

      • int main() 通常不是此函数的有效签名,不使用参数时请使用 int main(void)
      • 幻数7 多次出现。也许这些应该被宏 professores 替换?后者通常全部大写以区别于常规变量。
      • 一个值存储在holder 中,但永远不会被读取。
      • 尝试在一个语句中声明和初始化变量(例如int n = 5),除非您使用的是不允许这样做的旧版 C。
      • 尽量使变量的范围尽可能小。简而言之,在使用前直接声明它们。
      • scanf 函数可能很难使用 w.r.t。避免缓冲区溢出。最好将其替换为 fgets 后跟 sscanf 的组合(或手动解析结果)。
      • 您可以将值直接写入数组,例如scanf(" %d", &amp;quantidades[i]);

      其他学分:Oka 和 Andrew Henle。

      【讨论】:

      • 非常感谢您的反馈。您建议使用什么来代替 scanf?
      • @JOAOVITORPEREIRAVENTURA 不客气。搜索 scanf here 以进行替代性和更广泛的讨论。如果一定要使用scanf,那么最好也检查一下它的返回值,看是否读取成功。
      • 调用scanf通常不安全具有误导性。尝试读取字符串时必须采取一些预防措施来限制输入长度(%s%[]),但主要是scanf 使用起来非常棘手,而不是不安全,在常见任务中存在许多陷阱。最常用的替代方法是使用fgets 读取部分/整行,然后手动或使用sscanf 解析它们,这样可以在解析和处理错误输入时提供更强大的控制。
      • @Oka 没错,没错。它并非总是不安全,但它在 C11 中被 Clang 的分析器视为已弃用是有原因的。我会更新答案。
      • 在C11中,最好换成scanf_s... IMO, no it should not be,除非你想写成de facto non-portable不再安全的代码。 scanf() 的真正问题是,如果发生故障,它会使您的输入流处于未知状态,因此 fgets() 然后 sscanf() 是 IMO 唯一真正的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多