【问题标题】:Why function does not know the array size?为什么函数不知道数组大小?
【发布时间】:2011-02-14 12:30:03
【问题描述】:

如果我写

int main()
{
    int a[100] = {1,2,3,4,};
    cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array, 
                                        //isn't it
    return 0;
}

我得到 400!

如果我写

void func(int *a);

int main()
{
    int a[100] = {1,2,3,4,};
    func(a);
    return 0;
}

void func(int *a)
{
     cout<<sizeof(a)/sizeof(a[0])<<endl; //a is a pointer to the first elem of array
}

那么我得到 1!

那么为什么函数不知道数组大小呢?

【问题讨论】:

标签: c++ function pointers sizeof


【解决方案1】:

函数不知道示例中的数组大小,因为您采取了明确的步骤将数组转换为指针类型,从而完全剥离了函数参数的原始数组性质。再一次,您自己采取了慎重的步骤来确保该函数不知道数组的大小。在这种情况下,看到你问为什么函数不知道数组大小的问题是相当奇怪的。

如果你用什么函数接收它的参数作为一个数组,你必须将它作为一个数组传递,而不是仅仅作为一个指针,并声明相应的函数相应的参数。 C++ 中的数组不能“按值”传递,这意味着您必须“通过引用”传递它,这是一种可能性

void func(int (&a)[100])
{
  cout << sizeof a / sizeof a[0] << endl;
}

【讨论】:

    【解决方案2】:

    将数组作为参数传递给采用指针的函数时,数组会衰减为指针。

    void bar(int *a)
    {
        std::cout << sizeof(a) << std::endl; // outputs "4" (on a 32 bit compiler)
    }
    
    void foo()
    {
        int a[100] ;
        std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
        bar(a);
    }
    

    所以也许解决方案是提供一个正确的函数,将数组的引用作为参数:

    template <size_t T_Size>
    void bar(int (&a)[T_Size])
    {
        std::cout << T_Size << std::endl;    // outputs "100" (on ALL compilers)
        std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
    }
    
    void foo()
    {
        int a[100] ;
        std::cout << sizeof(a) << std::endl; // outputs "400" (on a 32 bit compiler)
        bar(a);
    }
    

    当然,函数必须模板化。

    【讨论】:

      【解决方案3】:

      这不起作用,因为 sizeof 是在编译时计算的。该函数没有关于其参数大小的信息(它只知道它指向一个内存地址)。

      考虑改用 STL 向量,或将数组大小作为参数传递给函数。

      Marcel Guzman 在Calculating size of an array! 中回答了这个问题!

      【讨论】:

        【解决方案4】:

        指针是指针。这意味着,它只是指向内存,仅此而已。创建指向数组的指针(通常意味着指向数组第一个元素的指针,但不一定)仍然只是指向某个内存位置的指针。由于内存地址只是一个内存地址,因此指针也无法知道它最初指向的内存是一个数组,或者该数组有多长。

        这就是指针的工作原理。它们指向记忆,仅此而已。

        【讨论】:

          【解决方案5】:

          sizeof 返回类型的大小。在第二个示例中,func( int *a ),a 是一个指针,sizeof 将这样报告它。即使你做了func( int a[100] ),a 也是一个指针。如果你想要 func 中数组的大小,你必须将它作为一个额外的参数传递。

          【讨论】:

            【解决方案6】:

            您第一次得到 400,因为您只将 sizeof(a),而不是 sizeof(a)/sizeof(a[0]) 传递给 cout。您需要将该计算用括号括起来以获得正确的输出值,即:

            cout << (sizeof(a)/sizeof(a[0])) << endl;
            

            第二次,你应该得到 2、4 或 8(取决于架构),肯定不是 400,因为你实际上是在输出这个:

            cout << sizeof(int*) << endl;
            

            通用指针的大小始终是固定值。

            【讨论】:

              【解决方案7】:

              没有。你错了。

              如果我运行您的第二部分代码,它会在我的计算机上给出 1。不是 400。

              #include <iostream>
              
              void func(int *a);
              
              using namespace std;
              
              int main()
              {
                  int a[100] = {1,2,3,4,};
                  func(a);
                  return 0;
              }
              
              void func(int *a)
              {
                   cout<<sizeof(a)/sizeof(a[0])<<endl;
              }
              

              生产

              1
              

              【讨论】:

              • 在原帖中他说他得到了 400。
              【解决方案8】:

              数组在传递给函数时会衰减为指针,因此您将得到的只是指针的大小。

              【讨论】:

              • 数组只在传递格式请求它们衰减时衰减为指针,即如果相应的参数被声明为指针(如本例所示)。如果参数被声明为对数组的引用,则不会发生衰减。
              • @AndreyT:谁说过参考资料?如果您的函数是void func(int a[]),那么a 仍将衰减为指针。
              猜你喜欢
              • 2022-11-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-20
              • 1970-01-01
              相关资源
              最近更新 更多