📜  不要将sizeof用于数组参数(1)

📅  最后修改于: 2023-12-03 15:35:55.463000             🧑  作者: Mango

不要将sizeof用于数组参数

当你在函数中使用数组作为参数时,你可能会想知道数组的长度。一种尝试获取数组长度的方式是使用sizeof操作符。比如:

void foo(int arr[]) {
    size_t len = sizeof(arr) / sizeof(arr[0]);
    // ...
}

然而,这样做是错误的,因为arr在函数中只是一个指针,而不是一个数组。

数组作为参数

在函数参数中声明一个数组是非常常见的。C语言中的函数参数是按值传递的,这意味着当你将一个数组作为参数传递给函数时,实际上是将数组的首元素的地址传递给函数。

例如,给定以下函数:

void foo(int arr[]) {
    // ...
}

你可以通过下面的代码来调用它:

int main() {
    int arr[10];
    foo(arr);
    // ...
}

foo函数中的arr实际上只是一个指向arr数组首元素的指针。这个指针的大小是固定的,通常为4或8个字节,不会随着数组的大小而改变。

sizeof操作符

sizeof是一个操作符,用于获取对象的大小(以字节为单位)。在C语言中,你可以使用sizeof来获取一个类型、变量或表达式的大小。

例如,以下代码将打印一个int类型的大小:

printf("%zu", sizeof(int)); // 将打印4(假设int占4个字节)

sizeof可以在编译时计算对象的大小,这意味着它可以用来分配内存或在数组长度是常数时计算数组的长度。

然而,在传递数组参数时,你需要注意到sizeof并不会给你期望的数组大小。

正确的方法

如果你需要在函数中获取数组的长度,有几种方法可以实现。

首先,你可以将数组的大小作为函数参数传递:

void foo(int arr[], size_t len) {
    // ...
}

int main() {
    int arr[10];
    foo(arr, 10);
    // ...
}

这种方法可以确保你得到了正确的数组长度,但需要调用函数时提供一个额外的参数。

第二种方法是使用C99引入的变长数组:

void foo(size_t len, int arr[len]) {
    // ...
}

int main() {
    int arr[10];
    foo(10, arr);
    // ...
}

注意,这种方法也需要提供数组长度作为参数。

第三种方法是使用宏定义计算数组长度:

#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

void foo(int arr[]) {
    size_t len = ARRAY_SIZE(arr);
    // ...
}

int main() {
    int arr[10];
    foo(arr);
    // ...
}

这种方法可以在不需要额外参数的情况下获取数组大小,但需要你在每个数组调用处显式调用宏。

总结

不要将sizeof用于数组参数,因为数组参数在函数中变为指针,无法得到正确的数组大小。相反,你可以将数组长度作为函数参数传递,使用变长数组,或使用宏定义计算数组大小。