GromHellscream
V2EX  ›  问与答

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

  •  
  •   GromHellscream · Jan 3, 2021 · 2165 views
    This topic created in 1980 days ago, the information mentioned may be changed or developed.
    #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 replies    2021-01-04 10:02:09 +08:00
    qianlv7
        1
    qianlv7  
       Jan 3, 2021   ❤️ 1
    c = (int *) ((char *) c + 1); int* 做运算是按 4 个字节的, char* 指针的运算是 1 个字节的, 所以这句 c 现在的位置就做 1,2 之间的内存了,然后*c = 500 就导致 2 个位置的内存都修改了部分
    GromHellscream
        2
    GromHellscream  
    OP
       Jan 3, 2021
    @qianlv7 好的,谢谢你。那能给出这个 128250 和 256 的计算过程吗?导致这两个值的原因我大概懂了,但怎么算出来的,不太懂。
    learningman
        3
    learningman  
       Jan 3, 2021
    指针+1 的 1 指的是指针对应的数据结构的单位内存大小吧(不确定)
    qianlv7
        4
    qianlv7  
       Jan 3, 2021
    @GromHellscream 你就是修改了 a[1] 的后 3 个字节,后 a[2] 的第一个字节
    Lime
        5
    Lime  
       Jan 3, 2021   ❤️ 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  
       Jan 3, 2021   ❤️ 1
    maxhhg
        7
    maxhhg  
       Jan 3, 2021   ❤️ 1
    @Lime 你的小端字节序错了
    [url=https://imgchr.com/i/sCNUY9][img]https://s3.ax1x.com/2021/01/03/sCNUY9.png[/img][/url]
    Lime
        8
    Lime  
       Jan 4, 2021
    @maxhhg fixed
    yyttll
        9
    yyttll  
       Jan 4, 2021
    32 位机器 int 占 4 个字节,char 占 1 个字节,int 指针加 1,其值加 4,char 指针加 1,其值加 1 。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2848 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 48ms · UTC 13:11 · PVG 21:11 · LAX 06:11 · JFK 09:11
    ♥ Do have faith in what you're doing.