(int (*)(void *, void *))(numeric ? numcmp : strcmp) ?

查看:250
本文介绍了(int (*)(void *, void *))(numeric ? numcmp : strcmp) ?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

描述:
这是The C Programming Language书中实现多行文本排序的部分代码。
实现排序的有两个函数,自定义的numcmp和库函数strcmp。
lineptr是一个二级指针,用来存储多行文本。

全部代码地址:
https://github.com/WebFeng/learn_c/blob/master/e_arr_point/sort_textline2.c

代码部分实例:

char *lineptr[MAXLINES];

qsort1((void **)lineptr, 0, nlines-1, (int (*)(void *, void *))(numeric ? numcmp : strcmp));

int numcmp(char *s1, char *s2)

问题:
1、(第二行代码)为什么要把lineptr转成void类型?
2、lineptr转成void类型后,由于numcmp和strcmp的参数类型与void不符,则需要用(int (*)(void *, void *))把函数参数强制转换成void类型。那么请问此处的强制类型转换只是为了让编译器知道函数的形参类型与实参类型相符么?C的底层究竟做了什么?是真的把原本接收char *类型的函数改成了接收void *类型了么?
3、直接把函数参数改写成void *,然后在numcmp中把参数转int,在strcmp中把参数转char,这样就不用函数的强制类型转换了。numcmp接收void *类型参数会不会让代码看起来很怪?

解决方案

1:为什么要把lineptr转成void类型?
因为声明,void *lineptr[] 和 void **lineptr 是等价的

void qsort1(void *lineptr[] ..... )

至于 char** 为什么和 void ** 不兼容
不管你是几级指针,归根到底都是指针,所以都能和void *兼容,void * 本来就是一个抽象的指针类型

char **a;
void *ptr = a;
char ***a
void ptr = a; // 都是完全兼容的

2 :函数的强制类型转换只是为了让编译器知道函数的形参类型与实参类型相符么?C的底层究竟做了什么?是真的把原本接收char 类型的函数改成了接收void 类型了么?

void qsort1(..... int (*comp)(void *, void *));
int numcmp(char *, char *);
int strcmp( const char  *, const  char *);
numcmp  与 comp 类型兼容
但是 strcmp 却与 comp 不兼容 

strcmp 与 comp 不兼容的原因
const void * 表示你可以不能修改 指针指向的内容
void * 表示你可以修改


不知道你有没有看过qsort库函数的源代码

void __cdecl qsort (  
    void *base,  
    size_t num,  
    size_t width,  
    int (__cdecl *comp)(const void *, const void *)  
    )    

第一:不管整形数组,还是字符串数组,都是void 接受,而你却是void *
第二 :comp 函数的参数是const void *

不管是库函数strcmp , 还是你自己写的比较函数,最好都用 加上const 

修改以后的代码

这篇关于(int (*)(void *, void *))(numeric ? numcmp : strcmp) ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆