我刚开始第一次使用typedef,而且我也没有使用过很多结构,尽管我很了解它们。
我创建了一个类型调用Max7219_t
,如下所示:
typedef struct {
uint16_t digit1,
uint16_t digit2,
uint16_t digit3,
uint16_t digit4,
uint16_t digit5,
uint16_t digit6
uint16_t digit7,
uint16_t digit8,
uint16_t intensity,
uint16_t _shutdown,
uint16_t scanl,
uint16_t testmode,
uint16_t decodetype } Max7219_t;
稍后在代码中,在我声明了此类型的变量并添加了值之后,我需要一次传输struct
中的每个字节,理想情况是在for
循环中。
除了直接引用每个成员(即*display->digit1
,然后是*display->digit2
等)之外,还有什么方法可以做到这一点吗?从本质上讲,是否有一种方法可以像使用数组一样枚举每个条目?
我不想只将整个事物转换为数组,因为我几乎肯定会在开发过程中为这个和其他结构添加不同的类型。
我觉得我在这里遗漏了一些明显的东西。我以为我可以只增加一个指针,但由于结构成员的大小不一样,我觉得这不会像指向数组一样工作。另外,在迭代for
循环时,我不确定for(q = 0; q != sizeof(Max7219_t); q++)
之类的东西是否也能正常工作。
非常感谢任何帮助!
答案 0 :(得分:2)
如果您需要访问"隐藏"在struct之后,有几种方法:
最后一种方法似乎最接近你想要的,所以也许是这样的:
Max7219_t yourStructure;
// ...
const uint8_t* const pointer = (const uint8_t*)&yourStructure;
for (size_t i = 0; i < sizeof(yourStructure); ++i)
{
uint8_t byte = pointer[i];
...
}
你的问题并不完全清楚......
答案 1 :(得分:1)
由于您的类型相同,因此请创建这些类型的数组:
typedef struct
{
uint16_t mode[13] ;
} Max7219_t ;
你通过任何其他数组迭代它。
Max7219_t var = { 0 } ;
for( size_t i = 0 ; i < 13 ; i++ )
{
var.mode[i] = 12345 ;
}
此方法不允许您使用元素的名称:digit1,digit2 ......
您可以使用枚举来获取这些枚举,这些枚举对应于数组中的正确元素。
enum
{
digit1 = 0 ,
digit2 = 1 ,
digit3 = 2 ,
//... and so on
} ;
答案 2 :(得分:1)
如果你想:
稍后在代码中,在我声明了这种类型的变量并添加了值之后,我需要一次一个地传输结构中的每个字节,理想情况是在for循环中。
您可以使用memcpy()
复制原始数据,或者如果您想要逐字节访问<34> &#34;你可以:
char *ptr = (char*)&Max7219_t_instance;
for(int i = 0; i < sizeof(Max7219_t) ++i){
// Work with bytes
}
请注意,您不能将任何内容更改为数组,您可以使用不同类型转换创建指针来处理相同的数据。
如果你想通过结构成员进行迭代(并且它们不是同一类型......否则使用2501s answer)你需要反思。有are ways how to employ reflection in C,但我会担心性能影响。
想象一下情况:
??? value = display->digit[x]; // This can be char/short/int/long...
您可以在左侧使用long
解决此问题,但使用浮点数和字符串...
哦,好吧......您可以为MS编译器解析.pdb
或者为gcc打开调试部分(启用-g
),但它远离便携式C实现。
但是当您需要使用整数类型(或者您可以使用原始二进制数据)时,可以创建如下数组:
int Max7219_t_structure_members[] = {sizeof(uint16_t), sizeof(uint16_t) ..., 0 };
每个结构成员的大小和
sum(Max7219_t_structure_members) == sizeof(Max7219_t)
为了论证,让我们想象你需要使用最大sizeof(long)
字节大的类型。
int offset = 0;
for(int i; Max7219_t_structure_members[i]; ++i){
long tmp = 0;
// This line will work only on little-endian machines
memcpy(&tmp, ((char*)insntance)+offset, Max7219_t_structure_members[i])
// Do your work
offset += Max7219_t_structure_members[i];
}
但是你必须手动维护结构。我不知道任何可以帮助您使用自动版本的宏(至少在gcc中)。
答案 3 :(得分:0)
由于结构中的所有元素都是相同的大小,理论上你可以声明一个指向uint16_t的指针,指向结构中的第一个元素,如下所示:
Max7219_t my_structure;
uint16_t *p = (uint16_t *)&my_structure;
for (int i = 0; i < ELEMENTS_IN_STRUCTURE; i++, p++) {
*p = some_value;
}
但是,我不建议这样做,因为如果你在结构中添加了一些其他变量类型它就行不通,它完全违背了结构和类型的目的。
我要做的是编写一个根据需要填充值的函数。
void init_max_77219(Max7219_t *my_structure) {
my_strcture->digit1 = ...;
}
然后只要你需要初始化结构就调用它。
对于这个特殊场景(结构充当uint16_t
的包),如果需要,可以坚持使用数组,然后在其他地方存储不同类型的变量。
答案 4 :(得分:-1)
工会的用例:
union variable {
Max7219_t yourStructure;
uint16_t array[13];
);