我有一个任务是在使用动态内存时对负数和正数进行排序,因此在这种情况下,我使用calloc和冒泡排序来排列负数而不改变它们的顺序。问题是当我输入偶数个整数时,在结果的中间会出现一些10位数的随机负数。奇数个整数也不会发生同样的情况。什么似乎是问题?
#include <stdio.h>
#include <stdlib.h>
#define SIZE 1000
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (arr[j] < 0) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
}
int main() {
int n;
int i, *sk;
printf("Enter integer: \n");
scanf("%d", &n);
printf("Enter %i integers: \n", n);
sk = (int*)calloc(sizeof(int), n);
for (i = 0; i < n; i++) {
scanf("%d", sk + i);
}
swap(sk, n);
return 0;
}
答案 0 :(得分:1)
这是未定义的行为,只有当您碰巧输入偶数个整数时才会向您显示,但实际上问题始终存在:您从数组的末尾读取一个值,它会进入数组的中间位置。
您可以通过i <= n
和j <= n
更改i < n
和j < n
来解决此问题。但是,这不会修复破坏的排序算法,因为交换条件也不正确。而不是
if(arr[j]<0)
应该是
if(arr[j]<arr[j-1])
答案 1 :(得分:0)
您的for
循环中有2个经典错误:
for (i = 0; i <= n; i++)
几乎总是错误的,因为循环运行n + 1
次,它只应枚举从0
到n - 1
的索引值。
在第二个循环中你有一个相同的错误:测试j <= n
让你走得太远而且超出了数组的末尾。一些随机值被混乱到数组中,但这种未定义的行为可能会产生更糟糕的后果。
此外,您的比较测试不正确,应为if (arr[j] < arr[j-1])
。
根据经验,每当你在循环测试中看到<=
运算符时,再看一下,这可能是一个错误。
以下是更正后的版本:
void swap(int *arr, int n) {
int i, j, temp;
for (i = 0; i < n; i++) {
for (j = 1; j < n; j++) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
}
printf("sorted integers to negative and positive: \n");
for (i = 0; i < n; i++) {
printf("%i ", arr[i]);
}
printf("\n");
}