为什么 sizeof(array) 返回的值是数组中索引的三倍?

Edu*_*nho 4 c++ arrays for-loop sizeof

我想在 for 循环中打印一个数组,但数组不仅打印随机数,而且还打印比数组边界多 3 倍的数字,这很奇怪,因为我使用的是 sizeof(A) 所以它只打印直到它的界限。你们知道为什么它打印的次数比代码中指定的次数多吗?

我尝试的代码如下:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
        int A[] = {1, 2, 4, 8, 16, 32, 64, 128};
        for (int i = 0; i < sizeof(A); i++) {
                cout << A[i] << endl;
        }
}

Run Code Online (Sandbox Code Playgroud)

输出如下:

1 2 4 8 16 32 64 128 14294328 0 14294384 11 14294320 0 794104558 32759 0 0 62 0 794128456 32759 0 0 0 0 0 0 0 0 0 0

正如您所看到的,当打印量应该仅为数组大小时,有 32 个输出。

我希望代码的输出是: 1 2 4 8 16 32 64 128

Vla*_*cow 8

sizeof带有运算符的表达式sizeof(A)生成数组的大小(以字节为单位)A。获得的值等于数组中元素的数量乘以数组元素的大小,即

sizeof( A ) = 8 * sizeof( int )
Run Code Online (Sandbox Code Playgroud)

因此,如果您有数组大小并且知道数组元素的类型,您可以获得数组中元素的数量,例如

size_t n = sizeof( A ) / sizeof( A[0] )
Run Code Online (Sandbox Code Playgroud)

这意味着你的 for 循环应该重写为

for ( size_t i = 0, n = sizeof( A ) / sizeof( A[0] ); i < n; i++ ) {
//...
Run Code Online (Sandbox Code Playgroud)

来自 C++17 标准(8.3.3 Sizeof)

1 sizeof 运算符生成其操作数的对象表示形式中的字节数。操作数可以是一个表达式,即一个未计算的操作数(第 8 条),也可以是一个带括号的类型 ID。sizeof 运算符不得应用于具有函数或不完整类型的表达式、此类类型的括号名称或指定位字段的泛左值。sizeof(char)、sizeof(signed char) 和 sizeof(unsigned char) 均为 1。应用于任何其他基本类型 (6.9.1) 的 sizeof 的结果是实现定义的。[ 注意:特别是,sizeof(bool)、sizeof(char16_t)、sizeof(char32_t) 和 sizeof(wchar_t) 是实现定义的。

注意std::size()头文件中声明了标准的C++函数<iterator>,可以用来代替带有sizeof运算符的表达式

#include <iterator>

//...

for ( size_t i = 0, n = std::size( A ); i < n; i++ ) {
//...
Run Code Online (Sandbox Code Playgroud)

但在引入标准 C++ 函数 std::size 之前,使用了header 中声明的结构体value的数据成员。std::extent<type_traits>

另一种方法是使用基于范围的 for 循环,例如

for ( const auto &item : A ) {
        cout << item << endl;
}
Run Code Online (Sandbox Code Playgroud)

您还可以在 for 循环中使用迭代器或标准算法,例如std::copystd::for_each

这是一个演示程序,展示了输出数组的可能方法

#include <iostream>
#include <type_traits>
#include <iterator>
#include <algorithm>

int main()
{
    int A[] = { 1, 2, 4, 8, 16, 32, 64, 128 };

    //  using the sizeof operator
    for (size_t i = 0, n = sizeof( A ) / sizeof( A[0] ); i < n; i++)
    {
        std::cout << A[i] << ' ';
    }
    std::cout << '\n';

    //  using function std::size()
    for (size_t i = 0, n = std::size( A ); i < n; i++)
    {
        std::cout << A[i] << ' ';
    }
    std::cout << '\n';

    //  using std::extent_v
    for (size_t i = 0, n = std::extent_v<decltype( A )>; i < n; i++)
    {
        std::cout << A[i] << ' ';
    }
    std::cout << '\n';

    //  using range-based for loop
    for ( const auto &item : A )
    {
        std::cout << item << ' ';
    }
    std::cout << '\n';

    //  using for loop with iterators
    for (auto first = std::begin( A ), last = std::end( A ); first != last; ++first)
    {
        std::cout << *first << ' ';
    }
    std::cout << '\n';

    //  using algorithm std::copy
    std::copy( std::begin( A ), std::end( A ),
        std::ostream_iterator<int>( std::cout, " "));
    std::cout << '\n';

    //  using algorithm std::for_each
    std::for_each( std::begin( A ), std::end( A ),
        []( const auto &item )
        {
            std::cout << item << ' ';
        } );
    std::cout << '\n';

}
Run Code Online (Sandbox Code Playgroud)

程序输出是

1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
1 2 4 8 16 32 64 128 
Run Code Online (Sandbox Code Playgroud)


Viv*_*ick 7

在 C++ 中,与 C 一样,sizeof(x)给出了 的大小(以字节为单位x。对于数组,您可以使用通常的技巧sizeof(x)/sizeof(x[0])来获取元素的数量

您可以将其视为总大小(以字节为单位)除以一个元素的大小(以字节为单位)。

请注意,当数组作为参数传递给函数时,此技巧将不起作用,因为 C 样式数组会衰减为指针(即函数不会具有数组大小的信息)。

话虽这么说,std::array通常更好地用作常规 C 样式数组的抽象,特别是由于与标准算法(例如 )的兼容性,std::for_each而且还适用于循环的范围:

#include <iostream>
#include <array>

int main()
{
    std::array<int, 8> A;

    for (int item : A) {
        std::cout << item << endl;
    }
}
Run Code Online (Sandbox Code Playgroud)