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

C语言指针算术未打印变量地址时无法正确指向变量问题

问题原因说明

根本原因:你的代码触发了C语言的未定义行为

C标准对指针算术和指针比较有严格的约束:

  • 只有指向同一个数组元素(包括数组末尾后一个合法位置)的指针,才能进行加减运算、大小比较操作。
  • 你代码里的d、c、b、a是四个独立的局部变量,C标准没有规定它们在栈上的存储顺序、是否连续、是否存在内存填充间隙,跨独立变量的指针遍历本身就是不被允许的,编译器可以按照任意逻辑处理这类代码。

首次运行跳过8、6的原因

GCC在默认编译(无调试相关代码)时,哪怕不开启优化(-O0),也可能调整局部变量的栈存储布局:

  • 可能没有按照你定义变量的顺序连续分配四个int的内存空间,c、b的存储位置不在&d向低地址递减的路径上
  • 极端情况下甚至会把没有被取地址的变量优化到寄存器中,不在栈上分配空间,所以ptr--遍历的时候会直接跳过c、b对应的内存,访问到的下一个有效变量就是a,所以输出10、4的结果。

添加地址打印代码后恢复正常的原因

当你增加了打印四个变量地址的代码后,编译器必须为四个变量都在栈上分配可寻址的内存空间,为了适配取地址的操作,编译器大概率会按照连续顺序分配四个int的内存,这时候指针增减刚好能遍历到所有变量的地址,输出符合你的预期。
注意:这只是编译器的巧合实现,不属于C标准保证的稳定行为,更换编译选项、编译器版本或者修改其他代码都可能导致问题复现。


正确实现方案

如果需要用指针遍历多个同类型变量,应该把变量存入数组,数组的元素存储是连续、顺序确定的,此时的指针算术才符合C标准要求:

#include <stdio.h>

int main(void) {
    int arr[] = {10, 8, 6, 4};
    int *ptr;
    int len = sizeof(arr) / sizeof(arr[0]);

    printf("decrement \n");
    for (ptr = arr + len - 1; ptr >= arr; ptr--)
    {
        printf("%d \n", *ptr);
    }

    printf("increment \n");
    for (ptr = arr; ptr < arr + len; ptr++)
    {
        printf("%d \n", *ptr);
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:27:05