【问题标题】:How come does the size of arr[0] is of 8 bytes?为什么 arr[0] 的大小是 8 个字节?
【发布时间】:2017-01-03 01:36:52
【问题描述】:

我正在浏览寻找一种方法来查找给定矩阵的行数和列数,而无需任何其他信息,我找到了这个答案。

Given a matrix, find number of rows and columns

这是上述问题第二个答案中的代码 sn-p :

int main()
{
    float a[9][2]={{0,1},{1,1}};
    int row=(sizeof(a)/sizeof(a[0]));
    int col=(sizeof(a)/sizeof(a[0][0]))/row;
    printf("%d\n",row);
    printf("%d\n",col);
    return 0;
}

sizeof(a[0]) 怎么变成 8 了?据我了解,指针在 32 位拱形中的通用大小为 4 个字节,在 64 位拱形中具有 8 个字节。我在两台机器上都打印了 sizeof(a[0]) ,答案仍然是 8。 有人知道为什么吗?

已编辑:我的意思是说 a[0] 不会衰减为指针吗?

【问题讨论】:

  • 因为a[0]是矩阵的一行,包含2个浮点数,每个4字节。
  • "在我的理解中指针..." -- 你发布的代码中没有指针。
  • a[0] 是一个数组。数组和指针是不同的。该数组有 2 个元素,每个元素的大小为 4,因此总大小为 8。
  • 数组不是指针,指针也不是数组。
  • 仅仅因为一个数组在几乎所有地方都衰减为一个指针并不意味着它是一个。这只是语言工作方式的一部分。

标签: c++ c


【解决方案1】:

发布的代码中的任何地方都没有使用指针。当作为操作数传递给sizeof (1) 时,数组不会衰减到指向第一个元素的指针。

  • a 是一个二维数组,类型为 float [9][2]
  • a[0] 是这个二维数组中的第一项,它是一个float [2] 类型的一维数组。
  • sizeof(a) 给出二维数组的大小,相当于sizeof(float) * 9 * 2
  • sizeof(a[0]) 给出一维数组的大小,相当于sizeof(float) * 2
  • float 在您的系统上显然是 4 个字节,4 * 2 = 8。

(1) 参见 ISO 9899:2011 6.5.3.4 中 sizeof 运算符的规范:

当应用于具有数组类型的操作数时,结果是 数组中的总字节数。

“数组衰减”规则见6.3.2.1/3:

除非它是 sizeof 运算符的操作数,或一元 & 运算符,或者是用于初始化数组的字符串文字, 具有“类型数组”类型的表达式被转换为 类型为“pointer to type”的表达式,指向初始 数组对象的元素,不是左值。

【讨论】:

【解决方案2】:

但是 a[0] 是一个地址对吗?

不,a[0] 是一维数组。在几乎所有情况下,它都会衰减为指针。但是对于sizeof 操作,您将得到不同的答案。

由于 a[0] 是 2 个浮点数的一维数组,sizeof(a[0]) 给出 8。

【讨论】:

  • 谢谢你现在知道了:)
【解决方案3】:

a[0] 是一个包含 2 个浮点数的数组 (float[2])。因此,sizeof(a[0]) 等同于您的代码中的sizeof(float[2])。在您的平台上,sizeof(float) 是 4,因此 sizeof(a[0]) 是 8。

但是 float 的大小与计算 rowcolumn 的目的无关。无论sizeof(float) 是什么,您拥有的代码总是会给出正确的rowcolumn 值。

【讨论】:

    【解决方案4】:

    a 是一个二维数组。第一个维度是您拥有的总数组数,第二个数字是每个数组中的元素数。所以float a[9][2] 意味着你有 9 个数组彼此相邻(数组是连续的),每个数组有两个元素。

    现在,如果我们查看sizeof operator,我们会看到它被定义为

    当应用于数组时,结果是数组中的总字节数。这意味着包含 n 个元素的数组的大小是元素大小的 n 倍。

    对于数组。

    所以现在我们知道sizeof给出了数组的总大小,如果给定一个数组,我们知道a[n]代表a中的两个元素数组中的一个,那么sizeof(a[0])是总大小第一个数组(以及所有数组,因为数组不是锯齿状的)恰好是8,因为sizeof(float)4

    【讨论】:

    • 在 C 讨论中引用 C++ 标准时应该小心。 C 标准的全文如下:The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant. 现在,您不会在 C++ 中找到它,因为 C 具有 VLA,因此 sizeof 运算符的行为不同。
    • 这个答案中引用的部分也适用于 C,但请注意使 C 和 C++ 不同的所有肮脏细节。
    • @Lundin 我什至没有看到 Q 上的 C 标签。我只看到了 C++ 标签。相关部分仍然是这里最重要的部分。
    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 2023-03-03
    • 2016-09-25
    • 2020-07-10
    相关资源
    最近更新 更多