理解指针运算符&和取值运算符*的原理

理解指针运算符&和取值运算符*的原理

通过下面一段代码的输出结果,可以很好的理解指针运算符&和取值运算符的原理:
文字分析已经写在了代码注释中,是在做实验时根据输出结果分析的

#include <stdio.h>

int main(void)
{
	/*
	 * int a[5] 与 int a 的本质:
	 * 	其实两个a并无本质区别,它们都是汇编中的标签
	 * 	汇编中的标签代表的是地址
	 * 	所以这两个a都是代表这片空间的起始地址
	 * 	再具体一点说:
	 * 	数组名a代表了一个具有20字节的空间的起始地址
	 * 	整型变量a代表了一个具有4个字节空间的起始地址
	 */
	int a[5] = {1,2,3,4,5};/* a作为右值时代表数组首元素的地址 */
	int *ptr = (int *)(&a + 1);

	/* 数组在栈上的布局 */
	for (int i = 0; i < 5; i++) {
		printf("address a[%d] = %p\n", i, &a[i]);
	}

	printf("address  a:%p\n", a); /* a代表的是数组首元素的地址 */
	printf("address &a:%p\n", &a);/* &a代表的是数组的首地址 */

	/*
	 * sizeof(&a) = 8:说明&a是一个指针类型
	 * 一个类型为T的指针的移动,以sizeof(T)为移动单位
	 * 所以
	 * a+1:
	 * 	a本身就是一个地址,它就是汇编中的一个标签
	 * 	a代表的时数组首元素的地址,地址就是一个指针,它是一个int类型的指针,意思就是指针指向4个字节大小的内存单元
	 * 	移动单位为sizeof(int)
	 * &a+1:
	 * 	先理解&a:
	 * 		取地址符&后面跟的是指针的类型,什么是指针的类型?
	 * 		int类型的指针,就是这个指针指向4个字节大小的内存空间
	 * 		long类型的指针,就是这个指针指向8个字节大小的内存空间
	 * 		这个就是指针的类型
	 * 		所以,因为这里的a是一个数组,内存空间大小为20字节
	 * 		所以 &a + 1 的第一步就是根据a的大小计算出移动单位,然后将&a(地址)加上移动单位,最后得到新的地址
	 * 	理解概念,你是一个什么类型的指针
	 *
	 * 	总结:
	 * 		&a表示的是一个指针,更具体一点说,代表一个a类型的指针
	 * 		再进一步说,&a 表示的是指向a类型所占有的字节空间的地址
	 * 	
	 * 	& 和 * 的原理:
	 * 		取地址符 & 的工作原理:
	 *			1.先计算出占用内存空间的大小:
	 *				举个例子:&a就是先计算出类型a的大小
	 *			2.将标签a替换成地址
	 *				
	 *
	 *			取值运算符 * 的工作原理:
	 *			举例:
	 *				int * p = &a;
	 *				*p;
	 *			1.先读取p里的内容,找到内存空间的首地址
	 *			2.连续读取这个指针类型大小的字节单元
	 *			
	 */
	printf("address  a+1:%p\n", a+1); /* a+1代表数组第二个元素的地址 */
	printf("address &a+1:%p\n", &a+1);/* &a+1代表第二个数组的地址 */
	printf("size  a:%d\n", sizeof(a)); /* sizeof(a) = 20 */
	printf("size &a:%d\n", sizeof(&a));/* sizeof(&a) = 8 */
	printf("address (int *)(&a + 1):%p\n", ptr);
	printf("address (int *)(&a + 1):%p\n", (int *)(&a +1));

	printf("%d, %d\n", *(a + 1), *(ptr - 1));

	return 0;
}

输出结果:

address a[0] = 0x7ffc494a8200
address a[1] = 0x7ffc494a8204
address a[2] = 0x7ffc494a8208
address a[3] = 0x7ffc494a820c
address a[4] = 0x7ffc494a8210

address    a:0x7ffc494a8200
address &a:0x7ffc494a8200

address    a+1:0x7ffc494a8204
address &a+1:0x7ffc494a8214

size  a:20
size &a:8

address (int *)(&a + 1):0x7ffc494a8214
address (int *)(&a + 1):0x7ffc494a8214
2, 5

图解:
上面的输出结果对应的图,更容易理解
在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值