Memory address code

理解内存地址https://blog.csdn.net/ssc_zcys/article/details/105871643
指针补充https://blog.csdn.net/ssc_zcys/article/details/105876987

写程序的时候并不是从上至下写的,逻辑也不是特别好,但有助于理解,所以我保持了代码的完整性,并附上详细的注释。

下面贴上代码:
addr.c

/***********
*   addr.c
*  ssc_zcys
* 2020-05-01
***********/
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    int b[5]={1,2,3,4,5};
    printf("b_addr   =%p\n",b);    //b_addr   =0x7fff9a625ed0
    printf("b[2]_addr=%p\n",&b[2]);//b2_addr  =0x7fff9a625ed8
    printf("&b+1_addr=%p\n",&b+1); //&b+1_addr=0x7fff9a625ee4
                         //(&b+1)等于数组结束地址的下一个存储单元
    int a = 511;   //十进制     十六进制        二进制
                   // 511      0x01ff      0000 0001 1111 1111
                   // 在内存中的存放方式:小端存储
                   //内存地址   0x0001    0x0002    0x0003    0x0004
                   //内存内容  11111111  00000001  00000000  00000000
    printf("a_sizeof=  %d\n",sizeof(a));//int型数据占四个字节
    printf("a_addr=%p\n",&a);       //a_addr=0x7fff9a625ecc

    //(&a+1)取的是int型a结束地址的下一个存储单元,
    //十六进制:0xcc+4=0xd0 (这里恰好指向了上面的数组b)
    printf("&a+1_addr=%p\n",&a+1);  //&a+1_addr=0x7fff9a625ed0
    printf("(char *),value(&a+i) per byte:\n");
    //取指针指向的地址的内容,也叫解引用
    printf("&a+0=%d\n",*(char*)&a);//先取a的地址,
                                   //转换为(char *),地址不变,
                                   //但是char类型是一个字节,
                                   //所以指向的是a的第一个字节,
                                   //最后再加*是解引用。
                                   //因为a是四个字节,在内存中
                                   //小端存储,所以存储方式是:
                                   //11111111 00000001
                                   //00000000 00000000
                                   //output:-1
    printf("&a+1=%d\n",*((char *)&a+1));
                                   //同理。地址加1就是取第二个字节
                                   //output:1
    printf("&a+2=%d\n",*((char *)&a+2));
                                   //同理。地址加2就是取第三个字节
                                   //output:0
    printf("&a+3=%d\n",*((char *)&a+3));
                                   //同理。地址加3就是取第三个字节
                                   //output: 0   
            //***   注意   ***/ 
            //如果写成  *(char *)&a+1  就变成了先取地址值,最后加1
            //或者分开写:
            //           char *p;
            //           p = (char *)&a+1;
            //           printf("%d\n",*p);

    int *pi;
    pi = &a;              //a=511      a_addr=0x7fff9a625ecc
    printf("pi_sizeof= %d\n",sizeof(pi));  //指针占8个字节
    printf("pi_addr= %p\n",pi);     //pi_addr=0x7fff9a625ecc
    //------------------------------------------------------------
    //重新举例捋一遍
    int c = 0x78563412;             //little endian
                                    //0x12 0x34 0x56 0x78
                                    //00010010 00110100
                                    //01010110 01111000
    printf("c_addr=%p\n",&c);        //c_addr=0x7fff9a625ec8
    printf("&c+1_addr=%p\n",&c+1);//&c+1_addr=0x7fff9a625ecc
    char *ptr;
    printf("ptr_sizeof=%d\n",sizeof(ptr));//指针八字节
    ptr = (char *)&c;             //取c的地址转换为(char *)
                                  //地址仍旧是0x7fff9a625ec8
                                  //但此时,就像上面的变量a
                                  //转换为char型后只能指向一个
                                  //字节的内容
    printf("ptr_addr=%p\n",ptr);  //ptr_addr=0x7fff9a625ec8
    printf("%d\n", *ptr);         //output:18      0001 0010
    ptr = (char *)&c + 1;         //指向int型c的第二个字节
    printf("ptr_addr=%p\n",ptr);  //ptr_addr=0x7fff9a625ec9
    printf("%d\n", *ptr);         //output:52      0011 0100
    ptr = (char *)&c + 2;         //指向int型c的第三个字节
    printf("ptr_addr=%p\n",ptr);  //prt_addr=0x7fff9a625eca
    printf("%d\n", *ptr);         //output:86      0101 0110
    ptr = (char *)&c + 3;         //指向int型c的第四个字节
    printf("ptr_addr=%p\n",ptr);  //prt_addr=0x7fff9a625eca
    printf("%d\n", *ptr);         //output:120     0111 1000

    return 0;
}

没有保存第一次的输出结果,贴上第二次的输出结果:
addr_output
变量在内存中的位置:
变量在内存的位置
在这里插入图片描述

。。。 。。。没有耐心怎么能行,哈哈

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值