在这个小例子中,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实际上实际上返回了指针的大小。
答案 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 ++中,数组只是指针,仅此而已。数组大小不存储在任何地方,当然也不可能传递可变大小的函数参数。