C语言 大小运算符如何为结构工作



我正在阅读K&R。在示例中,它将结构数组定义为:

struct key {
char * word;
int count;
} keytab[] = {
"auto", 0,
"break", 0,
/*more members*/
"while", 0
};

然后要计算数组的大小,它使用两种方法:

1) #define NKEYS (sizeof keytab/ sizeof(struct key))
2) #define NKEYS (sizeof keytab/ sizeof keytab[0])

然后它说第二种方法的优点是,如果类型发生变化,则不需要更改它。有人可以告诉我最后一行的含义吗?这里谈论什么优势?

如果将来您将keytab数组更改为与struct key不同的类型,则必须更改第一个 sizeof 行,因为该类型是显式写入的。第二个 sizeof 行将继续工作,因为它不命名类型,但采用数组元素的任何类型。

对于 1) 代码需要假设我们正在查看类型为struct key的成员数组。
使用2)代码不需要知道这一点。

出于可维护性的原因,这被认为是 2) 的优点。
考虑几个人在项目上工作,一个人将数组的定义更改为

struct key2 {    
char * word;
int count;
int coolness;    
} keytab[] = /* ... */

并将struct key的定义与代码相同。另一个负责具有大小宏定义的代码部分。

然后1)变得错误,但2)保持正确。
因此,1)将需要两个开发人员之间的额外同步,这意味着额外的努力和错误的风险。

">有人能告诉我最后一行的含义吗?">

其实很简单。当您声明某物(任何内容)的数组时,每个元素都是该类型的sizeof。(例如int array[10] = {0};声明并初始化一个 10 元素的数组int) 数组的每个元素都有sizeof (int)个。

您可以使用array[x]访问每个元素(其中 x 是0-9)。任何元素,例如array[0]是一个int.(就像*array是对第一个元素的引用一样——其中array[0]只是在指针符号中*(array + 0),当然,指针表示法只是*(array)*array,因为括号是不必要的)。

回到struct数组的大小。sizeof keytab给出数组中的字节总数。sizeof keytab[0]给出每个元素中的字节数。因此sizeof keytab / sizeof keytab[0]数组中的元素数。它与写sizeof keytab / sizeof *keytabsizeof keytab / sizeof (struct key)相同。

为什么?因为sizeof keytab[0]只是sizeof (struct key).但是,如果您根据sizeof (struct key)调整元素数量,然后更改类型,则所有带有sizeof (struct key)的代码都将是错误的,但是如果您使用sizeof keytab[0]调整大小,则代码将继续计算正确的元素数,因为您基于sizeof "an element"而不是sizeof (an arbitrary type name)进行计算。

有人能告诉我最后一行的含义吗?

获取类型为struct key的数组元素的实际数量

这里谈论什么优势?

除了不明确依赖于某种类型的优点之外,

编译器可以使用实际定义对宏进行更多优化。 与sizeof(var)相比,sizeof(type)优化得更好。

最新更新