【发布时间】:2015-10-30 03:28:20
【问题描述】:
例如将char* str 传递给采用void *ptr 的函数
我意识到为了通过这个,我需要通过:
fnc(&str)
一旦进入 fnc(void *ptr) 函数,我需要取消引用才能使用它
fnc(void *ptr){
*(char **)ptr = other string
}
我通过反复试验了解到这一点,但从未真正理解为什么会发生这种情况
外面的*是什么意思?里面的 2 * (char __) 怎么样?
编辑:
例如,一个回调函数将 str1 传递为“&str”,将 str2 传递为“第一个元素为 char* 的数组的地址”
lfind(&str, arr, ...., cmp);
进入
int cmp_str_ptr(const void *str1, const void *str2){
return strcmp(*(char **)str1, *(char **)str2);
}
我真正想知道的是 * 在每个间接级别上的含义。 *(char *)str1 vs *(char **)str1 vs *(char)str1 如果最后一个有效,甚至与 *(char *)&str1 组合。
括号外的 * 与括号内的 * 是什么意思。不管使用什么功能,我都想知道这些是什么意思。
最终编辑:
感谢 Mike 帮我解决了这个问题,我现在意识到真正的问题在于类型转换,而不一定是一般的指针。我读过 K&R 的 c 编程语言,但直到现在我才明白。
总而言之,我要问的是为什么 strcmp 需要 *(char **)str1 作为值,在 Mike 的回答之后,我看到它被转换为指向 char* 的指针,因此需要取消引用它以便按照 strcmp(char *s1, char *s2) 要求。
除了在回调函数上创建相似性(对 char ** 的两次取消引用而不是一次强制转换和一次取消引用)之外,我仍然不知道 lfind 将第一个参数作为 &str 传递的原因。我从乔纳森的回答中假设了这一点,他提到没有必要在函数内使用 *(char **)ptr。
再次感谢大家的帮助。对于这个相对愚蠢的问题,我们深表歉意。
【问题讨论】:
-
您发布的代码会导致未定义的行为(尽管它在实际代码中有些常见!依赖于编译器不执行允许执行的优化)。如果您可以展示一个完整的工作示例来说明您的意思,它将改善您的问题。
strstr等函数不使用这种技术 -
多种误解...(1) 您不一定需要使用
fnc(&str)— 使用fnc(str)就可以满足多种用途; (2) 一旦在函数内部,您不一定会在函数内部使用*(char **)ptr;; (3)strstr()和strcmp()不接受void *参数。如果被调用函数需要修改调用函数中的指针,您所描述的可能是正确的,但这需要将指向指针的指针作为void *传递,这并不是您所建议的。 -
括号内:
char**只是一个类型。通过将类型放在括号中,您创建了一个 typecast。它是一个指向char的指针。括号外是dereference;也就是说,您正在访问char**指向的char*指针。
标签: c void-pointers