将未初始化的局部变量传递给函数时,C++编译器警告(?)
C++ compiler warning(?) when passing uninitialized local variable to function
我对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
的默认构造函数并初始化对象。
基元数据类型(如int
和float
)的变量,除非声明为具有静态存储持续时间,否则如果未显式初始化,则将具有垃圾。尝试读取和使用垃圾会正确地触发警告。(具有静态存储持续时间的基元数据类型的变量(即全局变量或声明为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)也会更改。
对函数的调用本身保持不变。
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C/C++预处理器是否可以检测一些编译器选项
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 我需要知道编译器如何在cpp中使用析构函数
- 编译器如何区分std::vector的构造函数
- CLANG 编译器 说:变量"PTR"可能未初始化
- 告诉c++编译器该参数没有别名
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么所有C++编译器都会崩溃或挂起此代码
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 为什么C++编译器没有检测到正确声明的类?