我有一个函数可以对数组进行一些计算,但它必须知道数组的大小。如果我的函数只有数组本身,没有大小,我怎么能得到它?
是否可以在多维数组上做到这一点?
一种方法是使用模板:
template <size_t N>
void foo(int (&array)[N]) {
⋮
}
int main() {
int array[] = {5, 4, 3, 2, 1};
foo(array);
}
请注意,这只适用于调用者在编译时知道数组大小的情况。
您的问题标记为“C++”,所以第一条规则是:
数组是邪恶的!如果可能,不要使用数组。请改用std::vector
(或其他容器)。
void Foo(const std::vector<int>& v)
{
size_t size = v.size();
}
但是,如果你必须使用数组:
如果您的数组在堆栈上分配并作为数组变量传递:您可以使用模板技巧
template<typename T, size_t size>
size_t GetSize(T (&arr)[size])
{
return size;
}
但这是一个巨大的矫枉过正:如果你经常用不同的数组大小调用这样的函数,代码膨胀将是巨大的。
如果您的数组作为指针传递并且没有记录的“数组结束”标志:不可能
如果你的数组有“数组结束”标志:计算所有元素直到这个标志。以空结尾的 C 字符串就是很好的例子:
size_t strlen(const char *str)
{
size_t size = 0;
while(*str++)
++size;
return size;
}
“真的必须使用数组”,例如,如果您使用某种带有 C 接口的库。大多数此类库为您提供数组大小以及指向数组数据的指针,或者明确记录了有关如何查找此类数组结尾的约定(C 字符串除外。每个人都知道,它们以 结尾\0
)。这些方法中的任何一种都是不安全的。
顺便说一句,我是否已经提到数组是邪恶的?=)
在不更改现有函数的签名的情况下,唯一的解决方案是在您的数组中添加一个“哨兵”元素 - 例如,一个可能不属于您的数组合法部分的数字。扫描数组,直到你到达那个哨兵,然后计算元素。这会给你数组的长度。这种方法类似于 C 字符串通过添加空终止来确定长度的方法。
当然,在 C++ 中,你有一个比普通数组更好的选择: usingstd::vector<T>
可以避免传递长度,因为vector<T>
它有size()
函数。
如果它是一个像这样静态分配的普通 C 数组:
int a[5]
你可以找到长度
sizeof(a)/sizeof(a[0])
但是,仅当您在非常“a”变量的范围内使用 this 时才是正确的,并且长度基本上是在编译时计算的。
如果您想将数组传递给具有以下签名的函数:
void f (int *arr)
那么就无法在函数内部找到该长度,因为它需要指向 int 的通用指针(或数组)。
希望你也可以这样做,这在 C 中很常见。将数组的大小作为参数传递给函数。
例如,将向量与标量相乘
void scalar_mutliply ( double* vector, double scalar, unsigned size ) {
for ( unsigned i = 0; i < size; ++i ){
vector[i] *= scalar;
}
}
并对其进行测试:
using namespace std;
int main ( ) {
double vector [] = { 1, 2, 3, 4 ,5 };
scalar_mutliply( vector, 2, sizeof(vector)/sizeof(vector[0]) );
for (int i = 0; i < sizeof(vector)/ sizeof(vector[0]); ++i ){
cout << vector[i] << endl;
}
return 0;
}
这导致了这个输出:
2
4
6
8
10
考虑您可能能够将数组元素的数量存储在元素 0 中,并将其余元素存储在其他元素中的可能性。