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

关于C语言指针ii值为0的疑问:为何不是内存单元地址?

嘿,这个问题问到点子上了!咱们先理清两个核心点:指针ii本身的值根本不是0,你看到的0是因为用错了printf的格式符;另外,咱们可以一步步走代码,把每个变量的变化都捋清楚,你就明白到底发生了什么。

首先,核心错误:用错了printf格式符

你最后写的是printf("%f", ii);,但ii是float*类型的指针,%f是用来打印浮点数(float/double)的格式符,用它打印指针属于未定义行为——简单说就是编译器不知道该怎么处理,结果完全依赖于系统环境。

在你的场景里,指针的二进制值被强行解析成了浮点数,刚好在你的系统上这个解析结果是0.0,但这完全是巧合,换个平台可能输出奇怪的数字,甚至程序崩溃。

如果要打印指针的内存地址,应该用%p格式符,并且要把指针转换成void*类型,正确的写法是:

printf("%p", (void*)ii);

这样就能看到ii实际指向的内存地址了。

咱们一步步走代码,看变量到底怎么变

为了更清楚,我把每一步的变量变化列出来:

  1. 初始化阶段

    • float hh[]={10,4,(float)('b'-'d')};:'b'-'d'等于-2,所以hh初始是[10.0, 4.0, -2.0]
    • static float *ii=dd;:因为dd是NULL,所以ii一开始是空指针
  2. hh[0]+=6/4;

    • 这里是整数除法,6/4的结果是1(不是1.5),所以hh[0] = 10.0 + 1 = 11.0,现在hh变成[11.0, 4.0, -2.0]
  3. ii=&hh[2]-1;

    • &hh[2]是数组第三个元素的地址,指针减1后指向数组的第二个元素hh[1],所以现在ii = &hh[1](是一个有效的内存地址,不是0)
  4. *ii=ii[0]+3;

    • ii[0]等价于*ii,也就是当前hh[1]的值4.0,加3后是7.0,所以hh[1]被改成7.0,hh变成[11.0, 7.0, -2.0]
  5. ii[-1]=(*(hh+1))+2;

    • ii[-1]等价于*(ii-1),也就是hh[0];*(hh+1)是hh[1]的值7.0,加2得9.0,所以hh[0]被改成9.0,hh变成[9.0, 7.0, -2.0]
  6. hh[2]=*(++ii)*2;

    • ++ii让ii的指向往后移一位,变成指向hh[2];*(ii)是当前hh[2]的值-2.0,乘2得-4.0,所以hh[2]被改成-4.0,现在ii = &hh[2],hh变成[9.0, 7.0, -4.0]
  7. *ii=(hh[0]==4);

    • hh[0]是9.0,9.0 == 4的结果是假,C语言里布尔假用0表示,所以把0赋值给*ii(也就是hh[2]),现在hh[2] = 0.0,但**ii本身还是指向hh[2]的地址,没有变**!

最后再明确两个点

  • 指针ii的值从第三步开始就一直是有效的内存地址(最后指向hh[2]),从来不是0;
  • 你看到的0,是错误用%f打印指针时,把地址的二进制当成浮点数解析的结果;如果要打印ii指向的内容(也就是hh[2]的值),应该写printf("%f", *ii);,这时候输出的0.0才是正确的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:00:49