【问题标题】:Warning about uninitialized local variable关于未初始化局部变量的警告
【发布时间】:2021-09-25 10:53:07
【问题描述】:

我有以下代码:

#include <stdio.h>

int main()
{
    int student = 1;
    float mark, total = 0;

    while (mark != -1.00) {
        printf("Enter marks for Student %d (or -1 to stop): ", student);
        scanf("%f", &mark);
        total += mark;
        student++;
    }

    return 0;
}

当我尝试使用 gcc -O -Wall main.c 编译它时,我收到警告:

main.c: In function ‘main’:
main.c:8:17: warning: ‘mark’ is used uninitialized [-Wuninitialized]
    8 |     while (mark != -1.00) {
      |            ~~~~~^~~~~~~~
main.c:6:11: note: ‘mark’ declared here
    6 |     float mark, total = 0;
      |

【问题讨论】:

  • 只需在while循环开始之前打印mark的值,多次运行程序然后你会看到它可能包含任意值 - 因此需要在使用之前对其进行初始化它。给出警告是因为您使用mark 作为条件并且它没有被初始化。
  • 欢迎来到 SO。我们的问题是什么?您是否认为您收到了消息但初始化了mark?你想知道如何初始化变量吗?你想知道为什么使用未初始化的变量是不好的吗?我们不知道您的知识水平以及信息的哪一部分让您感到困惑。
  • markwhile 的测试尝试获取它时未初始化。

标签: c initialization warnings


【解决方案1】:

开头变量mark没有初始化值,所以它的值是未知的。

在下一行中,您将在 while 循环中进行比较。但是您还没有从用户那里读取mark 的值,所以被比较的值是未知的。

我怀疑你想使用 do { ... } while 循环:

do {
    printf("Enter marks for Student %d (or -1 to stop): ", student);
    scanf("%f", &mark);
    total += mark;
    student++;
} while (mark != -1.00);

在添加到total 之前,您还应该检查mark 是否不是-1.00,因此您的循环应该是:

while (1) {
    printf("Enter marks for Student %d (or -1 to stop): ", student);
    scanf("%f", &mark);
    if (mark != -1.00) {
        total += mark;
        ++student;
    } else {
        break;
    }
}

在处理浮点数时,您可能需要牢记the basic problem of their limited precision

【讨论】:

  • 在加到总和做学生++之前,您还应该测试该标记不是-1
  • mark 的值是不确定的(根据 C 2018 6.7.9 10),并且使用它不符合使行为未由 C 标准定义的规则(C 2018 6.3 .2.1 2) 因为它的地址被占用了。具有不确定值的对象在每次使用时可能表现得好像其值不同;不恰当地说它可以保存“内存中的随机垃圾”。
  • @EricPostpischil 更好吗?
  • 关于:if (mark != -1.00) { 文字 -1.00double 文字,应该使用的是 float 文字:if (mark != -1.00f) { 注意尾随 f
  • 关于“比较 mark != -1.00 不是最佳实践”:这里的比较很好。浮点数不会随机注入错误;算术和四舍五入是明确指定的(尽管不幸的是,一些编程语言通过在计算中注入纬度来消除这一点,使它们远离 IEEE-754 规范)。当用户输入-1 或类似的东西时,scanf("%f", &amp;mark); 将在mark 中存储-1。
【解决方案2】:

while (mark != -1.00)

mark 未在此处初始化,因此出现警告。这是未定义的行为。

【讨论】:

  • 在未初始化时使用 mark 会产生不确定的值。这不是未定义的行为。
  • 如果标记可以保持陷阱表示,我可能会。
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 2012-10-03
  • 2021-12-06
  • 2016-08-12
  • 1970-01-01
  • 2021-10-02
相关资源
最近更新 更多