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

时间:2010-05-01 09:38:58

标签: c++ function pointers sizeof

如果我写

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!

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

8 个答案:

答案 0 :(得分:5)

当传递给函数时,数组会衰减为指针,所以你得到的只是指针的大小。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

当将数组作为参数传递给带有指针的函数时,数组将作为指针衰减。

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);
}

当然,该功能必须模板化。

答案 4 :(得分:0)

没有。你错了。

如果我运行你的第二部分代码,它会在我的电脑上提供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

答案 5 :(得分:0)

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

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

第二次,你应该得到2,4或8(取决于架构),绝对不是400,因为你基本上输出了这个:

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

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

答案 6 :(得分:0)

指针是指针。这意味着,它只是指向记忆,这就是它的全部内容。创建指向数组的指针(通常表示指向数组的第一个元素的指针,但不一定)仍然只是指向某个内存位置的指针。由于内存地址只是一个内存地址,因此指针也无法知道它指向的内存最初是一个数组,还是该数组的长度。

这只是指针的工作方式。他们指向记忆,就是这样。

答案 7 :(得分:0)

该函数不知道示例中的数组大小,因为您采用显式步骤将数组转换为指针类型,从而完全剥离其原始数组性质的函数参数。再一次,您自己采取了有意识的步骤,以确保该函数不知道数组的大小。在这种情况下,看到你问一个关于为什么函数不知道数组大小的问题是很奇怪的。

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

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