C语言 获取数组的大小常见问题

C语言中,获取数组的大小时,特别是在只有指向数组首元素的指针的情况下。这个问题的核心在于,数组和指针在C语言中有着不同的处理方式,尤其是在计算大小时。数组和指针之间存在密切的关系,但它们并不相同。当拥有一个数组时,可以使用 sizeof 操作符来获取数组的大小,但如果只拥有一个指向数组首元素的指针,则无法通过 sizeof 来获取数组的大小。

1、使用 sizeof 获取数组大小

如直接操作数组,则可以通过 sizeof 操作符获取数组的大小,如下,

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    size_t size = sizeof(arr) / sizeof(arr[0]);
    printf("Array size: %zu\n", size);  // 输出 5

    return 0;
}

2、指针无法通过 sizeof 获取数组大小

如果将数组传递给一个函数时,数组会衰退(decay)为指向其第一个元素的指针。此时,sizeof 操作符仅能返回指针本身的大小,而不是数组的大小。

#include <stdio.h>

void printSize(int *ptr) {
    size_t size = sizeof(ptr) / sizeof(ptr[0]);
    printf("Pointer size: %zu\n", size);  // 输出 1 或其他不期望的结果
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    printSize(arr);

    return 0;
}

3、传递数组的大小

由于指针无法知道数组的大小,通常的做法是显式地传递数组的大小作为参数。

#include <stdio.h>

void printSize(int *ptr, size_t size) {
    printf("Array size: %zu\n", size);
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    size_t size = sizeof(arr) / sizeof(arr[0]);  // 在调用前计算数组大小
    printSize(arr, size);

    return 0;
}

4、使用动态数组时

如果数组是动态分配的(例如使用 malloc()),就不能使用 sizeof 来获取数组的大小,因为在这种情况下,数组的大小信息不会存储在指针中。

#include <stdio.h>
#include <stdlib.h>

void printSize(int *ptr, size_t size) {
    printf("Dynamic array size: %zu\n", size);
}

int main() {
    size_t n = 5;
    int *arr = (int *)malloc(n * sizeof(int));  // 动态分配数组
    if (arr == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }

    printSize(arr, n);  // 必须显式传递数组的大小

    free(arr);  // 释放动态分配的内存
    return 0;
}

5、获取数组大小的使用示例

获取数组的大小常常会遇到一些问题,尤其是涉及到指针和数组传递时。获取静态数组、数组传递、动态数组、以及使用结构体传递数组大小的情况的使用示例。

#include <stdio.h>
#include <stdlib.h>

// 定义一个结构体用于保存数组和大小信息
typedef struct {
    int *array;
    size_t size;
} ArrayInfo;

// 打印数组信息的函数
void printArrayInfo(ArrayInfo arrInfo) {
    printf("数组的元素数量: %zu\n", arrInfo.size);
    for (size_t i = 0; i < arrInfo.size; ++i) {
        printf("%d ", arrInfo.array[i]);
    }
    printf("\n");
}

// 示例:传递数组到函数并查看sizeof行为
void printArraySize(int arr[]) {
    printf("在函数内部 sizeof(arr) = %zu (这是一个指针的大小)\n", sizeof(arr));
}

int main() {
    // 1、静态数组
    int staticArr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    size_t staticArrSize = sizeof(staticArr) / sizeof(staticArr[0]);
    printf("在主函数中 sizeof(staticArr) = %zu\n", sizeof(staticArr));
    printf("静态数组元素数量: %zu\n", staticArrSize);

    // 调用函数传递数组
    printArraySize(staticArr);

    // 使用结构体传递静态数组信息
    ArrayInfo staticArrInfo = {staticArr, staticArrSize};
    printArrayInfo(staticArrInfo);

    // 2、动态分配的数组
    size_t dynamicArrSize = 5;
    int *dynamicArr = malloc(dynamicArrSize * sizeof(int));
    if (dynamicArr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }

    // 初始化动态数组
    for (size_t i = 0; i < dynamicArrSize; ++i) {
        dynamicArr[i] = (int)(i * 2);
    }

    // sizeof(dynamicArr) 只能返回指针的大小
    printf("sizeof(dynamicArr) = %zu (这是一个指针的大小)\n", sizeof(dynamicArr));

    // 使用结构体传递动态数组信息
    ArrayInfo dynamicArrInfo = {dynamicArr, dynamicArrSize};
    printArrayInfo(dynamicArrInfo);

    // 释放动态分配的内存
    free(dynamicArr);

    return 0;
}

推荐阅读
cjavapy编程之路首页