【问题标题】:In C, why is the sizeof function used as the denominator to store the number of elements in an array? [duplicate]在C语言中,为什么要用sizeof函数作为分母来存储数组的元素个数? [复制]
【发布时间】:2020-07-10 15:10:55
【问题描述】:

我不止一次看到数组索引 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 运算符返回的内容吗?如果不除以数组元素的大小,则不会得到数组的长度
  • 如果数组的元素大小 > 1,为什么建议不要除法?数组的元素显然少于或等于字节。
  • 常见于代码:#define COUNTOF(arr) ( sizeof(arr) / sizeof((arr)[0]) )
  • 不是很相关,但sizeof 是一个运算符(一个单一的),而不是一个函数。这种区别在某些情况下具有一些重要意义。
  • @EugeneSh。我想说sizeof() 是一个运算符而不是一个函数与这个问题有关。运算符可用于全局变量初始化,例如此问题中的 static const int n = ...。不能在那里调用可执行函数。

标签: arrays c sizeof divide


【解决方案1】:
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

【讨论】:

    【解决方案2】:

    这是因为数组的大小(以字节为单位)是一个元素的大小乘以元素的数量。请注意,sizeof 不适用于指向使用 malloc() 分配的堆变量的指针。

    【讨论】:

    • sizeof 不会确定仅给定元素指针的数组的大小。这个指针是来自malloc 还是其他地方无关紧要。此外,sizeof 是运算符,而不是函数,并且在应用于对象(而不是类型)时不需要括号。
    • 它非常适合指针。你只需要知道结果意味着什么。
    • @EricPostpischil "sizeof 不会确定仅给出指向元素的指针的数组的大小" 这就是我的意思,我不知道这不清楚。 “另外,sizeof 是一个运算符,而不是一个函数,并且在应用于对象(而不是类型)时不需要括号。”这里是题外话。 @klutt 取决于“作品”的定义。这就是你在这里欢迎新成员的方式吗?
    • sizeof 是一个运算符这一事实是相关的,因为这个答案将其称为sizeof(),给人一种误导性的印象,即括号是其中的一部分。不幸的是,这种流行的概念导致人们用不必要的括号将代码弄得乱七八糟。评论让您有机会改进答案。
    • @Eric,我一直使用括号,因为我不会费心去记住 sizeof(variableName) 或 sizeof(typeName) 是否需要它们。我确定有人需要它们,我只是湿器中没有多余的容量:-)
    【解决方案3】:

    为什么要这样做?这样做是为了在不进行其他更改的情况下对数组进行更改,从而减少因错误代码引入错误和/或彻底失败的机会。

    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 的任何这些定义。

    (有符号整数溢出的未定义行为可能更可能发生在其中一些定义中,但这在原始代码中也没有解决)

    【讨论】:

    • 您似乎错过了问题的重点。它不是问为什么使用表达式来计算数组大小。它在问为什么要按元素的大小来划分。
    • @EricPostpischil Forest, trees.
    猜你喜欢
    • 1970-01-01
    • 2021-06-06
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    相关资源
    最近更新 更多