例子:
struct dummy
{
int var;
};
为什么会使用这样的结构?我大多数情况下都在一些头文件中看到它们。
atomic_t
类型也是这样定义的。难道不能简单地定义为:
typedef int atomic_t;
它更具可扩展性。
假设在未来,您意识到struct dummy
应该包含一个名称字段,那么您可以更改其定义为:
struct dummy
{
int var;
char name[30];
};
无需大量更改您的应用程序代码。
typedef uint32_t myObject;
myObject x, y;
...
y = x + 3; // meaningless, but doesn’t produce an error.
// may later cause runtime failure.
相对比较
typedef struct { uint32_t var; } myObject;
myObject x, y;
...
y = x + 3; // syntax error.
atomic_t
名称相匹配。我自己在设计8位微处理器的闪存“文件系统”时使用了这个概念,其中需要能够从一对字节中形成虚拟页ID或物理页ID(暗示两者均为16位,并且使用任何更大的值都需要进行大量重构),但我想确保我不会意外地将物理页ID传递给期望逻辑页ID的例程,反之亦然。 - supercat另一个用途是将整个数组传递给函数。
struct s {
int a[3];
};
void f1(int a[]) // this evaluates to a pointer, same as void f1(int *a)
{
printf("%d\n", sizeof(a));
}
void f2(struct s *obj)
{
printf("%d\n", sizeof(obj->a));
}
int main(int argc, char **argv)
{
int a[3] = {1, 2, 3};
struct s obj;
obj.a[0] = 1;
obj.a[1] = 2;
obj.a[2] = 3;
f1(a);
f2(&obj);
return 0;
}
// output
// 8
// 12
a[3]
解析为f1,因此会丢失信息。如果您将指向a的指针解析为f1,则也不需要结构体,并在取消引用后获得此结果。 - dhein并非所有可以在32位中表示的东西都应该被视为数字。即使具有数值的东西也可能具有语义,这表明它们需要特殊处理。例如,假设处理器具有“原子递增”指令,但它比“普通”递增指令慢。如果想要在一个地方原子递增 fnord
并在另一个地方递减它,可以使用:
volatile int fnord;
...
atomic_inc(&fnord);
...
atomic_dec(&fnord);
大多数情况下是为了保持兼容性,因为可能早期版本的结构体有额外的元素。
或者是为了以后添加其他元素。
(甚至结构的内部版本有不止一个成员,这对于atomic_t
类型我真的可以想象。)