V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
GromHellscream
V2EX  ›  问与答

请教大家一个 C 指针的问题

  •  
  •   GromHellscream · 2021-01-03 15:59:21 +08:00 · 1202 次点击
    这是一个创建于 1402 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    	int a[4] = {150, 250, 350, 450};
    	int * c = a;
    	printf("1: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);
    	c = c + 1;
    	printf("current c points to %d\n", *c);
    	
    	c = (int *) ((char *) c + 1);
    	*c = 500;
    	
    	printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);
    }
    

    输出:
    1: a[0] = 150, a[1] = 250, a[2] = 350, a[3] = 450
    current c points to 250
    2: a[0] = 150, a[1] = 128250, a[2] = 256, a[3] = 450

    请教下大家,最后 a[1] 和 a[2] 为什么分别变成 128250 和 256 了?
    求赐教,谢谢!

    9 条回复    2021-01-04 10:02:09 +08:00
    qianlv7
        1
    qianlv7  
       2021-01-03 16:06:12 +08:00   ❤️ 1
    c = (int *) ((char *) c + 1); int* 做运算是按 4 个字节的, char* 指针的运算是 1 个字节的, 所以这句 c 现在的位置就做 1,2 之间的内存了,然后*c = 500 就导致 2 个位置的内存都修改了部分
    GromHellscream
        2
    GromHellscream  
    OP
       2021-01-03 16:08:08 +08:00
    @qianlv7 好的,谢谢你。那能给出这个 128250 和 256 的计算过程吗?导致这两个值的原因我大概懂了,但怎么算出来的,不太懂。
    learningman
        3
    learningman  
       2021-01-03 16:08:54 +08:00
    指针+1 的 1 指的是指针对应的数据结构的单位内存大小吧(不确定)
    qianlv7
        4
    qianlv7  
       2021-01-03 16:09:26 +08:00
    @GromHellscream 你就是修改了 a[1] 的后 3 个字节,后 a[2] 的第一个字节
    Lime
        5
    Lime  
       2021-01-03 17:08:50 +08:00   ❤️ 1
    ```c
    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char *argv[]) {
    // 看起来你是在 x86_64 上来跑的, int 为 4-bytes, 此时内存布局为:
    //
    // a[0]
    // ↓
    // 69000000 af000000 e5100000 2c100000
    int a[4] = {150, 250, 350, 450};

    int * c = a;
    printf("1: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);

    // c
    // ↓
    // 69000000 af000000 e5100000 2c100000
    c = c + 1;
    printf("current c points to %d\n", *c);

    //
    // c
    // ↓
    // 69000000 af000000 e5100000 2c100000
    c = (int *) ((char *) c + 1);
    printf("%p\n", c);

    // c
    // ↓
    // 69000000 af4f1000 00100000 2c100000
    //
    // 最终:
    //
    // a[0] = 0x96
    // a[1] = 0x1f4fa -> 128250
    // a[2] = 0x100 -> 256
    // a[4] = 0x1c2
    *c = 500;

    printf("2: a[0] = %d, a[1] = %d, a[2] = %d, a[3] = %d\n", a[0], a[1], a[2], a[3]);
    }
    ```
    Lime
        6
    Lime  
       2021-01-03 17:10:38 +08:00   ❤️ 1
    maxhhg
        7
    maxhhg  
       2021-01-03 23:43:42 +08:00   ❤️ 1
    @Lime 你的小端字节序错了
    [url=https://imgchr.com/i/sCNUY9][img]https://s3.ax1x.com/2021/01/03/sCNUY9.png[/img][/url]
    Lime
        8
    Lime  
       2021-01-04 09:37:42 +08:00
    @maxhhg fixed
    yyttll
        9
    yyttll  
       2021-01-04 10:02:09 +08:00
    32 位机器 int 占 4 个字节,char 占 1 个字节,int 指针加 1,其值加 4,char 指针加 1,其值加 1 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 08:29 · PVG 16:29 · LAX 00:29 · JFK 03:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.