学习C指针的心得随笔

学习C语言的指针有一点体会,现在记录下来。如有不妥,请读者批评指正。

一、指针是什么?

我理解的指针,它本身就是一个指向变量的地址,那么根据它所指向的C语言的变量类型,指针也相应的区别为char、int型等等。但是,对于指针本身来说,是没有什么区别的,它仅仅是一个地址而已,在32位机器上,一个指针的大小Sizeof(指针)永远是32位(4Byte),同理64位的机器则是64位(8Byte).也就是说指针的地址大小是一个机器字长,等于一个int型的长度。指针的存储内容就是那个指向变量的地址,指针的存储内容上的指向就个那个变量,需要注意的是指针也要占据存储空间。

二、指针和地址

我们一般定义一个int型指针是这样,int a;int *p=&a;或者,int *p;p=&a.这里*p=a,可以理解为给a起了一个别名是*p,当然a也可能还有其他的别名。指针只能是地址,而且是首地址,&a运算的结果正好是一个地址。 *p也是一个地址,不同的是p不是一个单纯的家伙,它有个指向范围int型,好,当你看到(int *)&a觉得是个什么东西?其实它就是个p(屁),*((int *)&a)是什么?是*p,即a.说一下,(int *)&a是个指针,指针当然需要类型了,所以要有(int*),相当于把变量a的地址转换为一个int型的指针.其他类型参照原理一样。

可以回头仔细的看一下,

  int *p =&a和

        p  =&a

(int *)&a

有什么感觉呢?

现在说说二级指针,是指向指针的指针。也就是说它是一级指针的别名。现在定义一个,int **p2,int *p1.p2=&p1,那么*p2=p1,**p2=*p1.如果想再指向p2,定义int *p3=&p2对不对呢?还是int ***p3=&p2呢?好像*的个数反映的就是指针的级别了。好,一个p1的指向范围是int,可以缩小吗?我们试试看,按字节来,char *pb;pb=(char*)p1那么pb,pb+1,pb+2,pb+3分别是int*的地址的四个字节。若有char *pb;pb=(char*)p2,那么pb,pb+1,pb+2,pb+3分别是p2的地址的四个字节.

#include "stdio.h"


int  main(void)
{
int a=0xa;
int *p1=&a;
printf("------------------------------------------------\n");
printf("*p1=%x,p1=%p,&p1=%p\n",*p1,p1,&p1);
printf("------------------------------------------------\n");
int **p2=&p1;
printf("p1=%p\na=%x\np2=%p\n*p1=%x\n&a=%p\n*p2=%p\n**p2=%x\n",p1,a,p2,*p1,&a,*p2,**p2);
printf("------------------------------------------------\n");
printf("(int*)&a:%p--->(*(int*)&a):%x\n",(int*)&a,(*(int*)&a));


char *pb;


pb=(char*)p1;
printf("onelevel:%p--->%x\n",pb,*pb);


pb=(char*)p2;
printf("twolevel:%p--->%x %x %x %x\n*pb=p2=%p\n",pb,(unsigned char)*pb,(unsigned char)(*(pb+1)),(unsigned char)(*(pb+2)),(unsigned char)(*(pb+3)));
printf("------------------------------------------------\n");
printf("sizeof(char)=%d,sizeof(char*)=%d,sizeof(int*)=%d,sizeof(&p1)=%d\n",sizeof(char),sizeof(char*),sizeof(int*),sizeof(&p1));printf("------------------------------------------------\n");
pb=(char*)p2;
printf("*(char*)p2:%x %x %x %x\n",(unsigned char)*pb,(unsigned char)*(pb+1),(unsigned char)*(pb+2),(unsigned char)*(pb+3));
printf("------------------------------------------------\n");
pb=(char*)&p2;
printf("*(char*)&p2:%x %x %x %x\n",(unsigned char)*pb,(unsigned char)*(pb+1),(unsigned char)*(pb+2),(unsigned char)*(pb+3));
return 0;
}


把这个程序运行一下,看看结果。在32位intel的运行结果



[root@andLinux win]# gcc pp.c -o pp&&./pp
------------------------------------------------
*p1=a,p1=0xbfe10080,&p1=0xbfe1007c
------------------------------------------------
p1=0xbfe10080
a=a
p2=0xbfe1007c
*p1=a
&a=0xbfe10080
*p2=0xbfe10080
**p2=a
------------------------------------------------
(int*)&a:0xbfe10080--->(*(int*)&a):a
onelevel:0xbfe10080--->a
twolevel:0xbfe1007c--->80 0 e1 bf             小端顺序:其实是:bf e1 00 80
*pb=p2=0xbfe10080
------------------------------------------------
sizeof(char)=1,sizeof(char*)=4,sizeof(int*)=4,sizeof(&p1)=4  
------------------------------------------------
*(char*)p2:80 0 e1 bf
------------------------------------------------
*(char*)&p2:7c 0 e1 bf

再多说下,其实指针的强制类型转换,转换的只是指向的类型和地址的范围,而指针依然是一个机器字长的大小,从来都没有变。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值