You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

我在C语言中这样打印指针是否正确?为何出现输出异常与编译警告

问题说明与修正方案

对核心疑问的直接回应

  • 你当前用%i打印指针的方式完全错误,不符合C语言的类型匹配规则
  • 你看到的一长串负数是类型不匹配、截断指针值产生的错误输出,属于异常结果,不是真实的内存地址

编译警告的产生原因

  • %i是专门为打印有符号int类型整数设计的格式化占位符,只接受int类型的参数
  • 你的代码里传入的参数全是各级指针(int*、int**、int***),类型和%i要求的int不匹配,编译器自然会抛出大量格式不匹配的警告
  • 这种不匹配的参数传递属于C语言定义的未定义行为,运行结果没有标准保障

负地址的生成逻辑

现在主流运行环境是64位系统:

  • 指针的存储长度是8字节,常规int类型只有4字节
  • 当你把8字节的指针值传给期待4字节int的%i时,高位的4字节会被直接截断
  • 截断后的32位值如果最高位(有符号数的符号位)为1,就会被解读成负数输出,所以你看到的大负数本质是被截断的错误值
  • 虽然数值是错的,但逻辑对应关系和真实地址是一致的:比如本来指向同一个变量的&a、p、*q、**r,截断后的值完全相同,和你输出里的重复数值是对应的

正确的指针打印方式

C语言为指针打印提供了专属的格式化占位符%p:

  • 打印任意级别的指针值时,使用%p作为格式符,并将指针强转为void*类型传入,就能完全匹配C标准要求,彻底消除编译警告
  • 使用%p输出的地址会以标准十六进制形式展示,不会出现截断导致的负数
  • 注意:解引用指针得到的结果如果是int类型(比如*p、**q、***r),本身就是合法的int值,继续用%i打印是正确的,这也是你输出里几个10是正常值的原因

修正后的可正常编译运行的测试代码

#include <stdio.h>

int main(){
    int a = 10;
    int *p = &a;
    int **q = &p;
    int ***r = &q;
    printf("%i\n", a);
    printf("%p\n", (void*)&a);
    printf("%p\n", (void*)p);
    printf("%p\n", (void*)&p);
    printf("%i\n", *p);
    printf("%p\n", (void*)q);
    printf("%p\n", (void*)&q);
    printf("%p\n", (void*)*q);
    printf("%i\n", *(*q));
    printf("%p\n", (void*)r);
    printf("%p\n", (void*)&r);
    printf("%p\n", (void*)*r);
    printf("%p\n", (void*)*(*r));
    printf("%i\n", *(*(*r)));
    return 0;
}

内容的提问来源于stack exchange,提问作者user15380805

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 22:45:04