【发布时间】:2016-04-16 07:51:50
【问题描述】:
作为作业,我编写了这个程序,它应该使用 qsort_r 对控制台输入进行排序(这是我无法更改的一件事,我们需要使用 qsort_r)。我们应该实现三种不同的排序功能; compVal 通常按值对输入进行排序,compOnes 按其位值包含的 1 的数量对输入进行排序,而 compBitSeq 按最长的位序列对它们进行排序(并且排序应该双向工作,因此方向变量)。
正常的排序功能可以正常工作。不过,我无法让 compOnes 和 compBitSeq 工作。我自己尝试了辅助功能 countOnes 和 bitSequence;他们似乎工作得很好,做我期望他们做的事。但是,当我尝试调整程序时,整个程序会给我一个分段错误。
由于我对指针还不是超级安全,因此我无法真正确定这里出了什么问题。我确实假设将函数传递给函数可能存在问题,并且我没有正确传递所有值,但我不确定该怎么做?我尝试将所有内容放在一个函数中,这非常不雅,因为我必须执行相同的循环才能同时找到 acount 和 bcount,但这也没有用。 qsort_r 也降低了我的灵活性,因为我必须坚持函数所需的数据类型。
我现在已经摆脱了分段错误,将函数 strcomp 与 memcmp 互换就可以了!现在我确实得到了一个输出,但它并不如预期的那样,我无法理解这里出了什么问题。我已经用几个值尝试了我的 countOnes 和 bitSeq 函数,输出告诉我正在确定的值是正确的(我在我的代码中对此进行了评论,所以我知道它应该是什么顺序)。但是排序似乎是完全随机的(可能不是,但我真的不知道它是按什么排序的......而且我确实觉得每次输出都不同,即使数字相同,特别是如果我以不同的顺序输入它们),即使是完全正常的排序顺序。
如果这有帮助,我现在修改了我的函数,以便打印他们正在比较的数字,并且......这是一些负数: 数字 a:-41,数字 b:-39,顺序:-2 数字 a:-34,数字 b:-31,顺序:-3 数字 a:-36,数字 b:-34,顺序:-2 数字 a:-41,数字 b:-36,顺序:-5 数字 a:-39,数字 b:-36,顺序:-3 3、15、7、97、32
(显然,数字在输入时就出来了,因为这些值都给出了否定的结果......)
他们来自哪里?显然我传递了一些错误,但我不知道是什么......?也许某些数据类型混乱了,但我不知道是哪一个以及在哪里。我试图改变一些事情,但没有帮助。
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int compVal (const void *a, const void *b, void *direction) {
int order = memcmp(a, b, sizeof(char)) * *(int *) direction;
printf("number a: %d, number b: %d, order: %d\n", *(char *)a, *(char *)b, order);
if (order > 0) {
return 1;
} else if (order < 0) {
return -1;
} else {
return 0;
}
}
int countOnes (char number) {
int counter = 0;
for (int i = 0; i < (8 * sizeof(char)); i++) {
if (number & 1) {
counter += 1;
}
number = number >> 1;
}
return counter;
}
int bitSequence (char number) {
int bit = number & 1;
number = number >> 1;
int current = 1, max = 1;
for (int i = 1; i < (8 * sizeof(char)); i++) {
if ((number & 1) == bit) {
current += 1;
if (current > max) {
max = current;
}
} else {
current = 1;
}
bit = number & 1;
number = number >> 1;
}
return max;
}
int compOnes (const void *a, const void *b, void *direction) {
char achar = *(char *) a, bchar = *(char *) b;
char acount = countOnes(achar);
char bcount = countOnes(bchar);
//return memcmp(&acount, &bcount, sizeof(char)) * *(int *) direction;
printf("ones a: %d, ones b: %d\n", acount, bcount);
return compVal(&acount, &bcount, &direction);
}
int compBitSeq (const void *a, const void *b, void *direction) {
char achar = *(char *) a, bchar = *(char *) b;
char aseq = bitSequence(achar);
char bseq = bitSequence(bchar);
//return memcmp(&aseq, &bseq, sizeof(char)) * *(int *) direction;
printf("sequence a: %d, sequence b: %d\n", aseq, bseq);
return compVal(&aseq, &bseq, &direction);
}
int main (int argc, char* argv[]) {
if (argc < 3) {
printf("At least 2 values needed for sorting\n");
return EXIT_FAILURE;
}
int direction = 1;
qsort_r(&argv[1], argc - 1, sizeof(char *), compVal, &direction); // 3, 7, 15, 32, 97
//qsort_r(&argv[1], argc - 1, sizeof(char *), compOnes, &direction); // 32, 3, (7, 97), 15
//qsort_r(&argv[1], argc - 1, sizeof(char *), compBitSeq, &direction); // (97, 15), (7, 32), 3
//char test1 = countOnes(3), test2 = countOnes(7), test3 = countOnes(15), test4 = countOnes(32), test5 = countOnes(97);
//printf("%d, %d, %d, %d, %d\n", test1, test2, test3, test4, test5); // 2, 3, 4, 1, 3
//test1 = bitSequence(3), test2 = bitSequence(7), test3 = bitSequence(15), test4 = bitSequence(32), test5 = bitSequence(97);
//printf("%d, %d, %d, %d, %d\n", test1, test2, test3, test4, test5); // 6, 5, 4, 5, 4
for (int i = 1; i < argc; i++) {
if (i == argc -1) {
printf("%s\n", argv[i]);
} else {
printf("%s, ", argv[i]);
}
}
return EXIT_SUCCESS;
}
【问题讨论】:
-
argv是char*的数组,而不是int*。 this(*(int *) a) 有对齐问题。 -
比较函数产生的返回值是否必须为-1、0或1才能得到正确的结果?或者它可以是任何正值或负值吗?不知道我是否需要在这里考虑其他任何事情......
-
这取决于排序功能的实现。
-
好吧不,也不是这样,显然我比较的数字已经错了……
标签: c sorting segmentation-fault qsort