解释qsort中的C代码行

解释qsort中的C代码行,c,syntax,qsort,C,Syntax,Qsort,我一直在研究qsort的不同实现,在这里找到的源代码()中有一行我不理解。它看起来像一个函数指针声明。我非常感谢你的帮助。我已经包含了尽可能多的代码(注有行)来回答这个问题。如果没有,请告诉我,谢谢 typedef struct { char *lo; char *hi; } stack_node; void _quicksort (void *const pbase, size_t total_elems, size_t size, cmp_t cmp, void *ar

我一直在研究qsort的不同实现,在这里找到的源代码()中有一行我不理解。它看起来像一个函数指针声明。我非常感谢你的帮助。我已经包含了尽可能多的代码(注有行)来回答这个问题。如果没有,请告诉我,谢谢

typedef struct
{
    char *lo;
    char *hi;

} stack_node;


void _quicksort (void *const pbase, size_t total_elems, size_t size, cmp_t cmp, void *arg)
{

    char *base_ptr = (char *) pbase;

    const size_t max_thresh = 4 * size;

    if (total_elems == 0)

        return;

    if (total_elems > 4)
    {
        char *lo = base_ptr;
        char *hi = &lo[size * (total_elems - 1)];
        stack_node stack[(8 * sizeof(size_t))];
        stack_node *top = stack;

        /* Line below is a function pointer declaration?  Initializes struct? */

        ((void) ((top->lo = (((void*)0))), (top->hi = (((void*)0))), ++top));

        while ((stack < top))
        {
            char *left_ptr;
            char *right_ptr;

            char *mid = lo + size * ((hi - lo) / size >> 1);
typedef结构
{
char*lo;
char*hi;
}栈节点;
void\u快速排序(void*const-pbase,size\t-total\u-elems,size\t-size,cmp\t-cmp,void*arg)
{
char*base_ptr=(char*)pbase;
常量大小\u t最大值\u阈值=4*大小;
如果(总要素==0)
返回;
如果(总要素>4)
{
char*lo=基本ptr;
字符*hi=&lo[大小*(总元素-1)];
堆栈节点堆栈[(8*sizeof(size_t))];
堆栈_节点*top=堆栈;
/*下面一行是函数指针声明?初始化结构*/
((void)((top->lo=((void*)0)),(top->hi=((void*)0)),++top));
而((堆栈<顶部))
{
字符*左ptr;
字符*右\u ptr;
char*mid=lo+size*((hi-lo)/size>>1);

…代码继续

不,它不是一个函数指针声明。它只是一种复杂的表达方式

top->lo = 0;
top->hi = 0;
++top;
您可以使用
运算符将上述语句重写为单个表达式语句

top->lo = 0, top->hi = 0, ++top;
然后添加不必要的强制转换

top->lo = (void *) 0, top->hi = (void *) 0, ++top;
还有一堆冗余的
()
s

然后将整个内容强制转换为
(void)
(例如,抑制任何关于表达式结果“未使用”的潜在编译器警告)

现在你有了你的原始版本


我不清楚为什么有人决定对
运算符和大量冗余的
()
使用这种奇怪的语法。看起来像是一个宏扩展。可能是一段已经预处理的代码。
((void*)0)
部件可能很容易成为标准
NULL
宏的预处理器替代品。

查看URL,我们发现该行实际上是一个特定的宏定义

/* The next 4 #defines implement a very fast in-line stack abstraction. */
/* The stack needs log (total_elements) entries (we could even subtract
   log(MAX_THRESH)).  Since total_elements has type size_t, we get as
   upper bound for log (total_elements):
   bits per byte (CHAR_BIT) * sizeof(size_t).  */

#define STACK_SIZE        (CHAR_BIT * sizeof(size_t))
#define PUSH(low, high)   ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high)    ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY   (stack < top)
/*下一个4#定义实现一个非常快速的内嵌堆栈抽象*/
/*堆栈需要日志(total_elements)条目(我们甚至可以减去
log(MAX_THRESH))。由于total_元素的类型大小为
日志的上限(总元素):
每字节位数(字符位)*sizeof(大小t)*/
#定义堆栈大小(字符位*大小)
#定义推送(低、高)((无效)((顶部->低=(低)),(顶部->高=(高)),++顶部))
#定义POP(低、高)((空)(-top,(低=高->低),(高=高->高)))
#定义堆栈不为空(堆栈<顶部)
代码实际上出现在
PUSH
的定义中,其概要出现在
POP
中。使用额外的
()
s是为了确保
++top
--top
以正确的顺序发生
内联


当我们看到
qsort.C
顶部的版权(C)1991-2017消息时,它以这种方式实现的原因就更清楚了。1991年的编译器可能在内联函数方面真的很差劲。

链接中的代码没有这样的行。它只是说
PUSH(NULL,NULL);
。您是从哪里获得此版本的?您为什么要查看此表单?上面的代码是后期预处理,非常有用。谢谢。这是后期宏扩展。
((void) ((top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top));
/* The next 4 #defines implement a very fast in-line stack abstraction. */
/* The stack needs log (total_elements) entries (we could even subtract
   log(MAX_THRESH)).  Since total_elements has type size_t, we get as
   upper bound for log (total_elements):
   bits per byte (CHAR_BIT) * sizeof(size_t).  */

#define STACK_SIZE        (CHAR_BIT * sizeof(size_t))
#define PUSH(low, high)   ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high)    ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY   (stack < top)