如何确定C中数组的大小?

时间:2020-03-05 18:45:51  来源:igfitidea点击:

如何确定C中数组的大小?

也就是说,数组可以容纳多少个元素?

解决方案

回答

执行摘要:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

要确定数组的大小(以字节为单位),可以使用sizeof
操作员:

int a[17];
size_t n = sizeof(a);

在我的计算机上,整数是4个字节长,所以n是68.

为了确定数组中元素的数量,我们可以除以
数组的总大小乘以数组元素的大小。
我们可以使用以下类型进行此操作:

int a[17];
size_t n = sizeof(a) / sizeof(int);

并得到正确的答案(68/4 = 17),但是如果
a更改后,如果我们忘记更改,将会遇到一个讨厌的错误
同样是sizeof(int)

因此首选除数是sizeof(a [0]),即
数组的zeroeth元素。

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

另一个优点是我们现在可以轻松地进行参数设置
宏中的数组名称并获取:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

回答

sizeof(array) / sizeof(array[0])

回答

值得注意的是,sizeof在处理已衰减为指针的数组值时无济于事:即使它指向数组的开始,但指向编译器,它与指向单个元素的指针相同该阵列的。指针不会"记住"用于初始化数组的其他任何信息。

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

回答

@ Magnus:该标准将sizeof定义为产生对象中的字节数,并且sizeof(char)始终为1. 字节中的位数是特定于实现的。

编辑:ANSI C ++标准第5.3.3节

The sizeof operator yields the number of bytes in the object representation  of its operand. [...] sizeof (char), sizeof (signed char) and sizeof (unsigned char) are 1; the result of sizeof applied to any other fundamental type is implementation-defined.

第1.6节C ++内存模型:

The fundamental storage unit in the C++ memory model is the  byte. A byte is at least large enough to contain any member of the basic execution character set and is composed of a contiguous sequence of bits, the  number of which is implementation-defined.

回答

@Skizz: I am pretty sure I am right, although the best "source" I can give you at the moment is Wikipedia, from the article on sizeof:

维基百科是错误的,斯基茨是正确的。根据定义,sizeof(char)为1.

我的意思是,请仔细阅读Wikipedia条目以确认它是错误的。 "字符的倍数"。 sizeof(char)不能是" 1"以外的任何东西。如果是2,就意味着sizeof(char)是char大小的两倍!

回答

sizeof是我所知的最好方法,在括号的使用上有一个很小但是(对我来说,这是一个主要的挑战)。

正如Wikipedia条目所表明的那样,C的`sizeof'不是函数。它是一个运算符。因此,除非参数是类型名称,否则不需要在参数周围加上括号。这很容易记住,因为它使参数看起来像强制转换表达式,该表达式也使用括号。

因此:如果我们具有以下条件:

int myArray[10];

我们可以使用以下代码找到元素数量:

size_t n = sizeof myArray / sizeof *myArray;

对我来说,这比带有括号的替代方法要容易得多。我也赞成在该部门的右侧使用星号,因为它比索引更简洁。

当然,这也都是编译时,因此无需担心划分会影响程序的性能。因此,请尽可能使用此表格。

最好在有一个实际对象时在一个对象上使用sizeof,而不是在一个类型上使用,因为这样一来,我们就不必担心会出错并指出错误的类型。

例如,假设我们有一个函数,例如通过网络将某些数据作为字节流输出。让我们调用函数" send()",并使其以指向要发送的对象的指针以及对象中的字节数作为参数。因此,原型变为:

void send(const void *object, size_t size);

然后,我们需要发送一个整数,因此我们将其编码如下:

int foo = 4711;
send(&foo, sizeof (int));

现在,我们通过在两个位置指定" foo"的类型,介绍了一种微妙的脚部射击方法。如果一个更改但另一个没有更改,则代码将中断。因此,请始终这样做:

send(&foo, sizeof foo);

现在我们已受到保护。当然,我们可以重复变量的名称,但是如果我们更改它,则很有可能以编译器可以检测的方式破坏该变量。