问题的由来是我写了一个排序算法程序,在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 --;
- }
这下运行结果就没有问题了