如果我尝试使用函数在C++中显示数组的长度sizeof
,它会正确显示结果,在本例中为 8。
int main()
{
int array_enteros[]={'9','8','7','6','5','4','3','2'};
int longitud=sizeof(array_enteros)/sizeof(*array_enteros);
cout<<longitud<<endl;
return 0;
}
我不喜欢的是你必须输入array_enteros
两次单词才能知道长度,为此,最好通过一个函数来获得它。
int obtener_longitud_array(int* array_enteros)
{
return sizeof(array_enteros)/sizeof(*array_enteros);
}
int main()
{
int array_caracteres_enteros[]={'9','8','7','6','5','4','3','2'};
int longitud=obtener_longitud_array(array_caracteres_enteros);
cout<<longitud<<endl;
return 0;
}
在这种情况下,它返回 1,这是一个不同的值。
函数的参数会不会有问题?
问题。
您的函数的问题
obtener_longitud_array
是您在传递参数时丢失了大小信息array_enteros
(而且您只能计算整数数组的大小)。解释。
C++ 是一种强静态类型语言,这意味着您不能在
object
运行时更改类型,并且所有内容都有具体类型(没有像.net这样的通配符类型)。但有时 C++ 给人一种被动态类型化的感觉,因为存在隐式类型转换。根据C++ 标准(我的翻译和强调),这些隐式转换之一是数组到指针的转换:
安排
N
T
将是:哪里
T
是任何类型和任何N
值。未知的扩展修复
T
将是:where
T
可以是任何类型,并且是您在示例中使用的数组类型。将数组传递
array_enteros
给函数obtener_longitud_array
时,数组会经过上述转换(第 4.2 节)并丢失其原始类型。数组的原始类型包含大小。大小作为类型的一部分。
一个数组
N
T
或一个未知扩展数组T
包含大小作为其类型的一部分:这就是为什么可以使用函数重载来检测大小的原因:
所以你的函数
obtener_longitud_array
可以是一个模板,它可以像这样获取数组的大小:或者你可以将它推广到像 Dolmens 所做的非整数类型。但我不会重新发明轮子,而是使用标准库
std::extent
头实用程序:<type_traits>
问题是该函数没有接收数组,而是一个大小为 1 的指针,指针像数组一样工作,但它们不一样。
您可以使用宏来解决此问题
然后像使用函数一样使用 GetSize
由于您使用的是 C++,因此您可以使用C++ 的处理方式:使用
template
.1. C++11
constexpr
,:它编译没有问题
2. C++98,没有
constexpr
:唯一改变的就是删除了那个关键字。
它编译没有问题
测试代码:
适用于 C++98 及更高版本:
输出是:
如您所见,它区分了fix和non- fixes。在第一种情况下,它返回元素的数量(无论是在声明变量时指定还是省略)。在第二个中,它返回.
0
为什么是2个版本?
第一个
template
不是绝对必要的。如果您在不是 数组的变量上使用它,这是为了避免错误。它利用了该语言的SFINAE特性:当尝试实例化模板并且参数不匹配时,它不会引发错误,而是继续寻找匹配的其他template
版本。在我们的测试代码中,如果我们省略了模板的第一个版本
我的 g++吐出以下内容:
但是,对于这两个版本,编译器都会尝试两者,并且根据情况,它会在其中一个或另一个上成功。这些尝试使我们能够区分普通变量和数组。
另一种方法是使用 C++11 和
template std::remove_all_extents< T >
:就我而言,这是一个非常免费的翻译,它说:
T
它是形式tipo[]...
(具有任意数量的维度, obtenemos el tipo base
T`.T
不是形式tipo[]...
,我们仍然得到类型T
。这可用于获取任何变量的大小,无论它是否为数组:如果是,我们可以获取其基本类型的大小;如果不是,我们仍然得到基本类型的大小。因此,无论如何,我们将变量的大小除以从获得的大小就足够
typedef type
了template
:显示以下内容: