c ++中的静态数组会忘记它的大小

时间:2010-05-01 01:02:15

标签: c++

在这个小例子中,c ++忘记了数组的大小,传递给构造函数。我想这很简单,但我看不到它。

在classes.h中,有以下代码:

#ifndef CLASSES_INC
#define CLASSES_INC
#include <iostream>

class static_class {
 public:
 static_class(int array[]) {
  std::cout<<sizeof(array)/sizeof(int)<<"\n";
 } 
};

class my_class{
 public:
 static static_class s;
 static int array[4];
};

#endif

在classes.cpp中,有以下代码:

#include "classes.h"

int my_class::array[4]={1, 2, 3, 4}; 

static_class my_class::s = static_class(my_class::array);

在main.cpp中,只有简单的

#include "classes.h"

int main () {

 return 0;
}

现在,所需的输出(来自static_class的构造函数)是4.但我得到的是1.为什么会这样?

<击>编辑:

<击>

许多答案表明指针上的sizeof返回指针的大小。事实并非如此,AFAIK(来自http://msdn.microsoft.com/en-us/library/4s7x1k91(VS.71).aspx - “当sizeof运算符应用于数组时,它会产生该数组中的总字节数,而不是数组标识符所表示的指针的大小。”)

EDIT2:

好吧,正如我发现的那样,当编译器可以看到大小时,sizeof会返回整个大小,但是当它衰减到一个指针(这就是这里的情况)时,sizeof实际上实际上返回了指针的大小。

6 个答案:

答案 0 :(得分:11)

声明函数参数时,以下两个是等效的,因为当数组作为参数传递时,数组会衰减为指针:

int array[]
int *array;

所以,你最终计算sizeof(int*) / sizeof(int),这恰好是你平台上的一个,因为它们的大小是相同的。

如果你需要函数中数组的大小,你应该将它作为参数传递给函数,或者使用一个容器来跟踪你的大小。

答案 1 :(得分:3)

还有一个模板选项,就像这样?

class static_class
{
public:
   template<int I>
   static_class(int (&array)[I])
   {
      std::cout << I << std::endl;
   } 
};

我认为无论如何都会有用。 sizeof(array)/sizeof(array[0])仅适用于数组定义实际可见的范围。换句话说,你的static_class构造函数无法“看到”数组的大小,它只知道它获得了一些(任何)大小的数组。你可以传递一个包含100个元素或4个元素的数组,函数本身就不会得到任何信息。

在我的示例中,另一方面,模板将导致为您传入的每个数组大小创建一个版本的函数。这可能是也可能不是。一般来说,最好将数组大小放在某处,比如:

class my_class
{
public:
   static static_class s;
   static const int array_size = 4;
   static int array[array_size];
};

然后你可以传递my_class :: array_size,而不必担心编译器可能会或可能没有关于数组属性的信息。

答案 2 :(得分:1)

在C中,因此我假设在C ++中,任何作为参数传递的数组都会变成一个简单的指针类型,它会丢失大小信息。由于static_class构造函数从参数获取数组,因此会丢失其数组质量。

答案 3 :(得分:0)

另一个答案暗示的基本问题是数组不是C / C ++中的第一类类型。特别是,您不能声明将数组作为参数的函数或函数类型。现在,由于历史原因在时间的深处丢失,而不是仅仅声明声明一个数组的函数参数是一个错误,因此决定编译器应该静默地将数组声明转换为指针声明。这导致人们将数组声明为参数并意外地获取指针而导致混淆。

答案 4 :(得分:-1)

因为数组是指向sizeof(数组)的点的指针。数组永远不知道它的大小(看看如果你试图访问超出其结尾的元素会发生什么)。编译器在定义时知道了;那一切

无论如何,你想要的解决方案是std :: vector

答案 5 :(得分:-3)

你会感到惊讶,但在C ++中,数组只是指针,仅此而已。数组大小不存储在任何地方,当然也不可能传递可变大小的函数参数。