变量与指针、取值符与取地址符

变量与指针、取值符与取地址符

by HPC_ZY

也是偶然,在一个项目中需要多次交换二维数组中的值,逐个操作确实耗时,就想能不能利用指针操作快速交换。成功后写此文,记录分享。

一、基础知识

通过几个例子谈谈变量、指针、地址、取地址等等

符号名称作用对象作用
&取地址符变量返回变量所在的地址
*取值符指针(地址)返回指针指向地址里存储的值

一个简单的例子

/* 取值符与取地址符*/
void main()
{
	// 初始化
	int *a = new int[1];
	a[0] = 123;
	// 取指针指向的值
	printf("a[0] = %d\n", a[0]);	// 最常用的取值方式
	printf("*a = %d\n", *a);		// 利用取值符 
	// 取指针地址
	printf("a = %0x\n", a);			// 最常用的取地址(a本来就是指针,存的地址)
	printf("&a[0] = %0x\n", &a[0]); // 利用取地址符 
	// 取存储指针的地址
	printf("&a = %0x\n", &a);		// 利用取地址符 

	// 结束
	printf("done");
	getchar();
}

某一次运行结果如下(每一次运行结果都是不一样的,因为会分配到不同地址)

操作描述
a[0]123获取指针a指向的第一个内存地址中存储的值
*a123获取指针a指向内存地址中存储的值
a0xf0595f40获取指针a指向的地址
&a[0]0xf0595f40获取指针a指向的第一个值的地址
&a0x58fffb48获取指针a在内存中的地址

打个比方(如下图),就好比办公室内有8个工位,小a被安排到5号工位即a的地址),他接收到任务1a指向的地址),任务1的内容是做一个ppta指向地址中存放的值)。
那么对应起来就是,
1)a[0] / *a ——任务具体内容——指针指向的地址中存放的值
2) a / &a[0]——任务号——指针指向的地址
3) &a —— 工位——指针存放的地址

在这里插入图片描述


二、实例

用一些例子进一步说明、理解

  1. 交换两个变量的值
/*交换两个变量的值(排序算法中常用到)*/
void main()
{
	// 初始化
	int a = 23;
	int b = 7;
	int tmp;
	// 显示
	printf("a = %d\n", a);
	printf("&a = %0x\n", &a);
	printf("b = %d\n", b);
	printf("&b = %0x\n", &b);
	// printf("tmp = %d\n", tmp); 因为没有初始化,所以不能写这一句
	printf("&tmp = %0x\n\n", &tmp);	
	// 交换
	tmp = a;
	a = b;
	b = tmp;
	// 显示
	printf("a = %d\n", a);
	printf("&a = %0x\n", &a);
	printf("b = %d\n", b);
	printf("&b = %0x\n", &b);
	printf("tmp = %d\n", tmp);
	printf("&tmp = %0x\n\n", &tmp);

	printf("done");
	getchar();
}

我某一次运行的结果如下表所示(每一次运行结果都是不一样的,因为会分配到不同地址)

abtmp&a&b&tmp
操作前237/0xee3ffa540xee3ffa740xee3ffa94
操作后723230xee3ffa540xee3ffa740xee3ffa94

从上表可以看出,交换只修改变量的值,不会修改变量在内存中储存的位置(地址)。这里顺便提一下,我们可以看到a,b,tmp的地址依次相差32(注意表中地址以十六进制显示),因为在我的电脑里int类型为32位。

  1. 交换两个指针变量的值
void main2()
{
	// 初始化
	int *a = new int[1];
	int *b = new int[1];
	a[0] = 27;
	b[0] = 9;

	int *tmp;
	// 显示
	printf("*a = %d\n", *a);
	printf("a[0] = %d\n", a[0]);
	printf("a = %d\n", a);
	printf("&a = %0x\n", &a);
	printf("b[0] = %d\n", b[0]);
	printf("b = %d\n", b);
	printf("&b = %0x\n", &b);
	printf("&tmp = %0x\n\n", &tmp);
	// 交换
	tmp = a;
	a = b;
	b = tmp;
	// 显示
	printf("a = %d\n", a);
	printf("&a = %0x\n", &a);
	printf("b = %d\n", b);
	printf("&b = %0x\n", &b);
	printf("tmp = %d\n", tmp);
	printf("&tmp = %0x\n\n", &tmp);

	printf("done");
	getchar();
}

我某一次运行的结果如下表所示(每一次运行结果都是不一样的,因为会分配到不同地址)

abtmp*a*b*tmp&a&b&tmp
操作前0x23A358500x23A35890/279/0x7E7F57580x7E7F57780x7E7F5798
操作后0x23A358900x23A358500x23A35850927270x7E7F57580x7E7F57780x7E7F5798

从上表可以看出,这次我们只交换了a,b指向的地址,而没有修改对应地址中存储的数值。
地址0x23A35850中依旧存的27,地址0x23A35890中依旧存的9

就好比,小a小b安排到5、6号工位即a、b的地址),又分别拿到任务1、任务2a、b指向的地址);后面老板又让他们把任务交换一下,小a做任务2,小b做任务1交换指向的地址)。自始至终呢,任务号对应的任务内容两个地址中存放的值)并没有变。

在这里插入图片描述


其他

  1. 上述内容应该是对的,也不排除有说错的地方。
  2. 暂时写到这里,如果以后有更多理解和实例会继续补充。
  3. 欢迎大家讲出自己的理解。
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值