【问题标题】:Bubble-sort 'works' in Windows, but not with GCC on GNU/Linux冒泡排序在 Windows 中“有效”,但不适用于 GNU/Linux 上的 GCC
【发布时间】:2012-10-05 11:19:00
【问题描述】:

我正在使用 Ubuntu Linux 进行编程。昨天我遇到了一个非常奇怪的问题,它真的很晦涩,很奇怪。

问题是我尝试进行冒泡排序,逻辑,语法一切都是正确的,但输出是错误的。我在 Windows 中编写了相同的程序,它运行良好。我在 Linux 中使用 Eclipse IDE。可能是什么问题?另一方面,我使用指针(通过引用调用)来完成冒泡排序,但在 Ubuntu 中输出也是错误的,而在 Windows 中输出还可以。我不知道怎么弄出来的。

我的冒泡排序代码如下:

#include<stdio.h>

void main(void)
{
  int array[] = {4,2,6,3,1,5,8,4,6,1};
  int i=0;
  int j=0;
  for(i=1;i<=10;i++)
    {
      for(j=0;j<=10-i;j++)
        {
          if(array[j]>array[j+1])
            {
              int temp = array[j];
              array[j] = array[j+1];
              array[j+1] = temp;
            }
        }
    }
  for(i=0;i<=9;i++)
    {
      printf("%d\t",array[i]);
    }
}

输出:

gcc -o bubblesort.c -o output
./output


2 3 4 1 5 6 4 6 1 1

【问题讨论】:

  • 第一次通过第二个循环,您将到达 i=1j=9array[j+1] 是无效访问 => 您的代码表现出未定义的行为。
  • GNU C compiler Linux output is wrong -- 这句话的意思是您在输入时认为的意思,这种情况极为罕见。几乎总是,这意味着你搞砸了,而不是编译器。
  • @mah - 我编辑了标题等。希望它现在更接近事实(更具体)
  • 感谢@ArjunShankar 澄清我的头衔...

标签: c linux gcc syntax gnu


【解决方案1】:

超出数组的边界是未定义的行为(其中的一个子集行为“正确”),这就是程序正在发生的事情。数组使用从零开始的索引,这意味着最后一个有效索引比数组中的元素数少一:

/* 10 elements in 'array'. */
int array[] = {4,2,6,3,1,5,8,4,6,1};

for(j=0;j<=10-i ;j++)
{
    if(array[j]>array[j+1]) /* When 'j' is 9 the
                               'array[j + 1]' is
                               out of bounds. */

改变内部for循环终止条件:

for(j=0;j<=9-i ;j++)

您可以使用sizeof(array)/sizeof(array[0]) 来获取array 中的元素数量,而不是在整个代码中硬编码910。这使得以后更改array 中的元素数量变得更不容易出错并且更简单:

const int ARRAY_SIZE = sizeof(array)/sizeof(array[0]);

【讨论】:

  • 你能解释一下行为是如何未定义的吗?.. 数组中有 10 个元素,冒泡排序的规则是外循环应该是
  • @JamalHussain,我错误地认为i 被用于索引(更新答案)。不是,但j + 1 的索引是问题。
【解决方案2】:

这个:

for(j=0;j<=10-i;j++)

连同这个:

if(array[j]>array[j+1])

以及您越界访问数组的其他地方可能是导致问题的原因。

越界访问数组是未定义的行为

【讨论】:

    【解决方案3】:

    这是冒泡排序的伪代码:

    for (i = 0; i < 9; i++) {
        for (j = i + 1; j < 10; j++) {
            if (element[i] > element[j]) swap_elements();
    

    【讨论】:

    • 感谢它确实有效。但我很惊讶为什么我的代码在 Windows 网络 bean 中工作。是不是很奇怪?
    • @JamalHussain:您的代码调用了“未定义的行为”。它的字面意思是代码可以以完全任意的方式运行。 UB 最阴险的结果之一是代码完全按照您的意愿行事,但后来却在您的脸上炸开了锅。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2019-01-07
    • 2017-10-21
    • 2013-01-24
    • 1970-01-01
    • 2021-12-11
    • 2021-12-15
    相关资源
    最近更新 更多