以下代码来自The Practice of Programming:
int scmp(const void *p1, const void *p2)
{
char *v1, *v2;
v1 = *(char **) p1;
v2 = *(char **) p2;
return strcmp(v1, v2);
}
我不明白为什么要使用表达式*(char **) p1
。我们可以使用(char *)p1
吗?
他们之间有什么区别?
谢谢!
答案 0 :(得分:5)
否即可。 (char **)
是类型转换,并且在转换之前的一元*
取消引用指针。如果您只是v1 = (char *) p1
,那么v1
将被设置为等于p1
,当您想要的v1
等于char*
时p1
点。
答案 1 :(得分:2)
此功能中的界面设计稍微复杂一些 出现。人们可以设计scmp来指向字符串(这个顺便说一下是 strcmp 的作用)。
int scmp1(void * p1, void *p2) { return strcmp((char*)p1,(char*)p2);}
char *ptr = "bar";
char *ptr2 = "foo";
scmp1(ptr, ptr2); // this would make sense, however,
scmp(&ptr, &ptr2); // this is how the interface is designed.
比较函数没有明显的原因需要指向(指向字符串的指针)。 也许该函数将在以下章节中扩展为 swap 函数内部的指针 - 然后调用者将看到ptr指向“foo”而ptr2指向“bar”。 (这在scmp1 aka strcmp类型函数中是不可能的,其中要传递的指针可以分别在本地修改,即分别在scmp1和strcmp函数中修改,但没有更改传播给调用者)
答案 2 :(得分:2)
(char**)p1
表示 p1 是一个指向char *(char *)的指针(第二个*表示)。
所以得到值*(char**)p1
,结果是 char (我们可以说是一个字符串)*,可以指向v1(类型是 char *)。<登记/>
void *可以转换为任何指针*(char *,int *,double *)...... *
答案 3 :(得分:1)
让字符串"yourString1"
和"yourString2"
。
让s1
成为指向“yourString1”的指针,s2
成为指向“yourString2”的指针
s1->"yourString1"
s2->"yourString2"
调用scmp(s1,s2);
会导致p1
指向s1
而p2
指向s2
p1->s1->"yourString1"
p2->s2->"yourString2"
所以,p1
,p2
这里是双指点。
由于p1
,p2
是一个空指针,因此必须将其转换为char pointer
。
所以,
(char**)p1
会使p1成为char双指针
*(char**)p1
和*(char**)p2
现在指向s1
和s2
。
这将允许strcmp比较s1
和s2