同一个函数能够处理不同结构体的数据
1. 使用 void*
指针和类型标识符
可以定义一个通用的处理函数,该函数接受一个 void*
指针和一个类型标识符,通过类型标识符确定指针指向的数据类型并进行相应处理。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int intValue;
} IntData;
typedef struct {
float floatValue;
} FloatData;
typedef struct {
char strValue[20];
} StringData;
typedef enum {
TYPE_INT,
TYPE_FLOAT,
TYPE_STRING
} DataType;
void processData(void *data, DataType type) {
switch (type) {
case TYPE_INT:
printf("Int value: %d\n", ((IntData *)data)->intValue);
break;
case TYPE_FLOAT:
printf("Float value: %f\n", ((FloatData *)data)->floatValue);
break;
case TYPE_STRING:
printf("String value: %s\n", ((StringData *)data)->strValue);
break;
default:
printf("Unknown type\n");
break;
}
}
int main() {
IntData intData = {10};
FloatData floatData = {3.14};
StringData stringData;
snprintf(stringData.strValue, sizeof(stringData.strValue), "Hello, world!");
processData(&intData, TYPE_INT);
processData(&floatData, TYPE_FLOAT);
processData(&stringData, TYPE_STRING);
return 0;
}
2. 使用联合体和类型标识符
可以将不同结构体的实例嵌入一个联合体中,并使用类型标识符来确定当前数据类型。
#include <stdio.h>
#include <string.h>
typedef struct {
int intValue;
} IntData;
typedef struct {
float floatValue;
} FloatData;
typedef struct {
char strValue[20];
} StringData;
typedef enum {
TYPE_INT,
TYPE_FLOAT,
TYPE_STRING
} DataType;
typedef struct {
DataType type;
union {
IntData intData;
FloatData floatData;
StringData stringData;
} data;
} ContextDependentData;
void processData(ContextDependentData *var) {
switch (var->type) {
case TYPE_INT:
printf("Int value: %d\n", var->data.intData.intValue);
break;
case TYPE_FLOAT:
printf("Float value: %f\n", var->data.floatData.floatValue);
break;
case TYPE_STRING:
printf("String value: %s\n", var->data.stringData.strValue);
break;
default:
printf("Unknown type\n");
break;
}
}
int main() {
ContextDependentData var;
var.type = TYPE_INT;
var.data.intData.intValue = 10;
processData(&var);
var.type = TYPE_FLOAT;
var.data.floatData.floatValue = 3.14;
processData(&var);
var.type = TYPE_STRING;
snprintf(var.data.stringData.strValue, sizeof(var.data.stringData.strValue), "Hello, world!");
processData(&var);
return 0;
}
3. 使用函数指针
可以定义处理不同数据类型的函数,并使用函数指针调用相应的处理函数。
#include <stdio.h>
typedef struct {
int intValue;
} IntData;
typedef struct {
float floatValue;
} FloatData;
typedef struct {
char strValue[20];
} StringData;
void processIntData(void *data) {
printf("Int value: %d\n", ((IntData *)data)->intValue);
}
void processFloatData(void *data) {
printf("Float value: %f\n", ((FloatData *)data)->floatValue);
}
void processStringData(void *data) {
printf("String value: %s\n", ((StringData *)data)->strValue);
}
typedef void (*ProcessDataFunc)(void *);
void processData(void *data, ProcessDataFunc func) {
func(data);
}
int main() {
IntData intData = {10};
FloatData floatData = {3.14};
StringData stringData;
snprintf(stringData.strValue, sizeof(stringData.strValue), "Hello, world!");
processData(&intData, processIntData);
processData(&floatData, processFloatData);
processData(&stringData, processStringData);
return 0;
}
4. 使用宏
可以定义宏来简化对不同数据类型的处理函数的调用。
#include <stdio.h>
typedef struct {
int intValue;
} IntData;
typedef struct {
float floatValue;
} FloatData;
typedef struct {
char strValue[20];
} StringData;
#define PROCESS_DATA(data, type) process##type##Data(data)
void processIntData(void *data) {
printf("Int value: %d\n", ((IntData *)data)->intValue);
}
void processFloatData(void *data) {
printf("Float value: %f\n", ((FloatData *)data)->floatValue);
}
void processStringData(void *data) {
printf("String value: %s\n", ((StringData *)data)->strValue);
}
int main() {
IntData intData = {10};
FloatData floatData = {3.14};
StringData stringData;
snprintf(stringData.strValue, sizeof(stringData.strValue), "Hello, world!");
PROCESS_DATA(&intData, Int);
PROCESS_DATA(&floatData, Float);
PROCESS_DATA(&stringData, String);
return 0;
}
总结
以上方法展示了如何在C语言中实现同一个函数能够处理不同结构体的数据。根据具体需求和场景,可以选择使用 void*
指针和类型标识符、联合体和类型标识符、函数指针或宏来实现这一功能。每种方法都有其优缺点,选择合适的方法可以提高代码的灵活性和可维护性。