【问题标题】:C++ code don't have errors but not giving output [closed]C ++代码没有错误但没有给出输出[关闭]
【发布时间】:2022-01-02 12:05:21
【问题描述】:

我正在用 C++ 编写选择排序的代码。当我在 powershell 中使用命令g++ main.cpp -o main 编译它时没有错误,但是当我使用./main 运行代码时,它不显示任何内容。我尝试了 hello world 程序,它奏效了。我不知道为什么选择排序代码不起作用。

这是选择排序的代码

#include<iostream>

using namespace std;

int main()
{
   int n, a[n];

   cout << "Enter the size of the array = ";
   cin >> n;

   cout << "Enter the numbers :" << endl;

   for (int i = 0; i < n; i++)
   {
       cin >> a[i];
   }

   for (int i = 0; i < n-1; i++)
   {
       for (int j = i+1; j < n; j++)
       {
           if (a[i] > a[j])
           {
               int temp = a[i];
               a[i] = a[j];
               a[j] = temp;
           }
       }
   }

   for (int b=0; b<n; b++)
   {
       cout<<a[b];
   }

   return 0;
}

【问题讨论】:

  • 打开警告以查看错误godbolt.org/z/ErPY3x936
  • 即使 n 已被初始化,但事实并非如此。 a[n] 不是有效的 C++。如果您想要一个动态(重新)大小的数组,请查看 std::vector 。总是在 C++ 中初始化你的变量,编译器不会隐式地为你做这件事。
  • 编译时没有错误 -- 那只意味着没有语法错误。如果我让你编写一个程序来添加两个数字,但它却减去了两个数字,那么该程序也将“无错误地编译”。但它是正确的吗?不。程序不逻辑上正确。
  • 我不知道为什么选择排序代码不起作用。 -- What is a debugger?.
  • 仅供参考,这不是经典的selection sort。选择排序扫描序列中未排序的部分,记住当前极值的索引位置。一旦扫描完成,最极端值所在的索引位置将与适当的位置(用作索引的外循环的迭代计数)交换。简而言之,每次外循环迭代应该只有 一个 交换,并且应该发生在 内循环完成之后。

标签: c++ arrays sorting for-loop output


【解决方案1】:

您的程序中有 2 个问题

错误 1

在标准 C++ 中,数组的大小必须是编译时间常数。举个例子,

int n = 10;
int arr[n] ; //INCORRECT because n is not a constant expression

上面的正确写法是:

const int n = 10;
int arr[n]; //CORRECT

错误 2

您正在使用导致未定义行为未初始化变量。特别是当你写的时候:

int n, a[n]; //here variable n is uninitialized and holds **indeterminate value**.

在上述语句中,您创建了一个名为 nint,但由于您没有显式初始化它,它拥有一个不确定值

接下来,您将使用该垃圾值作为数组a 的大小。但请注意,使用未初始化的变量会导致未定义的行为

未定义的行为意味着任何事情1都可能发生包括但不限于给出您预期输出的程序。但是永远不要依赖(或根据)具有未定义行为的程序的输出。

这就是为什么建议这样做

始终在本地/块范围内初始化内置类型。

解决方案

更好的方法是使用std::vector,如下所示。


#include <iostream>
#include <vector>
int main()
{
    int n = 0; //always initialize built in types in local/block scope 
    
    std::cout<<"Enter size: "<<std::endl;
    std::cin >> n;
    
    //create a vector of size n  
    std::vector<int> a(n);
    
    //iterate and ask for input 
    for(int i = 0; i < a.size(); ++i)
    {
        std::cout<<"Enter element: "<<std::endl;
        std::cin >> a[i];
    }
    
    for (int i = 0; i < a.size() - 1; ++i) 
    {
        
        int index = i;
        for (int j = i + 1; j < a.size(); j++) {
          
          if (a[j] < a[index])
            index = j;
        }
        
        int temp = a[index];
        a[index] = a[i];
        a[i] = temp;
        
    }
    std::cout<<"The elements of the vector are:"<<std::endl;
    //print the element of the vector 
    for(const int& elem: a)
    {
        std::cout<<elem<<std::endl;
    }
    return 0;
} 

程序的输出可见here


1有关未定义行为的更准确的技术定义,请参阅this,其中提到:对程序的行为没有限制 .

【讨论】:

    【解决方案2】:

    始终初始化变量。没有初始化的声明是一种代码味道,例如这个:

    int n;
    

    问题紧随其后,因为

    int n, a[n];
    

    使用未初始化的n。编译器在警告这方面做得很好:https://godbolt.org/z/ErPY3x936。在初始化 n 之前,它有一个不确定的值。使用它的值会导致未定义的行为。此外,a[n] 是一个可变长度数组(除非n 是一个常量表达式),它不是标准 C++ 的一部分。当您需要一个大小仅在运行时知道的数组时,您可以使用std::vector

    int n = 0;
    cout << "Enter the size of the array = ";
    cin >> n;
    std::vector<int> arr(n);
    

    【讨论】:

      【解决方案3】:

      您正在尝试使用可变长度数组

      int n, a[n];
      

      可变长度数组不是标准 C++ 功能。所以你应该避免使用它们。而是使用标准容器std::vector&lt;int&gt;

      此外,变量n 未初始化。因此,可变长度数组的声明会调用未定义的行为。

      在对数组进行排序的 for 循环中,数组元素的交换次数过多。

      选择排序算法假定数组中的一个选定元素最多交换一次。

      还有一个标准函数std::swap可以用来代替手动交换元素。

      您的程序可能如下所示

      #include <iostream>
      #include <utility>
      #include <vector>
      
      int main()
      {
          size_t n = 0;
      
          std::cout << "Enter the size of the array (0 - exit): ";
          std::cin >> n;
      
          if ( n )
          {
              std::vector<int> v( n );
      
              std::cout << "Enter the numbers :" << std::endl;
      
              for ( auto &item : v )
              {
                  std::cin >> item;
              }
      
              for ( std::vector<int>::size_type i = 0; i < v.size(); i++ )
              {
                  auto min = i;
      
                  for ( auto j = i + 1; j < v.size(); j++ )
                  {
                      if (  v[j] < v[min] ) min = j;
                  }
      
                  if ( min != i ) std::swap( v[min], v[i] ); 
              }
      
             for ( const auto &item : v )
             {
                 std::cout << item << ' ';
             }
             std::cout << std::endl; 
          }
      
          return 0;
      }.
      

      【讨论】:

        猜你喜欢
        • 2021-12-04
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多