C语言_指针详解

C语言_指针详解

0.闲话

​ 看滴水逆向之后的学习总结。

​ 编译环境:vc++6.0

​ 个人认为:指针这一块要真正明白每个指针代表什么,如何在内存寻址,还是要看指针的反汇编,才能理解透彻。

1.内存引用

​ 指针的更本就是对内存的引用,应为指针引用起来比较方便,但是,在此之前不许要明白,有些内存是不能引用的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-43clgqCS-1585486053449)(E:/Typora/image/1585478949896.png)]

特别注意常量区。比如

char* p ="hello,world!\0"

此时的字符串helloworld就存储在常量区,通过指针p可以引用它,进行读操作,但是不能进行写操作,比如

*p = 'H;

这样写虽然能通过编译,但是程序不能运行,因为常量区的数据补课写入。

2.指针类型的实质及其大小。

​ 包含char,short,int,double,这些变量类型的指针。

​ 我下面以char型举例。

char* p;

​ 这里的变量,并不是 * p,而是p,他的类型为 char*(忘掉书上刻板的概念),也就是说,他在内存中和char型数据一样的存放变量,只不过char*型数据存储的是地址。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-74xc2kmL-1585486053451)(E:/Typora/image/1585480004205.png)]

可以发现,char*的p和int的a字节宽度都是4,只不过p的内存存储的是一个地址。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dwFsdtDI-1585486053451)(E:/Typora/image/1585480237386.png)]

这样就更明显了,也就是说,

char* p;

这样只是代表一个数据类型为char*的变量p,p在内存中的宽度为4,用于存放地址,而通过*p,能寻找p存储的地址对应的数据,并且根据char*,确定*p的大小为char型,即1个字节。

通过上面的举例,我要说的是,所有的指针变量其实都是4个字节,因为他们用于存放地址。而通过*这个符号,可以引用对应地址的数据。

​ 所以,二维指针,* * p,我们可以将p指向一个地址,这个地址存储的是另一个数据的地址,比如a的地址,那*p输出的就是a的地址, * *p输出的就是a的值。

​ 三维指针,四位指针……等等就是这样反反复复寻找对应地址的数据。

3.指针寻址

​ 既然不管指针什么类型,他的大小都是4个字节,且存储地址,那为啥还有划分类型呢?

不像数组的寻址,只需要str[i]中的i一直自增即可,而指针的寻址是根据数据偏移,而数据偏移的量,其实就跟这个指针的类型有关。比如

char* p;
int* q;
p++;
q++;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FfLLS71u-1585486053452)(E:/Typora/image/1585481745156.png)]

可以发下,char*型的p自增,地址+1;而int*型的q自增,地址+4;

所以当他指针寻址是,根据变量类型不同,偏移的量也不同。

4.结构体指针

结构体指针,一般用于指向一个结构体,方便查找数据。

strct student
{
	char name;
	int number;
	int ave;
}stu;
//这个结构体的宽度为12,不是9,因为 存在字节对齐。

//结构体指针
struct student* p;
p = stu;
p++;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PFQko4wx-1585486053452)(E:/Typora/image/1585482527807.png)]

结构体指针同样以符合指针的寻址,偏移规则,

一般结构体引用变量的方式为

stu.number = 10;

而结构体指针p引用这个结构体stu的变量,方式为

p->number = 10;

5.数组指针

同结构体指针一样,数组指针一般指向一个数组的首地址。

举例一个char型的数组指针。

char (*p)[n] ;//一定要写(),不然性质就变了。

这里的变量名一样是p。而对于的数据类型是char (*)[]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NYdrw8Cs-1585486053453)(E:/Typora/image/1585483538277.png)]

调试一下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1aOcloC8-1585486053453)(E:/Typora/image/1585484555791.png)]

char (*)p[4];

因为char的大小为1个字节,所以p的大小为1*4=4。

如果是int

int (*)q[4];

因为int的大小为1,所以q的大小为4*4 = 4 。

而一维的数组指针的寻址,需要两个*,即

printf("%d",*(*(p+1)+1));

因为这p的大小为4,,所以*(p+1)的偏移为1 * 4,(因为是char型)。

而后面总共的偏移为1 * 4+1 * 1 = 5 ; 就相当于a[5],对应就是字符f。

6.指针数组

char *p[5];

指针数组的本质是一个数组,只不过数组的每个变量存放指针。

7.指针函数

指针函数的本质是一个函数,只不过函数的返回值为一个指针。


建议多写写
如果发现我写的有什么不对或者是写的不好的地方,欢迎大家留言交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值