【问题标题】:other results when declaring in main method vs. outside from main method在 main 方法中声明与在 main 方法之外声明时的其他结果
【发布时间】: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 包含垃圾

标签: c++ arrays main


【解决方案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 进行初始化。

      【讨论】:

        猜你喜欢
        • 2011-11-20
        • 2012-10-29
        • 2011-03-23
        • 2019-02-26
        • 1970-01-01
        • 2019-07-04
        • 1970-01-01
        • 2021-02-02
        • 1970-01-01
        相关资源
        最近更新 更多