示例:
struct dummy
{
int var;
};
为什么使用这样的结构?大多数情况下,我在一些头文件中看到过它们。
atomic_t
类型也是这样定义的。不能简单地使用:
typedef int atomic_t;
答案 0 :(得分:7)
它更具扩展性。
假设将来您意识到struct dummy
应该包含名称字段,那么您可以将其定义更改为:
struct dummy
{
int var;
char name[30];
};
不会改变很多应用程序代码。
答案 1 :(得分:5)
另一个用途是将整个数组传递给函数。
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
答案 2 :(得分:5)
除了可扩展性之外,这个成语还使语法上不可能对类型进行常规算术,其含义在语义上没有意义。
E.g:
typedef uint32_t myObject;
myObject x, y;
...
y = x + 3; // meaningless, but doesn’t produce an error.
// may later cause runtime failure.
v.s。
typedef struct { uint32_t var; } myObject;
myObject x, y;
...
y = x + 3; // syntax error.
这可能看似人为,但它偶尔会非常有用。
答案 3 :(得分:3)
主要是保持兼容性,因为可能更早的结构有其他元素。
或者因为它可能会在以后添加其他元素。
(甚至结构的itnernal版本不仅仅有一个成员(我真正想象的atomic_t
- 类型。)
答案 4 :(得分:3)
并非所有可以用32位表示的东西都应该被视为数字。即使具有数值的事物也可能具有语义,这表明它们需要特殊处理。例如,假设处理器具有“原子增量”指令,但它比“正常”增量指令慢。如果想要在一个地方以原子方式递增fnord
并在另一个地方递减它,可以使用:
volatile int fnord;
...
atomic_inc(&fnord);
...
atomic_dec(&fnord);
然而,问题在于,如果其中一个应该增加fnord
的地方碰巧使用fnord++
而不是atomic_inc(&fnord);
,那么编译器将很乐意生成一个“正常”增量指令,代码可能在大多数时间都可以工作,但它可能会以难以追踪的方式失败。
用结构替换int
(并定义atomic_inc
内联函数以使用它)可以防止编译错误的代码fnord++;
。它不会防范fnord.var++;
,但会让程序员有机会检查结构,看看增加它的正确方法是什么。