当然有一个前提,就是你需要按照它的协议,实现一个compar函数,用于比较大小。 像这样类似的例子,C语言中还有很多,不过相比于其他语言,如C++中的模板,这种所谓的泛型,确实有些小巫见大巫了。 总结 C语言语法上本身基本不支持泛型编程,但是借助_Generic关键字和一些手段,可以实现泛型编程。
使用void指针:使用void指针来实现任意类型的数据传递,需要在使用时进行类型转换。 使用结构体和函数指针:通过结构体和函数指针组合来实现泛型数据结构和函数。 使用预处理器和宏:利用预处理器和宏定义来生成泛型代码,可以根据不同的数据类型生成相应的代码。 使用联合体:通过联合体来实现不同类型的数据共享内存,可以实现...
如上,也可以实现泛型的函数:void* lsearch(void* key, void *base, int n, int elemSize){ for(int i = 0;i < n; ++i){ void *elemAddr = (char *)base+i*elemSize; if(memcmp(key, elemAddr, elemSize) == 0) return elemAddr; } return NULL;} 代码第三行:将数组...
让我们通过一个具体的例子来理解如何使用 _Generic 实现泛型编程。 实现getTypeName 函数 假设我们想要实现一个 getTypeName 函数,该函数返回变量 var 的类型名称。可以这样写: #define GET_TYPENAME(var) _Generic((var), \ int: "int", \ char: "char", \ float: "float", \ double: "double", \ cha...
在之前的文章分享 Linux 内核源码实现的循环双链表也是一种泛型的思想(不了解的请戳这里:Linux内核源码剖析(一)--不同寻常的双向链表),利用用户自定义的结构体包含 Linux 内核双链表节点,通过结构体元素偏移找到用户结构体起始位置,实现一种“泛型”链表。不过今天小 C 分享的是另外一种实现思路,请往下看~ ...
尽管泛型宏在C语言中提供了一种实现泛型编程的方法,但它们也有一些显著的局限性:类型安全:宏展开是在编译前进行的,这意味着类型错误只能在编译时检测到,而不是在编写代码时。此外,由于宏是通过文本替换工作的,因此它们可能会引入意外的类型不匹配或转换。调试困难:由于宏在编译前被展开,因此它们不会出现在...
与C++不同,C语言没有类模板和函数模板这些概念,因此难以实现泛型编程。在C语言中,需要手动编写多个相似的函数来处理不同类型的数据,或者使用void指针等机制来传递不同类型的参数,这样会增加代码的复杂性和不易维护性。因此,在处理复杂的数据结构和算法时,C++的泛型编程能力优势明显,可以让程序员更加高效地完成...
利用C实现泛型(generics)效果 用一个函数实现一个算法,能够处理不同的数据类型(int,double,字符数组),这在C++和python这种高级语言中很常见也很容易做到。 在C中,灵活地使用void指针,内存操作,函数指针也能实现类似的效果。 下面一段代码,实现了一个泛型的原地洗牌的算法,需要传入数组首元素地址,元素个数与每个...
c语言是如何实现泛型链表 最近有看一点Linux内核源码,发现内核里大量使用了list_head结构体。百度查了一下,原来内核利用这个结构体实现了泛型。 自认为对链表已经很熟悉的我,决定自己实现一下。 下面以Node和list_head为例。 上图就是循环链大致思路了。(画的不好)...