如何将数组传递给“qsort”工作?

时间:2016-08-05 08:40:24

标签: c string

所以我有下面声明的main函数,用户必须在第一次执行程序时从命令行传递参数。然后,它接受*argv[]字符串输入数组并使用stdlib.h的qsort函数对它们进行排序,之后它最终打印输出数组中除文件名之外的所有元素;

int main(int argc,char *argv[]){                                                                                                                                                                                                
  qsort(argv,args,sizeof(*argv),comp_func);
  for(int U=1;U<argc;U++)printf("%s\n",argv[U]);                                                                                                                                                                                              
}

传递给comp_func的{​​{1}}函数如下所示:

qsort

我想知道的是这里发生了什么?我很漂亮int comp_func(char*a,char*b){ return strcmp(*(char **)a,*(char **)b); } 将数组的每个2长度排列发送到给定的比较器函数,在这种情况下,两者都是字符串,因为qsort是一个字符串数组。但是,我没有得到的是这里发生的事情:

argv

strcmp(*(char **)a,*(char **)b) 在做什么?它只是创建一个指向长度为1的任意字符串的指针的任意*(char **)a数组,然后将其第一个值赋值为char[],之后最终取消引用它,最终返回字符串{ {1}}?如果是这样,为什么不仅仅是普通的a工作呢?另外,有趣的是,如果我a只是普通的a,它会输出一串随机字符,类似于printf。但是,当我printf a时,我得到实际的字符串输入。这是为什么?我是??O_?的初学者,如果我再问任何问题,请耐心等待。

3 个答案:

答案 0 :(得分:4)

qsort()期望连续的对象数组作为第一个参数base。现在,argv是一个const char *指针数组,所以

qsort(argv, args, sizeof(*argv), comp_func);

说,对指针数组进行排序,其中sizeof(*argv)的大小为const char *

传递给comp_func()的是从基指针偏移的两个对象的地址,即argv中的char指针的地址。要获取包含参数字符串的实际字符串数组/指针,我们需要取消引用它。也就是说,参数字符串实际上位于*a*b

签名仍然是错误的,应该在整个地方抛出编译器警告。 comp_func()实际需要两个const void *

int
comp_func(const void *a,const void *b) {
    return strcmp(*(const char **)a,*(const char **)b);
}

演员表是必要的,因为*a不是const void *strcmp()需要const char *的有效类型。

答案 1 :(得分:2)

tldr;它是一个类型演员,然后是一个尊重。

比较函数的典型形式是

int comp_func(void *a, void *b)

(char**)a将一个指针转换为指向char *的指针,在这种情况下,它实际指向char数组的开头。

*(char**)a然后取消引用它,意味着指向数组开始的指针传递给strcmp()函数。

printf将指针指向要从该指针向前打印的数组的开头,直到指针指向char&#39; \ 0&#39;在数组中。乱码是因为它传递了一个指向指针的指针,所以你得到一个打印的内存地址。

答案 2 :(得分:2)

首先,比较功能应该是

int comp_func(const void* a, const void* b)

然后尝试分析代码:您传递给那个被称为argv的函数char *argv[],可以看作是char **

因此,在函数内部,必须将通用void指针强制转换为根类型char **

然后您必须取消引用要比较的array of pointers元素,因此:*(char **)