在 main 方法中声明与在 main 方法之外声明时的其他结果
Posted
技术标签:
【中文标题】在 main 方法中声明与在 main 方法之外声明时的其他结果【英文标题】:other results when declaring in main method vs. outside from main method 【发布时间】:2020-12-17 07:20:02 【问题描述】:我目前正在codeforce 上做一个简单的问题。 基本上,您会得到一个字符串(例如“1+3+2”),并且您必须将其排序后返回(例如“1+2+3”)。只会使用 1,2 和 3。
我开始:
#include <iostream>
using namespace std;
int main()
string str;
int arr[4];
cin >>str;
for(int i = 0; i < str.length();i+=2)
arr[str[i] - '0']++;
我的想法是将每个出现的数字存储在一个数组中。但是如果我要添加,我注意到一个问题
cout<< arr[2];
输入“1+2+3”,输出:
33
不过应该是1,因为3只出现过一次。
我通过移动“string str;”解决了这个问题和 "int arr[4]" up, over main:
#include <iostream>
using namespace std;
string str;
int arr[4];
int main()
cin >>str;
for(int i = 0; i < str.length();i+=2)
arr[str[i] - '0']++;
cout<< arr[2];
输出:
1
为什么它现在起作用了?
【问题讨论】:
你应该检查变量初始化。默认情况下,int
包含垃圾
【参考方案1】:
没有初始化器的自动存储持续时间:应用默认初始化:基本非类类型的数组将保留未初始化的值
在您的第一个示例中,arr
具有自动存储持续时间并且未初始化,这是默认初始化的结果:
int main()
// default initialization
int arr[4];
// reading from arr at this point (remains
// uninitialized) is undefined behaviour.
数组类型默认初始化的效果是数组的每个元素都是默认初始化的。默认初始化对基本的非类类型没有任何影响:元素将保持未初始化状态。读取此类元素(在示例中的元素上调用 operator++
)是未定义的行为。
你可以例如使用以下语法初始化arr
:
int main()
int arr[4];
数组的每个元素都是值初始化的,而数组的每个元素(基本的非类类型)都是零初始化的。
静态存储时长:适用零初始化
在第二个例子中,arr
不再具有自动存储时长,而是静态存储时长,并且适用静态初始化规则,这将导致 arr
被零初始化。
【讨论】:
【参考方案2】:默认情况下,C++ 不会将数组初始化为 0。你最初的内容是不可预测的,你的结果也是如此。
有多种方法可以解决问题。我建议使用std::vector,将变量声明为:
#include <vector>
std::vector<int> arr(4, 0);
第一个参数是大小,第二个是所有元素的初始值(默认为0)。您可以将其用作带有 [] 的数组。它还有其他有用的功能,例如可以根据需要进行扩展。
或者,您也可以使用memset 清除数组:
#include <cstring>
memset(arr, 0, sizeof(arr));
此功能较旧,您需要更加小心。
【讨论】:
【参考方案3】:在第一个示例中,您没有初始化 int arr[4];
。 因此,您的程序的行为是未定义的。
如果您在没有第一个 for 循环的情况下打印 arr
的内容:
for (auto x: arr)
std::cout << x << "\n";
你得到的垃圾数据恰好位于arr
的地址:
121
32584
615125669
22063
但不能保证你会得到任何东西。如果你给编译器提供了一个无效的程序,它可以为所欲为。
您可以通过初始化数组来修复此问题:
int arr[4] = ;
这将初始化数组,这对于int
意味着使用0
进行初始化。
【讨论】:
以上是关于在 main 方法中声明与在 main 方法之外声明时的其他结果的主要内容,如果未能解决你的问题,请参考以下文章
Java:为啥我不能在 main 之外调用这个方法? [关闭]
除了通过 main 的 argv 之外,还有其他方法可以将用户参数传递给程序吗?