【问题标题】:type cast function arguments类型转换函数参数
【发布时间】:2015-08-21 20:02:05
【问题描述】:

我一直在玩 C 中的类型转换。特别是,我一直(跟随 K&R)尝试实现一个程序,该程序将采用“一般”类型的输入(具体来说,K&R 实现了一个对指向通用数据的指针数组)。在这样做的过程中,我遇到了以下问题:

#include <stdio.h>

int comp(int *a, int *b); //*a == *b

main()
{
    int a = 2;
    int b = 3;
    int *pa = &a;
    int *pb = &b;

    int (*pfunc)(void *, void *) = (int (*)(void *, void *)) comp;
    int fin = (*pfunc)((void *)pa, (void *)pb);

    printf("%d \n", fin);
}

这符合要求,并且可以满足您的期望。问题在于:

#include <stdio.h>

main()
{
    int a = 2;
    int b = 3;
    int *pa = &a;
    int *pb = &b;

    void *pVoid_a = (void *) pa;
    void *pVoid_b = (void *) pb;

    int fin_Void = (*pVoid_a == *pVoid_b);
}

没用。

为什么这是一个问题:据我了解,在类型转换中

int (*pfunc)(void *, void *) = (int (*)(void *, void *)) comp;

创建了一个指针“comp”的副本,除了这个副本指向的函数接受参数“void *”而不是“int *”,并分配给变量“pfunc”。否则, pfunc 和 comp 的行为方式相同。 (我想我在这里一定是错的,但我不确定为什么)

在第一个程序中,当 (void *)pa 和 (void *)pb 被传递给 pfunc 时,我希望制作 pa 和 pb 的两个副本,但现在它们的类型是 (void *) 并分配给不同的名称。这些副本通过 pcomp 发送,打印返回的值等。

我试图在第二个程序中重新创建这个过程,但它不起作用!出于某种原因,在将 pVoid_a 和 pVoid_b 传递给 pfunc 之后的第一个程序中,它们最终在函数体中表现得像“int *”,即使它们似乎没有任何理由.为什么 pVoid_a 和 pVoid_b 在第一个程序中恢复了它们的“int”行为,而在第二个程序中没有?

【问题讨论】:

  • “复制了指针comp”并不意味着“复制了它指向的函数”。它仍然调用原始函数,该函数仍然将其参数视为int*
  • 虽然这不是你的问题的原因,虽然它似乎有效,但将一个接受 int* 参数的函数转换为接受 void* 参数的函数是未定义的行为。
  • 一般来说,与qsort() 等一起使用的比较器函数的可接受样式是函数进行指针转换,而不是调用者。也就是说,您将编写:int comp(const void *p1, const void *p2) { int i1 = *(int *)p1; int i2 = *(int *)p2; if (i1 &lt; i2) return -1; else if (i1 &gt; i2) return +1; else return 0; } 并将这个准确键入的函数传递给qsort(),而无需进行任何强制转换。标准 C 库 qsort()bsearch() 函数采用带有 const void * 参数的比较器。根据您的要求调整常数。 (这与 K&R 不同。)

标签: c function casting void-pointers


【解决方案1】:

您在第一个程序中观察到的行为发生是因为void* 类型的任何变量都被隐式转换为任何其他指针类型。在第二个程序中,您需要明确说明要将 pVoid_apVoid_b 转换为哪种指针类型,否则您将取消对 void* 的引用,这没有任何意义。修复:

int fin_Void = (*(int*)pVoid_a == *(int*)pVoid_b);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 2013-11-15
    • 2020-02-06
    • 1970-01-01
    相关资源
    最近更新 更多