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

为何十进制内存地址递减、十六进制内存地址递增?C程序观测疑问

关于内存地址十进制递减、十六进制递增的疑问解答

嘿,我来帮你理清这个困惑!首先得敲个重点:地址本身的数值趋势是固定的,十进制和十六进制只是同一数值的不同写法,不可能一个递增一个递减——你看到的差异肯定是打印方式或者代码逻辑出了小问题。

先搞懂数组内存的基本逻辑

不管是int、float还是double数组,元素在内存里都是连续挨在一起存储的。比如你定义int arr[5],第一个元素arr[0]的地址是最低的,往后每个元素的地址都会比前一个大(大多少取决于数据类型的字节数,比如int占4字节,那&arr[1]就比&arr[0]大4),所以地址数值本身是严格递增的——这个规律和用十进制还是十六进制表示没关系。

你看到矛盾趋势的核心原因

最可能的两种情况:

1. 用错了地址打印的格式符

在C语言里,地址是无符号的指针类型,必须用%p格式符打印(它会输出十六进制的地址,通常带0x前缀)。如果你图省事用%d(有符号十进制整数)打印地址,麻烦就来了:

  • 当地址的数值超过有符号整数的最大值(比如32位系统里是2^31-1),会被强制解析成负数。
  • 假设你的数组地址刚好落在这个负数区间,那么原本递增的地址数值,用%d打印出来就会是一串从“小负数”到“大负数”的数,视觉上可能和你预期的“递增”不符;而用%p打印的十六进制是正确的无符号值,看起来是正常递增,这就会让你误以为两种表示的趋势相反。

2. 遍历数组的顺序搞反了

比如你写循环的时候,从数组的最后一个元素(arr[4])往第一个(arr[0])遍历,那打印出来的地址数值本身就是递减的。但如果你的代码里,十进制地址是逆序打印,十六进制地址却不小心写成了正序打印,就会出现“一边递减一边递增”的矛盾——这纯粹是代码逻辑的小失误。

正确的打印姿势,帮你解决困惑

要准确打印地址的十进制和十六进制形式,建议这么写代码:

#include <stdio.h>
#include <stdint.h>  // 要包含这个头文件才能用uintptr_t

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    printf("十进制地址\t十六进制地址\t存储数值\n");
    for (int i = 0; i < 5; i++) {
        // 把地址转成uintptr_t(无符号整数类型),用%lu打印十进制
        printf("%lu\t\t%p\t\t%d\n", (uintptr_t)&arr[i], &arr[i], arr[i]);
    }
    return 0;
}

运行这段代码你会发现,十进制和十六进制地址的趋势完全一致——都是稳稳递增的,因为数组元素的地址本身就是按这个顺序排列的。

再总结下

地址的数值是固定的,十进制和十六进制只是不同的“写法”,不存在趋势相反的情况。你看到的问题,要么是用错了打印格式符把无符号地址当成有符号数输出,要么是循环遍历的顺序搞反了。按照上面的正确写法调整代码,就能看到一致的地址趋势啦!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:54:48