C语言中为什么要用sizeof函数作为分母来存储数组的元素个数?
In C, why is the sizeof function used as the denominator to store the number of elements in an array?
我不止一次看到在存储数组元素数时,数组索引 0 上使用的 sizeof 运算符充当分母。我的问题是为什么使用 sizeof 运算符而不是仅除以 1 或根本不除?
请参阅下面来自 https://www.bravegnu.org/gnu-eprog/c-startup.html 的一些示例代码中的这种现象的示例。
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]); //RIGHT HERE!!!!!
int main()
{
int i;
for (i = 0; i < n; i++)
sum += arr[i];
}
这是因为数组的大小(以字节为单位)是一个元素的大小乘以元素的数量。请注意 sizeof
不适用于指向使用 malloc()
.
分配的堆变量的指针
static int arr[] = { 1, 10, 4, 5, 6, 7 };
数组arr
是一堆整数,准确地说是六个。每个整数占用一定数量的字节(为了这个答案的目的,我们假设四个 - 在某些系统上它可能更多或更少)。
所以,sizeof(arr)
是 24 个字节,六个整数乘以每个四个字节。
如果您想知道数组中有多少 个元素(而不是字节),请将整个数组的大小除以单个成员的大小,其中之一:
static const int n = sizeof(arr) / sizeof(arr[0]);
static const int n = sizeof(arr) / sizeof(*arr);
// sizeof(arr) / sizeof(arr[0]) == 24 / 4 == 6 elements
为什么要这样做?这样做是为了在不进行其他更改的情况下对数组进行更改,从而减少引入错误的机会 and/or 因不正确的代码而彻底失败。
TLDR 答案:
这个构造自动计算数组的元素,因此它不依赖于人输入的数字——数字可能是错误的...
完整答案
如果代码是
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
int main()
{
int i;
for (i = 0; i < 6; i++)
sum += arr[i];
}
相反,如果通过删除一个元素来更改数组
static int arr[] = { 1, 10, 4, 5, 6 };
密码会被破坏。
这个代码
static const int n = sizeof(arr) / sizeof(arr[0]);
将适用于 arr
的所有以下定义:
static int arr[] = { 1, 10, 4, 5, 6, 7 };
或
unsigned long long arr[ NUM_ELEMENTS ];
或
static float arr[] = { 12.4, 54.2 };
您的原始代码
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]); //RIGHT HERE!!!!!
int main()
{
int i;
for (i = 0; i < n; i++)
sum += arr[i];
}
将(大部分)与 arr
.
的任何定义一起使用
(对于其中一些定义,有符号整数溢出的未定义行为更有可能发生,但这也未在原始代码中解决)
我不止一次看到在存储数组元素数时,数组索引 0 上使用的 sizeof 运算符充当分母。我的问题是为什么使用 sizeof 运算符而不是仅除以 1 或根本不除?
请参阅下面来自 https://www.bravegnu.org/gnu-eprog/c-startup.html 的一些示例代码中的这种现象的示例。
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]); //RIGHT HERE!!!!!
int main()
{
int i;
for (i = 0; i < n; i++)
sum += arr[i];
}
这是因为数组的大小(以字节为单位)是一个元素的大小乘以元素的数量。请注意 sizeof
不适用于指向使用 malloc()
.
static int arr[] = { 1, 10, 4, 5, 6, 7 };
数组arr
是一堆整数,准确地说是六个。每个整数占用一定数量的字节(为了这个答案的目的,我们假设四个 - 在某些系统上它可能更多或更少)。
所以,sizeof(arr)
是 24 个字节,六个整数乘以每个四个字节。
如果您想知道数组中有多少 个元素(而不是字节),请将整个数组的大小除以单个成员的大小,其中之一:
static const int n = sizeof(arr) / sizeof(arr[0]);
static const int n = sizeof(arr) / sizeof(*arr);
// sizeof(arr) / sizeof(arr[0]) == 24 / 4 == 6 elements
为什么要这样做?这样做是为了在不进行其他更改的情况下对数组进行更改,从而减少引入错误的机会 and/or 因不正确的代码而彻底失败。
TLDR 答案:
这个构造自动计算数组的元素,因此它不依赖于人输入的数字——数字可能是错误的...
完整答案
如果代码是
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
int main()
{
int i;
for (i = 0; i < 6; i++)
sum += arr[i];
}
相反,如果通过删除一个元素来更改数组
static int arr[] = { 1, 10, 4, 5, 6 };
密码会被破坏。
这个代码
static const int n = sizeof(arr) / sizeof(arr[0]);
将适用于 arr
的所有以下定义:
static int arr[] = { 1, 10, 4, 5, 6, 7 };
或
unsigned long long arr[ NUM_ELEMENTS ];
或
static float arr[] = { 12.4, 54.2 };
您的原始代码
static int arr[] = { 1, 10, 4, 5, 6, 7 };
static int sum;
static const int n = sizeof(arr) / sizeof(arr[0]); //RIGHT HERE!!!!!
int main()
{
int i;
for (i = 0; i < n; i++)
sum += arr[i];
}
将(大部分)与 arr
.
(对于其中一些定义,有符号整数溢出的未定义行为更有可能发生,但这也未在原始代码中解决)