作为提供另一种方法来实现OP想要的但假设他需要数据隐藏的辅助答案,我介绍这段代码,它建立在我的第一个答案之上,在一个C文件中为元素类型提供通用访问,并在头文件中仅提供不透明的数据类型。请注意,为了说明指针是什么,我使用了element*,但它们都可以被我在头文件中定义的ELEM_HANDLE替换。ELEM_HANDLE抽象了我们正在处理元素指针的事实。由于我们使用了不透明类型,我们提供了可以调用的方法(在element.h中定义)来处理我们的不透明类型。
element.h:
#include <stdint.h>
typedef struct element element;
typedef element *ELEM_HANDLE;
extern element *element_new();
extern void element_delete(element *elem);
extern void element_set_value_raw(element *elem, uint16_t value_raw);
extern uint16_t element_get_value_raw(element *elem);
extern void element_set_value_scaled(element *elem, float value_scaled);
extern float element_get_value_scaled(element *elem);
extern void element_set_desc(element *elem, char *desc);
extern char *element_get_desc(element *elem);
element.c:
#include <stdint.h>
#include <stdlib.h>
typedef struct element
{
uint16_t value_raw;
float value_scaled;
char *desc;
} element;
element *element_new()
{
return calloc(1, sizeof(element));
}
void element_delete(element *elem)
{
free(elem);
}
void element_set_value_raw(element *elem, uint16_t value_raw)
{
elem->value_raw = value_raw;
}
uint16_t element_get_value_raw(element *elem)
{
return elem->value_raw;
}
void element_set_value_scaled(element *elem, float value_scaled)
{
elem->value_scaled = value_scaled;
}
float element_get_value_scaled(element *elem)
{
return elem->value_scaled;
}
void element_set_desc(element *elem, char *desc)
{
elem->desc = desc;
}
char *element_get_desc(element *elem)
{
return elem->desc;
}
testelem.c:
#include <stdio.h>
#include "element.h"
#define REG_READ_COUNT 2
void dostuff(element *sv[], int arrLen)
{
int index;
element *curelem;
uint16_t raw;
float scaled;
char *desc;
for (index = 0; index < arrLen ; index++){
curelem = sv[index];
raw = element_get_value_raw(curelem);
scaled = element_get_value_scaled(curelem);
desc = element_get_desc(curelem);
printf("%s, %d, %.4f\n", desc, raw, scaled);
}
}
int main()
{
unsigned int index;
element *sv[REG_READ_COUNT];
char desc1[] = "The answer to everything";
char desc2[] = "OtherStuff";
for (index = 0; index < sizeof(sv) / sizeof(element *); index++)
sv[index] = element_new();
element_set_value_raw(sv[0], 42);
element_set_value_scaled(sv[0], 6.66f);
element_set_desc(sv[0], desc1);
element_set_value_raw(sv[1], 123);
element_set_value_scaled(sv[1], 456.7f);
element_set_desc(sv[1], desc2);
dostuff(sv, REG_READ_COUNT);
for (index = 0; index < sizeof(sv) / sizeof(element *); index++)
element_delete(sv[index]);
return 0;
}
请注意,我在传递元素指针数组时,对
dostuff
的数组长度进行了修改。这为 dostuff 提供了足够的信息来确定数组中有多少个元素。这应该可以在C89或以上版本和C++编译器上正确编译(和运行),只需将
.c
文件重命名为
.cpp
。
我提供这个答案是因为使用前向声明和不透明类型是许多“C”语言共享对象创建的方式。这种机制允许将元素源编译成独立库或共享对象,并在不知道 element
数据类型长什么样的情况下使用它。实质上,我们在使用我们的模块和库之间提供了一个接口合同。如果我们修改 element.cpp
中结构元素的内部,则使用它的模块不需要重新编译(只需重新链接)。如果我们修改接口(合同),则使用库的客户端代码需要重新构建。
因此,最终可以使用前向引用(不透明类型)隐藏 C
数据类型的内部并提供一层抽象。这种机制通常由共享对象(.so
文件)用于构建可以被 C
程序使用的复杂库。
X *x
并拒绝X x[]
。 - M.Melement
周围创建抽象,则此处没有给出任何可接受的答案。如果不需要数据隐藏,则OP的选择是有道理的。因此,消除所有歧义的简单问题是 - 是否需要对element
进行数据隐藏? - Michael Petch