我昨天写了以下插入排序(我3天前开始学习C)。出于某种原因,排序不会修改数组 AT ALL 。
#include <stdio.h>
int *insert(int arr[], int index, int item);
int *isort(int arr[]);
int main() {
int a[17] = {1, 2, 9, 5, 3, 2, 1, 6, 5, 9, 0, 1, 3, 4, 2, 3, 4};
int *b = isort(a);
for (int i = 0; i < 17; i += 1) {
printf("%d ", b[i]);
}
return 0;
}
int *insert(int arr[], int index, int item) {
--index;
while (index >= 0 && item < arr[index]) {
arr[index + 1] = arr[index];
--index;
}
arr[index + 1] = item;
return arr;
}
int *isort(int arr[]) {
for (int i = 1; i < sizeof(arr) - 1; i++) {
arr = insert(arr, i, arr[i]);
}
return arr;
}
我认为它可能是我的编译器,因为我正在运行非unix机器上的编译器:lcc-win,但我不确定。我在这里缺少一些基本的东西吗?
答案 0 :(得分:3)
int *isort(int arr[]) {
for (int i = 1; i < sizeof(arr) - 1; i++) {
arr = insert(arr, i, arr[i]);
}
return arr;
}
在这个函数中sizeof(arr)
实际上返回指针的大小而不是数组的大小。
在C中,一条特殊规则表示数组参数实际上已调整为相应指针类型的参数。
那是:
int *isort(int arr[]) { /* ... */ }
相当于:
int *isort(int *arr) { /* ... */ }
要解决此问题,请在函数中添加一个新参数,该参数采用数组的大小:
int *isort(int arr[], size_t size) { /* ... */ }
答案 1 :(得分:1)
正如已经指出的,第一个问题是isort函数在指针上使用sizeof运算符。乍一看,C处理数组的方式有点奇怪。数组的名称是指向其第一个元素的指针。所以当你打电话给isort时这样:
int *b = isort(a);
您只是将指向数组的指针推入堆栈。在isort的定义中,
int *isort(int arr[])
声明arr是一个指向int的指针,就像
一样int *isort(int *arr)
在这方面,C更令人困惑:如果你说过:
int *isort(int arr[17])
arr变量仍只是指向int的指针...&#34; 17&#34;这里丢弃了!即使使用这种语法,sizeof(arr)仍然是指向int的指针的大小。
在32位系统(ILP32)上,sizeof(arr)将始终为4,无论数组多大。
因此,您需要将数组的大小传递给isort。一个很好的通用方法是定义一个像这样的宏:
#define NITEMS(arr) (sizeof(arr)/sizeof(arr[0]))
这将计算任何类型的数组中的元素数。
您的下一个问题更多是样式而不是实际错误:
arr = insert(arr, i, arr[i]);
这会调用insert函数并引用&#34; arr&#34;。通过此引用修改数组,然后返回指向该数组的指针。它总是与你在第一个位置发送的指针相同,所以这个任务实际上什么都不做,无害。就像我说的,风格问题,而不是代码错误。
最后一个问题是你的isort函数停止了一次(在你纠正sizeof问题之后),因为你从1变为sizeof-1。这是一个固定版本:
#include <stdio.h>
#define NITEMS(arr) (sizeof(arr)/sizeof(arr[0]))
int *insert(int arr[], int index, int item);
int *isort(int arr[], size_t nitems);
int main() {
int a[17] = {1, 2, 9, 5, 3, 2, 1, 6, 5, 9, 0, 1, 3, 4, 2, 3, 4};
int *b = isort(a, NITEMS(a));
for (int i = 0; i < NITEMS(a); i += 1) {
printf("%d ", b[i]);
}
printf("\n");
return 0;
}
int *insert(int arr[], int index, int item) {
--index;
while (index >= 0 && item < arr[index]) {
arr[index + 1] = arr[index];
--index;
}
arr[index + 1] = item;
return arr;
}
int *isort(int arr[], size_t nitems) {
for (int i = 1; i < nitems; i++) {
insert(arr, i, arr[i]);
}
return arr;
}