【问题标题】:Please explain void pointers in C请解释 C 中的 void 指针
【发布时间】: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


【解决方案1】:

也许您应该阅读一本介绍性的 C 书籍,它解释了指针的概念。你好像有点糊涂了。

那么你必须把 void * 当作一个指针,它可以指向任何内存位置,但没有该位置所包含内容的类型信息。

当您想使用该位置时,您必须通过转换为适当类型的指针来告诉编译器 void 指针指向的类型。

【讨论】:

  • 您和上面的一些 cmets(Mike 和 Jonathan Leffler)帮助了我。非常感谢
  • 你永远不会得到那个 RedX 的答案。当书面内容不适合他们的世界时,人们会投反对票。我投了赞成票,您愿意回答,而且您的回答还可以,并且符合 OP 的理解水平。
猜你喜欢
  • 2011-11-13
  • 2013-03-15
  • 2017-03-09
  • 1970-01-01
  • 2016-05-23
  • 2011-04-01
相关资源
最近更新 更多