理解内存地址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;
}
没有保存第一次的输出结果,贴上第二次的输出结果:
变量在内存中的位置:
。。。 。。。没有耐心怎么能行,哈哈