C语言中,由于数组在传递到函数时会退化为指针,因此函数中无法通过 sizeof 获取数组的实际大小。解决方案是通过额外参数显式传递数组大小。在 C++ 中,模板和现代工具(如 std::size)提供了更优雅的解决方案,从而避免手动计算数组大小的麻烦。

1、sizeof 在传递数组时不返回实际大小的原因

C语言中,当数组被传递到函数时,它会退化为一个指向数组第一个元素的指针。也就是函数接收到的并不是数组本身,而是一个指向数组第一个元素的指针。

#include <stdio.h>

void printSize(int arr[]) {
    printf("Inside function, sizeof(arr): %zu\n", sizeof(arr));
}

int main() {
    int arr[10];
    printf("In main, sizeof(arr): %zu\n", sizeof(arr));
    printSize(arr);
    return 0;
}

2、数组退化

当将一个数组传递给函数时,它会退化为一个指向数组第一个元素的指针,在 main 中,int arr[10] 是一个数组。在 printSize 中,int arr[] 被解释为 int *,因此 sizeof(arr) 计算的是指针的大小,而不是数组的大小。

#include <stdio.h>

void printArraySize(int arr[]) {
    // 数组退化为指针,此时 sizeof(arr) 是指针的大小
    printf("In function, sizeof(arr): %zu\n", sizeof(arr));
}

void printArraySizeUsingPointer(int *arr) {
    // 同样的,使用指针作为参数也是指针的大小
    printf("In function, sizeof(arr): %zu\n", sizeof(arr));
}

int main() {
    int array[10]; // 定义一个数组
    printf("In main, sizeof(array): %zu\n", sizeof(array)); // 输出整个数组的大小

    printArraySize(array); // 传递数组到函数
    printArraySizeUsingPointer(array);

    return 0;
}

3、获取实际的数组大小的方法

如需要在函数中获取数组的实际大小,必须通过额外的参数将数组的大小显式传递给函数。

#include <stdio.h>

void printSize(int arr[], size_t size) {
    printf("Array size is: %zu\n", size);
}

int main() {
    int arr[10];
    printSize(arr, sizeof(arr) / sizeof(arr[0]));  // 显式传递数组大小
    return 0;
}

4、在 C++17 及更高版本中使用 std::size

在现代 C++(C++17 及之后),可以使用 头文件中的 std::size 来获取数组的大小,从而避免手动计算。

#include <iostream>
#include <iterator>
using namespace std;

void printSize(int arr[], size_t size) {
    cout << "Array size is: " << size << endl;
}

int main() {
    int arr[10];
    printSize(arr, size(arr));  // 使用 size 获取数组大小
    return 0;
}

5、使用模板自动推导数组大小(C++ 特性)

C++ 中,可以使用模板来推导数组的大小,而无需显式传递数组大小。这种方法只适用于真正的数组,而不适用于退化后的指针。

#include<iostream>
using namespace std;

template <typename T, size_t N>
void printSize(T (&arr)[N]) {  // 使用引用传递数组,保留数组大小信息
    cout << "Array size is: " << N << endl;
}

int main() {
    int arr[10];
    printSize(arr);  // 无需显式传递数组大小
    return 0;
}

推荐文档

相关文档

大家感兴趣的内容

随机列表