【问题标题】:Differents argument types on the same function [duplicate]同一函数上的不同参数类型[重复]
【发布时间】:2015-05-01 01:54:14
【问题描述】:

我有一个十进制到八进制的转换函数,并且想根据某些选项使用 int 或 unsigned int 来调用它。我的第一个想法是复制/粘贴代码并更改参数的类型...有更好的方法吗?

【问题讨论】:

标签: c


【解决方案1】:

你可以使用联合:

#include <stdio.h>

enum octal_type {AS_INT, AS_UINT};

typedef union {
    int as_int;
    unsigned as_uint;
} t_octal; 

void fn(t_octal value, enum octal_type type)
{
    switch (type) {
        case AS_INT:
            printf("%d\n", value.as_int);
            break;
        case AS_UINT:
            printf("%u\n", value.as_uint);
            break;
    }
}

int main(void)
{
    t_octal value;

    value.as_int = 5;
    fn(value, AS_INT);
    return 0;
}

或通用指针:

#include <stdio.h>

enum octal_type {AS_INT, AS_UINT};

void fn(const void *value, enum octal_type type)
{
    switch (type) {
        case AS_INT:
            printf("%d\n", *(int *)value);
            break;
        case AS_UINT:
            printf("%u\n", *(unsigned *)value);
            break;
    }
}

int main(void)
{
    int value = 5;

    fn(&value, AS_INT);
    return 0;
}

在 C11 下,您可以使用 _Generic 省略调用中的第二个参数:

#include <stdio.h>

enum octal_type {AS_INT, AS_UINT};

#define fn(x) fn_impl(x, \
    _Generic(*x, signed int: AS_INT, unsigned int: AS_UINT, default: AS_INT))

void fn_impl(const void *value, enum octal_type type)
{
    switch (type) {
        case AS_INT:
            printf("%d\n", *(int *)value);
            break;
        case AS_UINT:
            printf("%u\n", *(unsigned *)value);
            break;
    }
}

int main(void)
{
    int value = 5;

    fn(&value);
    return 0;
}

【讨论】:

    【解决方案2】:

    好吧,如果您需要在 C 中进行重载,您有三个选择。

    1. 自行实施 VFT。有很多方法可以创建 VFT 并根据您想要执行的操作调用适当的函数。只需在 C 中检查 OO 即可
    2. 使用预处理器。您可以在预处理器中使用与类型无关的过程。但是您必须对参数的类型进行多次检查,或者应用与类型无关的过程。
    3. 使用论据为您提供案例。你可以有一个带有三个参数的包装函数;主要的两个参数,可能是 void 指针类型,以及类型字符串、枚举、预处理器中定义的类型或其他类似行为之一。根据后者,您将进行类型转换并自己调用适当的函数。

    或者...您可以使用结构/联合(以类似对象的方式)并根据其特性进行适当的计算。但我认为,对于你必须做的最后一种方法来说,这将是太多的努力。其实,一切都太费劲了。我会做的是有一个函数,它的第一个参数是 void 指针,一个指向输出的指针和一个定义第一个参数类型的第三个参数。该过程是相同的,但您有不同的限制,可能会导致极端值或负值溢出。因此,通过第三个参数,您将对第一个 void 指针进行类型转换并进行转换。

    【讨论】:

    • 你应该如何通过检查整数的值来知道它是有符号的还是无符号的? :) 你不知道它是有符号还是无符号,所以你不知道如何解释这个值。 “超出有符号整数的限制”与“如果它是负数”是一回事。 (至少有二进制补码。)
    • 是的,@Jite。你是对的。实际上,我在看到您的评论之前就进行了编辑。
    • 我喜欢空指针方法,谢谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2021-02-18
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多