用C语言对Unix环境进行排序

用C语言对Unix环境进行排序,c,C,我试着整理我的环境 我的C++版本(STD::排序行与CSTROLL类)一起工作,但是Q排序版本失败了。我做错了什么 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> extern char** environ; struct CstrLess{ bool operator()(const char* s1, const char*

我试着整理我的环境

我的C++版本(STD::排序行与CSTROLL类)一起工作,但是Q排序版本失败了。我做错了什么

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
extern char** environ;


struct CstrLess{
  bool operator()(const char* s1, const char* s2){ return ::strcmp(s1,s2)<0; }
};

int main(){
  char** env = environ;
  size_t sz = 0;
  for(;*env; env++,sz++) {;} //measure the env

  //?
  qsort(environ, sz, sizeof(char*), (int (*)(const void*, const void*)) strcmp);

  /*std::sort(environ, environ + sz, CstrLess{});*/

  env = environ;
  while(*env){
    printf("%s%c", *env++, '\0');
  } 

  return 0;
}
#包括
#包括
#包括
#包括
外部字符**环境;
无结构{

bool操作符()(const char*s1,const char*s2){return::strcmp(s1,s2)
qsort
将其比较函数指针传递给要比较的元素;您需要间接传递该指针以获得要传递给
strcmp
char const*
指针:

qsort(environ, sz, sizeof(char*),
    [](const void* a, const void* b) {
        return strcmp(
            *reinterpret_cast<const char**>(a), *reinterpret_cast<const char**>(b)); });

qsort
将其比较函数指针传递给要比较的元素;您需要间接传递该指针以获取要传递给
strcmp
char const*
指针:

qsort(environ, sz, sizeof(char*),
    [](const void* a, const void* b) {
        return strcmp(
            *reinterpret_cast<const char**>(a), *reinterpret_cast<const char**>(b)); });

指向strcmp
的指针的类型为
int(*)(常量字符*,常量字符*)

qsort
所需的类型为
int(*)(常量void*,常量void*)

野生函数指针转换是未定义的行为。如果您没有使用难看的强制转换使其静音,编译器会理所当然地给您一个警告/错误。不同类型可能有不同的调用约定,因此此未定义的行为是一个值得关注的问题

正确的方法是编写包装器函数并传递指向该函数的指针:

int strcmp_wrapper (const void* s1, const void* s2)
{
  return strcmp(s1, s2); // implicit conversion from const void* to const char*.
}

指向strcmp的指针的类型为
int(*)(常量字符*,常量字符*)

qsort
所需的类型为
int(*)(常量void*,常量void*)

野生函数指针转换是未定义的行为。如果您没有使用难看的强制转换使其静音,编译器会理所当然地给您一个警告/错误。不同类型可能有不同的调用约定,因此此未定义的行为是一个值得关注的问题

正确的方法是编写包装器函数并传递指向该函数的指针:

int strcmp_wrapper (const void* s1, const void* s2)
{
  return strcmp(s1, s2); // implicit conversion from const void* to const char*.
}

“失败”是什么意思?
qsort
pass
char**
to
strcmp
,而不是
char*
@ecatmur输出未排序。你说的“失败”是什么意思?
qsort
char**
传递到
strcmp
,而不是
char*
@ecatmur输出未排序。为什么对
const char**
btw的强制转换似乎完全多余。@Lundin指针必须是间接的,也必须是强制转换的。不能间接执行
const void*
,因为这样会产生
const voide> 左值,不可能存在。为什么强制转换到
常量字符**
顺便说一句?似乎完全是多余的。@Lundin指针必须是间接的,也必须强制转换。不能间接转换
常量无效*
,因为这样会产生
常量无效
左值,而左值不可能存在。