编译器的差别gcc和VS

博客讲述了作者在实现插入排序算法时遇到的问题,即在GCC和VS编译器下得到不同排序结果。通过插入调试语句,作者发现问题出在`array[j+1]=array[j--];`这行代码上。GCC编译器在此处的优化导致了行为差异。为解决此问题,作者将代码调整为`array[j+1]=array[j]; j--;`,确保了在两种编译器下的正确性。博客强调了理解编译器差异和写出编译器无关代码的重要性。
摘要由CSDN通过智能技术生成

问题的由来是我写了一个排序算法程序,在gcc编译器下运行,发现结果有问题,然后开展的寻找错误解决问题

这是我写的一个简单的插入排序算法

#include <stdio.h>

//直接插入法排序函数主体
//参数1:待排序的序列
//参数2:序列的长度
//实现从大到小的排序
void insertSort(int  array[],int arraySize)
{
	int i , j , tmp,k = 0;
	for(i = 1 ; i < arraySize ; i++)	
	{
		tmp = array[i]; 
		j = i - 1;		
    	while(j >= 0 && tmp > array[j])	
		{
			array[j + 1] = array[j--];
		}
		array[j + 1] = tmp;
	}
}


int main()
{
	int a[7] = {5,6,3,9,2,7,1};
	insertSort(a,7);	
	int i = 0;
	for(i = 0 ; i < 7 ; i++)
	{
		printf("%d",a[i]);
	}
	printf("\n");
	return 0;
}

分别在两个不同的编译器中去编译运行,一个是vs2017环境、一个是Linux环境,他们用的编译器,分别是VS编译器和GCC编译器,同样的代码,运行出来的结果却不一样。 

为了定位问题,于是乎,我在程序体中加了多句printf输出想查看过程信息

具体代码我是这样写的,可以看一下

#include <stdio.h>

//直接插入法排序函数主体
//参数1:待排序的序列
//参数2:序列的长度
//实现从大到小的排序
void insertSort(int  array[],int arraySize)
{
	int i , j , tmp,k = 0;
	for(i = 1 ; i < arraySize ; i++)	//循环遍历序列
	{
		tmp = array[i];
   
		j = i - 1;
   
    printf("i = %d , j = %d , temp = %d\n",i,j,tmp);
		
    while(j >= 0 && tmp > array[j])	
		{
			array[j + 1] = array[j--];
		}
    for(k = 0;k<7;k++)
    {
      printf("%d",array[k]);
    }
    printf("\n");
		array[j + 1] = tmp;
       for(k = 0;k<7;k++)
    {
      printf("%d",array[k]);
    }
    printf("\n");
	}
}


int main()
{
	int a[7] = {5,6,3,9,2,7,1};
	insertSort(a,7);
	
	int i = 0;
   printf("最终");
	for(i = 0 ; i < 7 ; i++)
	{
		printf("%d",a[i]);
	}
	printf("\n");
	return 0;
}

然后下面这是运行的结果,可以发现,第一次从while循环中出来,两边的值就不一样了,while中只写了一句话

array[j + 1] = array[j--];

好了,问题找到,就是出在这句话上

于是乎,我们可以知道的是编译器不同造成的一个差别,并且我怀疑问题出在array[j + 1] = array[j--];这句话的j--上,于是上网查阅了相关资料,大体上是这样说的,我总结在下面了。

在一个循环体之中

gcc编译器 i++ 在遇到 '=' 符号时,会先增,而不是在一趟循环结束后再自增的

而VS编译器,是在一趟循环结束后才会i++的

这应该是gcc编译器对此做出了自己的优化

所以针对这一块程序,while里面我们可以改成这样,分成两步走

while(j >= 0 && tmp > array[j])	
{
	array[j + 1] = array[j];
	j --;
}

这下运行结果就没有问题了 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

翔在天上飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值