在 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 方法中声明静态变量?

java中main方法中声明的变量[重复]

除了通过 main 的 argv 之外,还有其他方法可以将用户参数传递给程序吗?

Flutter,BlocProvider 应该在 main 方法中吗?

C语言函数的声明是在哪个位置声明