C语言如何做到让函数知道传入的数据类型?

在C语言里,有一种指针类型void*,它可以允许在函数传参时传递不同类型的指针:
void test(void* p){
    //省略
}

int main(){
    int a = 3;
    char b = 'h';
    test(&a);
    test(&b);
}
在上面的情况里,int类型的指针与char类型的指针都可以传入test函数,但是怎么让test函数知道传入的数据类型并做对应的处理呢?

下面这个例子:

void test(void* p) {
    \\...
}

int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test(a);
    test(b);
}

有一个int数组与char数组,我需要将它们依次传入test处理,如果我将void指针p转换为int型:
void test(void* p) {
    int* pa = (int*)p;
    printf("%d\n", *pa);
}

int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test(a);
    test(b);
}

img

结果自然是数组a中的值能正常处理,b中的则不行。
void test(void* p) {
    char* pa = (char*)p;
    printf("%d\n", *pa);
}

int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test(a);
    test(b);
}

img

如果把void指针p转换为char类型,自然数组b中的值能正常处理,a不行。所以,怎样才能做到让test函数知道传入数据是什么类型,并做对应的处理呢?感谢

c++有模板能实现,c语言可以用宏定义


#include<stdio.h>

#define test(ptr,type) {\
type* p = (type*)ptr;\
printf("%d\n", *p);\
}

int main(){
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test(a,int);
    test(b,char);
    return 0;
}

我觉得可以试试看需要在调用test函数时将数据类型一并传入,这样test函数就可以根据传入的数据类型进行相应的处理。
我写个例子给你
比如哈我调用test函数时将数据类型(1代表int类型,2代表char类型)一并传入,在test函数内部根据传入的数据类型进行相应的处理。
代码如下:

void test(void* p, int type) {
switch(type) {
case 1: {
int* pa = (int*)p;
printf("%d\n", pa);
break;
}
case 2: {
char pa = (char*)p;
printf("%d\n", *pa);
break;
}
default: break;
}
}

int main() {
int a[5] = { 300,400,500,600,700 };
char b[3] = { 6,7,8 };
test(a, 1);
test(b, 2);
}

如果你想让test函数知道传入数据是什么类型,我只能给你另一种方法,在调用 test 函数前要额外传递类型信息。

#include <stdio.h>

void test(void* p, int type) {
    if (type == 1) {
        int* pa = (int*)p;
        printf("%d\n", *pa);
    } else if (type == 2) {
        char* pa = (char*)p;
        printf("%c\n", *pa);
    }
}

int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { '6','7','8' };
    test(a, 1);
    test(b, 2);
    return 0;
}


据我所知,C语言没有这种手段。上面几位已经解释的很清楚了,而且提供了其他的方法。我这里就给另外一种方法。

#include <stdio.h>

enum Type {
    kInt, 
    kChar,
};

struct Data {
    void* data;
    enum Type type;
};

void test(struct Data d) {
    switch (d.type) {
    case kInt:
        printf("%d\n", *(int*)d.data);
        break;
    case kChar:
        printf("%d\n", *(char*)d.data);
        break;
    default:
        break;
    }
}

int main() {
    int a = 5;
    struct Data d1 = {
        .data = &a,
        .type = kInt,
    };
    char c = 'a';
    struct Data d2 = {
        .data = &c,
        .type = kChar,
    };

    test(d1);
    test(d2);
}

一种方法是在函数test外部声明一个标志位来指示数组的类型,然后在函数内部根据标志位的值进行相应的处理。另一种方法是通过函数重载来实现,不同的数组类型使用不同的函数实现。
第一种方法为例:

#include<stdio.h>

enum DataType {INT_TYPE, CHAR_TYPE};

void test(void* p, DataType type) {
    if(type == INT_TYPE) {
        int* pa = (int*)p;
        printf("%d\n", *pa);
    } else if(type == CHAR_TYPE) {
        char* pa = (char*)p;
        printf("%d\n", *pa);
    }
}
 
int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test(a, INT_TYPE);
    test(b, CHAR_TYPE);
    return 0;
}

以第二种方法为例

#include<stdio.h>

void test_int(int* p) {
    printf("%d\n", *p);
}
 
void test_char(char* p) {
    printf("%d\n", *p);
}
 
int main() {
    int a[5] = { 300,400,500,600,700 };
    char b[3] = { 6,7,8 };
    test_int(a);
    test_char(b);
    return 0;
}
不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^