2. 指针类型与大小

任务目标

编写一个C程序,打印 char*、int*、double*、void* 以及函数指针的大小(字节数),并验证:在同一平台上,所有数据指针的大小相同,且指针大小与指向的数据类型无关。

核心知识点

指针变量存储的是内存地址。在同一个操作系统和编译器环境下,所有数据指针(无论指向 char、int 还是 double)的地址宽度相同,因此 sizeof(指针) 结果一致。指针的“类型”决定的是解引用时如何解释目标内存(例如 int* 按4字节读取),而不影响指针自身占用的字节数。

完整代码

#include <stdio.h>

int main(void) {
    // 数据指针
    char *p_char;
    int *p_int;
    double *p_double;
    void *p_void;

    // 函数指针
    int (*p_func)(int, int);

    printf("sizeof(char*)   = %zu 字节\n", sizeof(p_char));
    printf("sizeof(int*)    = %zu 字节\n", sizeof(p_int));
    printf("sizeof(double*) = %zu 字节\n", sizeof(p_double));
    printf("sizeof(void*)   = %zu 字节\n", sizeof(p_void));
    printf("sizeof(func*)   = %zu 字节\n", sizeof(p_func));

    // 验证:不同类型指针大小相等
    if (sizeof(p_char) == sizeof(p_int) &&
        sizeof(p_int) == sizeof(p_double) &&
        sizeof(p_double) == sizeof(p_void)) {
        printf("\n验证通过:所有数据指针大小相同。\n");
    } else {
        printf("\n验证失败:数据指针大小不一致。\n");
    }

    return 0;
}

编译与运行

# 使用gcc编译
gcc -o ptr_size ptr_size.c

# 运行
./ptr_size

预期输出(64位Linux/macOS环境)

sizeof(char*)   = 8 字节
sizeof(int*)    = 8 字节
sizeof(double*) = 8 字节
sizeof(void*)   = 8 字节
sizeof(func*)   = 8 字节

验证通过:所有数据指针大小相同。

在32位系统上,上述值将全部变为 4。无论哪种情况,所有指针大小都相等。

验证方法

  • 编译并运行程序,观察输出的5个字节数。
  • 判定通过条件:char*、int*、double*、void* 四者大小完全一致,且程序输出“验证通过”。
  • 若在32位环境下编译,所有值应为4;在64位环境下应为8——这正说明指针大小由平台地址宽度决定,与指向类型无关。

常见问题

  • 为什么函数指针大小可能不同? 在部分嵌入式平台(如Harvard架构)上,函数指针与数据指针大小可能不同。本案例在常见桌面/服务器系统上二者一致,但标准C不保证这一点。
  • 为什么不用 printf("%d", sizeof(...))? sizeof 返回 size_t 类型,用 %zu 格式化才是可移植的正确写法。