【问题标题】:is it possible to retrieve back the argument's datatype in called function when using same function for different input data types in c?在 c 中对不同的输入数据类型使用相同的函数时,是否可以在被调用函数中检索参数的数据类型?
【发布时间】:2017-11-15 23:11:01
【问题描述】:

我必须对不同的数据类型使用相同的函数以避免额外的函数和冗长的代码。 我在函数中使用 (void*) 参数,并想取回我从 main 发送的相同数据类型。即如果 int 来自 main,我应该能够从“func”的 void* 猜测 int 数据类型。这是示例函数...

void func(void* input)
{
    if(input is int)
        printf("%d", input);
    else if (input is char)
        printf("%c", input);
    else if (input is struct)
        //do somthing;
    } 

主要是:

int main()
{
    int q=1;
    char w='c';
    func(&q);
    func(&w);
    func(&struct);
    return 0;
}

【问题讨论】:

  • “否”。常见的方法是传递一个“标记的结构/联合”(或依赖其他上下文数据,例如 fscanf)。
  • @user2864740:你可以在 C11 中使用包装宏来伪造它,例如#define func(p) (printf(_Generic(*(p), int: "%d", char: "%c"), (p))).

标签: c


【解决方案1】:

当函数参数被声明为void * 时,任何类型信息都不适用于该函数。 C 不提供检查void * 变量以确定其真实类型的方法。

这意味着当您使用void * 参数描述的函数用于多种类型时,该参数必须包含某种类型的注释或指示。

一种标准方法是使用 struct,其中包含一个类型指示符,后跟一个支持所有各种类型的 union

typedef struct {
    unsigned short  usType;
    union {
        int iValue;
        float fValue;
    } U;
} MyVoidType;

另一种方法是使用void * 参数来表示函数要处理的事物,并使用第二个参数指示类型。

func(void *pItem, unsigned short usType)
{
    switch (usType) {
        case 1:
            {
                ItemType1 *pItem1 = pItem;
                // do things with pItem1
            }
            break;
        //  other cases for other types
    }
}

这类似于使用varargs 可变参数功能时可能遇到的问题。使用varargs,编译器知道还有其他参数,但是不会检查它们的类型,因为其他参数的类型信息不是函数定义/声明的一部分。 printf() 系列输出函数通过格式说明符提供了解决此问题的方法,函数使用这些说明符来确定参数的类型以及如何格式化值以打印参数。

这种方法存在问题,因为需要使用实际数据项维护注释或指示,并确保通过switch 语句中的适当更改来支持任何新类型。它还会导致编译现在无法为您进行参数检查的问题。

所以我也做了类似以下的事情。在一个文件中,我有一个函数可以处理我想要处理的所有各种类型。然后,这个函数被包装在多个版本中,并带有适当的类型化参数,这些参数只不过是使用适当的注释调用单个函数。

static short funcmain(void *pItem, unsigned short usType)
{
    switch (usType) {
        case 1:
            {
                ItemType1 *pItem1 = pItem;
                // do things with pItem1
            }
            break;
        // other case statements
    }
}

short funcType1 (ItemType1 *pItem)
{
    return funcmain (pItem, 1);
}

short funcType2 (ItemType2 *pItem)
{
    return funcmain (pItem, 2);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 2019-06-23
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多