*(char**) 与 (char*) 的区别


斯坦福大学公开课《编程范式》中讲到用C语言实现泛型的linear search。其中的比较函数为void (*cmpfn)(void* vp1, void* vp2)。那么,如果是比较两个字符串数组,该如何写这个比较函数呢?


一般思路都没啥神奇的地方,将void* 类型转换成想要的类型,然后已知类型的比较就可以了。


int str_comp(void* vp1, void* vp2)
{
	char* str1 = *(char**) vp1;
	char* str2 = *(char**) vp2;
	// do something with str1 and str2 ...
}


那么问题就来了,为什么要采用*(char**) 方式, 而不是(char*)方式呢?后者还有因为编译器的支持,可以省略书写的特性(观察前面一个int的例子就是如此)。


视频中的教授讲得很清楚。*(char**)形式是有一步跳跃的,而(char*)显然没有。我们把前者展开成完整形式:*((char**)vp1+0)。表示将vp1看成一个数组的话,第0号元素的内容(是一个char*类型)。


概念太抽象,举个具体的例子:

char* str1 = "hello";
char* str2 = "world";
str_comp(&str1, &str2);

在函数中如何做类型转换呢?

我们传入的很显然是一个char** 变量。那么,通过*(char**) vp1 或者 ((char**)vp1)[0] 形式就可以获得“hello” 字符串的首地址。而(char*)获得是什么呢?

假设“hello”的首地址为1000,&str1 的值为2000,那么vp1的值是2000(形参实参自行脑补),(char*) vp1 的值显然还是2000,*((char*) vp1+0) 的值为1000拆成4个char所显示的第一个byte,以此类推。可以想象最终打印出来的字符串是(char*)1000后面跟一串乱码。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值