指针概念与理解

一、前言:

1、为什么要使用指针?

变量的普通访问方法:从内存的开头,逐一向后查找。

变量的指针访问方法:根据指针变量的值,直接定位到变量所在内存的位置(地址),大大提高访问效率。

2、指针的理解

先要理解地址和数据,你可以想象有很多盒子,每个盒子有对应的号码,那个号码叫做“地址”,而盒子里放的东西叫做“数据”。
把上面的过程理解了,p和*p的区别就不难解释了。
p是指针变量,用来存放地址,你可以认为是上面所说的盒子的号码,“ * ”是解引用操作符,你可以把它理解成打开盒子,*p就是打开p号盒子,取出里面的数据。
简单来说,p存放的是地址,而*
p是让程序去那个地址取出数据。

 

 

二、概念:

1、p是一个指针变量的名字,指针变量p的值为指向的变量所在的内存起始地址(编号),如果使用%p来输出的话,它将是一个16进制数,使用%d来输出的话,它将是一个10进制数,两者转换互等。

2、*p表示此指针指向的内存地址中存放的内容(即指针所指向变量的值)。

3、&p就是取指针自身p的地址(即指针变量p所在内存的地址),毕竟指针变量也是变量的一种。

4、int *p应该理解为(int *)p ,注意int* 也是一种变量类型它定义的是 p(同样int **p理解为(int**)p), * 表示取地址上的数据。

5、指针的偏移p+1,改变的是p的值(数据),指针变量p自身在内存的地址(&p)不变。所有变量定义后,在内存的地址“&变量”不会随数据改变。如下图

 

 

三、实例对比测试:

1、分析比较p,*p,&p的值,理解指针中各个取值表示的意义。

2、不管十进制还是16进制表示的内存,单位都是字节(byte)。

 

#include"stdio.h"
main()
{
    int a[4] = { 100,200,300 }, *p1 = NULL, *p2 = NULL, *p3 = NULL;
    p1 = a; p2 = a + 1; p3 = &a[2];
    printf("对比p,*p,&p的值:\n");
    printf("p1的值:%d  *p1的值:%d  &p1的值:%d\n\n\n", p1, *p1, &p1);
    printf("p1的10进制值:%d, 变量a[0]在内存中的起始地址(10进制):%d\n\n", p1,&a[0]);
    printf("p1的16进制值:%p,变量a[0]在内存中的起始地址(16进制):%p\n\n", p1, &a[0]);
    printf("\n\n");
    system("pause");
    return(0);

}

 

四、指针的使用

因数组名a代表数组的首地址(即a[0]的地址),当p1=a(即p1=&a[0]),则数组元素a[i]的表达形式有p1[i]、*(p+i)、*(a+i)

 

五、总结

5.1、指针变量p的值是地址,“*”为取数据符,*p表示取p所指向的地址中的数据,“&”为取地址符,指针变量p自身所在的内存(&p)地址及空间大小(4个字节),与指针定义表达式中的数据类型无关。

5.2、假如定义int*p,char(*p)[2],double*p等,定义的是p指向的地址(p值)所在内存的数据类型,而不是定义p自身在内存(&p)数据及空间。

5.3、同样的指针偏移p=p+1,改变的是指针变量p的值(也就是改变p的指向地址),偏移量与定义指针有关,其偏移大小为指针指向地址的数据类型长度(如int*、int(*)[2]),而自身变量p在内存地址(&p)及空间大小4个字节不会改变。如下

 

	int n[3][4] = { 1, 2, 3, 4, 8, 7, 6, 5, 9, 10, 11, 12 };
	int(*p)[2] = n;

	printf("%d\n",p);	       //p指向的地址。
	printf("%d\n\n\n",&p);	   //变量p自身在内存的地址。

	p = p + 1;
	printf("%d\n",p);         //定义p指向地址的数据类型为int(*)[2],所以偏移2个int。
	printf("%d\n",&p);	      //指针偏移不会改变变量p自身在内存的地址。

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值