如何在C语言中检查变量是否已初始化?

51

在C语言中,有没有一种方法可以检查变量是否已经初始化?

考虑以下示例:

int main(){
    int a = 3, b = 7, c;

    if ( a > b )
        c = a-b;

    // Now, how can I check if the variable "c" has some value or not
    // I don't want check like this,
    // if ( isalpha(c) ) or if ( isdigit(c) )
    // or anything similar to like that
}

换句话说,C语言是否有类似于Perl中的defined函数的功能?在Perl中,我可以简单地使用if (defined c)来检查变量是否已定义,对于上面的示例,它将返回False。在C语言中如何实现相同的功能?

8
这并不可行;这只是未定义的行为。 - user2357112
6
在C语言中,变量c没有默认值。它的初始值是未指定的。尝试读取未指定初始值的变量会导致未定义行为。 - Bill Lynch
3
在你说“未指定”的地方,应该改为“不确定”。 - M.M
4
在C语言中,我们会说你的变量c定义为整数,但当b < a时它是未初始化的。如果一个变量没有被定义且你尝试引用它,编译器会生成一个错误(该变量不存在)。在某些情况下,如果你在给变量赋值之前尝试引用它,编译器可能会发出警告。但除了接受答案中提到的方法,你没有运行时的方法来检查是否已经给变量赋值。 - tomlogic
2
“defined” 意味着为变量分配了内存。当您使用 int c; 时,c 同时被 声明定义 - Spikatrix
显示剩余4条评论
3个回答

85

C语言没有这个能力。您有两个主要选项:

哨兵值

例如,如果您知道c的值永远不会为负数,则将其初始化为-1,并对其进行测试。

添加另一个变量

创建另一个变量bool we_set_c_to_something = false;,然后在写入c时将其设置为true


11
C是一种编译语言,不支持运行时变量绑定,而Perl是一种解释语言,支持动态类型。因此,在Perl中可以检查变量的定义,但在C中不行。
在C中声明一个变量int c;时,这个变量c被定义了,但没有初始化。声明和定义在一条语句中完成。
在C中,变量的定义不需要由代码编写者检查,编译器会为您完成。当编译和链接您的C代码时,编译器将检查所有变量的定义。如果在代码中发现未定义的变量,将会引发错误,并停止编译或链接过程。

我认为这段内容有些不够精确。据我所知,动态_类型_并不是允许在Perl中引用未定义变量的关键,虽然我不确定该特性的实际名称。另外,当你说编译器/链接器因有未定义变量而失败时,当你说“未定义”时,我想你指的是_未声明_,而不是未初始化的吧?(通常,编译器不会停止处理未初始化变量,除非明确要求。) - David Z
@DavidZ 当我说“未定义”时,它是未定义的。例如只有一个语句extern int a;,我可以在我的C代码中使用a。它被声明了,但没有被定义。在链接时会出现错误,但编译时没有错误。 - alijandro
啊,我明白你的意思了。抱歉,我误解了那个。在你的回答中提到extern作为一个变量可以被声明但不被定义的例子可能会更加清晰明了。 - David Z
可能是动态引用绑定。 - Benjamin Gruenbaum

10

错误的问题。您并没有询问变量是否被定义。如果变量未定义,则编译将失败。请查阅“声明”和“定义”的区别。在这些本地变量的情况下,您已经定义了变量c。

您要找的是初始化。许多编译器会警告您在变量初始化之前使用变量,但如果您坚持运行该代码,则假定您比编译器更懂得处理这个问题。此时,这就成了您的问题。 :) 一些语言(例如Perl)具有一个额外的标志,用于表示变量是否已初始化,它们会隐藏这个附加标志,您可能需要或不需要。如果您想在C中实现这个功能,则需要自己编写代码。

由于C++允许运算符重载,因此在C++中相对容易实现这一点。Boost提供了一个名为"optional"的模板来实现它,或者您可以自己编写代码来进行练习。但是,C没有运算符重载的概念(甚至该概念实际上并不存在,当时的编译器可能无法支持它),因此您所看到的只有现状。

Perl是一个特殊情况,因为它将这两个概念合并在一起,但C不会。在C中完全可以拥有已定义但未初始化的变量。实际上,在进行驱动程序等低级内存访问时,我们经常需要这种情况。


6
这个问题涉及到 C 语言而非 C++。 - 2501
3
@2501 的话没错,但由于大多数 C 编译器也是 C++ 编译器,因此提及一下似乎很值得。许多人在 C++ 中编写类似 C 代码,因为他们喜欢其中的一些附加功能。这也给了我一个机会来说明为什么它不能被添加到标准 C 中。 - Graham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接