将未初始化的局部变量传递给函数时,C++编译器警告(?)

C++ compiler warning(?) when passing uninitialized local variable to function

本文关键字:编译器 C++ 警告 函数 初始化 局部变量      更新时间:2023-10-16

我对C++很陌生,所以我希望有人能给我一些启发。我遇到了几个类似的话题,但我只需要澄清一下。

因此,传递一个已声明但未初始化为函数的本地字符串似乎是有效的。但当您尝试使用int或float时,编译器为什么会抱怨呢??

无论是字符串、float还是int,内存地址在声明时都会被引用,即使它可能是"垃圾"

#include <iostream>
using namespace std;
void load(int);
int main()
{
    int salary;
    load(salary);
    return 0;
}
void load(int sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

如果我将int或float声明为全局变量,它将按预期工作,没有任何警告。那么,在全局空间中声明变量是更好的做法吗(我希望不是)?

所以把它放在全球,它是有效的:

#include <iostream>
using namespace std;
int salary;
void load(int);
int main()
{
    load(salary);
    return 0;
}
void load(int sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

好的,另一个例子表明,未初始化的全局变量在作为值传递给函数时是有效的:(脱离David的评论)

int foo; 
int returnit(int j)
{ 
    cout << "your salary";
    cin >> j;
    return j; 
} 
int main() 
{ 
    int k = returnit(foo);
    cout << k; 
    return 0;
} 

无论如何,这里的教训是在传递给函数之前初始化原始数据类型。

因此,传递一个已声明但未初始化为函数的本地字符串似乎是有效的。但当您尝试使用int或float时,编译器为什么会抱怨呢??

如果您所说的"字符串"是指std::string对象,那是因为对象从未被初始化。当你这样做:

std::string s;

则调用std::string的默认构造函数并初始化对象。

基元数据类型(如intfloat)的变量,除非声明为具有静态存储持续时间,否则如果未显式初始化,则将具有垃圾。尝试读取和使用垃圾会正确地触发警告。(具有静态存储持续时间的基元数据类型的变量(即全局变量或声明为static的变量)隐式初始化为0。)

那么,在全局空间中声明变量是更好的做法吗(我希望不是)?

不,更好的做法是初始化变量。

解释为什么永远不应该在函数调用中使用未初始化的变量的最好方法是,这在逻辑上是无效的,有时在逻辑上也是无效的,而且语法也是无效的。

要查看您的程序是否在逻辑上有效,请使用box方法并跟踪您的程序。全局框中有全局变量,int main有自己的框,其中包含局部变量,当调用函数时,为该函数创建一个新框,并用其参数和局部变量填充。逐行进行,并在程序中更改变量值。记住只使用常量作为全局变量。当扭曲一个函数时,当你通过引用时要小心,你知道这个函数被赋予了内存中的变量地址,并且可以改变这个值。当使用按值传递时,在函数声明中使用这种语法:

int Multiplication(const int Var1, const int Var2);

这样可以保护传递给乘法运算的值。c++的语法是为了速度而设计的,它并不能阻止你在逻辑上不正确。

int salary;
load(salary);

您认为您传递给load的值是多少?你在传递一个无意义的值。

需要明确的是,您传递的不是"未初始化变量",而是未初始化变量的。如果你这样做:

int j=3;
load(j);

您正在将j的值(即3)传递给load。如果不另行指定,C++将按值传递。

全局变量也会遇到同样的问题

int foo;
int returnit(int j)
{
    return j;
}
int main(void)
{
    int j=returnit(foo);

你认为j在这里应该有什么价值?!在将变量的值传递给函数之前,仍然需要将其初始化为某个特定值。

要补充David的答案,您可能想做的(我猜)是修改原始的薪资变量。要做到这一点,您需要传递一个对变量的引用,如下所示:

void load(int& sal)
{
    cout << "your salary: " << endl;
    cin >> sal;
    cout << sal << endl;
}

注意"&"在函数签名的int之后。

另外请注意,在load()中未定义"salary"的地方使用它。您应该使用"sal"。

通过这种方式,编译器知道load()接收到对变量的引用,因此如果您在函数内部对其进行修改,则发送给函数的变量(salary)也会更改。

对函数的调用本身保持不变。