使用指针和 offsetof() 访问结构的正确方法是什么
What is correct way to access a struct using pointer and offsetof()
我有以下代码,以便能够访问结构数组中的多个字段(为简单起见,我已将其减少为两个)。最终指针计算的正确咒语是什么
*(ptr + offset) = data;
因为我总是得到:
错误:从类型“int32_t”{又名“int”}
分配给类型“struct osc_in_data”时类型不兼容
#define NumHarmonics 10
int32_t data1;
int32_t data2;
struct osc_in_data
{
int32_t LevelAttackRate;
int64_t LevelPeakLevel;
int32_t LevelDecayRate;
} OscControl[NumHarmonics];
void SetADSRvalues(int32_t offset, int32_t data)
{
int32_t harmonic;
struct osc_in_data *ptr;
for (harmonic = 0; harmonic < NumHarmonics; harmonic++)
{
ptr = &OscControl[harmonic];
*(ptr + offset) = data;
}
}
SetADSRvalues(offsetof(struct osc_in_data, LevelAttackRate), data1)
SetADSRvalues(offsetof(struct osc_in_data, LevelDecayRate), data2)
成员具有 int32_t
类型,因此指向它们的指针是 int32_t*
。
offsetof(...)
只是以字节为单位的偏移量。因此,您只需将指针指向要修改的成员的结构。然后使用普通加法将偏移量添加到指针,并记住使用 char*
指针一次添加一个字节。然后只需将指针转换为正确的类型并取消引用并访问它。
void SetADSRvalues(size_t offset, int32_t data)
{
for (size_t harmonic = 0; harmonic < NumHarmonics; harmonic++) {
// take the pointer to the structure we want to modify
void *base = &OscControl[harmonic];
// arithmetic using void* pointers is invalid
// so convert to `char*` pointer before arithmetic
char *basechar = base;
// then add the offset - just plain addition
// results in the address of the member inside the struct
void *memberpnt = basechar + offset;
// the member is `int32_t`, so the pointer has to be `int32_t*`
int32_t *memberpnt_int32 = memberpnt;
// finally set the value
*memberpnt_int32 = data;
// or a oneliner version:
*(int32_t*)((char*)&OscControl[harmonic] + offset) = data;
}
}
offsetoff
函数告诉您同一结构内 2 个内存地址之间的字节距离。
使用下面的代码,
*(ptr + offset) = data;
对struct osc_in_data
指针进行指针运算,与ptr[offset] = data;
相同
您可以尝试的是。
memcpy((char *)ptr + offset, data, sizeof data);
我有以下代码,以便能够访问结构数组中的多个字段(为简单起见,我已将其减少为两个)。最终指针计算的正确咒语是什么
*(ptr + offset) = data;
因为我总是得到:
错误:从类型“int32_t”{又名“int”}
分配给类型“struct osc_in_data”时类型不兼容#define NumHarmonics 10
int32_t data1;
int32_t data2;
struct osc_in_data
{
int32_t LevelAttackRate;
int64_t LevelPeakLevel;
int32_t LevelDecayRate;
} OscControl[NumHarmonics];
void SetADSRvalues(int32_t offset, int32_t data)
{
int32_t harmonic;
struct osc_in_data *ptr;
for (harmonic = 0; harmonic < NumHarmonics; harmonic++)
{
ptr = &OscControl[harmonic];
*(ptr + offset) = data;
}
}
SetADSRvalues(offsetof(struct osc_in_data, LevelAttackRate), data1)
SetADSRvalues(offsetof(struct osc_in_data, LevelDecayRate), data2)
成员具有 int32_t
类型,因此指向它们的指针是 int32_t*
。
offsetof(...)
只是以字节为单位的偏移量。因此,您只需将指针指向要修改的成员的结构。然后使用普通加法将偏移量添加到指针,并记住使用 char*
指针一次添加一个字节。然后只需将指针转换为正确的类型并取消引用并访问它。
void SetADSRvalues(size_t offset, int32_t data)
{
for (size_t harmonic = 0; harmonic < NumHarmonics; harmonic++) {
// take the pointer to the structure we want to modify
void *base = &OscControl[harmonic];
// arithmetic using void* pointers is invalid
// so convert to `char*` pointer before arithmetic
char *basechar = base;
// then add the offset - just plain addition
// results in the address of the member inside the struct
void *memberpnt = basechar + offset;
// the member is `int32_t`, so the pointer has to be `int32_t*`
int32_t *memberpnt_int32 = memberpnt;
// finally set the value
*memberpnt_int32 = data;
// or a oneliner version:
*(int32_t*)((char*)&OscControl[harmonic] + offset) = data;
}
}
offsetoff
函数告诉您同一结构内 2 个内存地址之间的字节距离。
使用下面的代码,
*(ptr + offset) = data;
对struct osc_in_data
指针进行指针运算,与ptr[offset] = data;
您可以尝试的是。
memcpy((char *)ptr + offset, data, sizeof data);