🎇作者:小树苗渴望变成参天大树
🎊 作者宣言:认真写好每一篇博客
🎄作者gitee:gitee
初阶指针
🎉前言
今天作者又来更新好文了,我们今天来讲指针方面的知识,指针可以说对于我们编程是特别重要的一个部分,因为他涉及到内存跟地址有关系,那指针到底是什么呢?我们接下来从以下几个方面给大家细细的讲解(没有特别说明的情况下,都是在32位平台下讲解的):
指针:
- 指针是什么
- 指针和指针类型
- 野指针
- 指针运算
- 指针和数组
- 二级指针
- 指针数组
🧨一、指针是什么
我们电脑有硬盘,有内存,通常硬盘就是你的存储空间,内存任务在运行的时候所占的空间,一般电脑,500GB硬盘大小,8/16GB内存大,我们可以打开我们的任务管理器:
那我们到底是怎么使用内存空间的呢?
内存的最小单位就是一个字节,那内存一共有多少个字节组成呢?这时候就需要引用地址的概念。
地址是什么呢?
对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0);
那么32根地址线产生的地址就会是:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
…
11111111 11111111 11111111 11111111
这里就有2的32次方个地址。每个地址是四个字节。
这时候我们有了2的32次方地址了,我们把这个地址所对应的数值,当成一个字节单位编号,这个时候我们内存就有2的32次方个字节。
每个地址标识一个字节,那我们就可以给 (2^32Byte = = 2^32/1024KB = =232/1024/1024MB==232/1024/1024/1024GB == 4GB)4G的空闲进行编址。
同样的方法,那64位机器,如果给64根地址线,那能编址多大空间,自己计算。
我们内存就可以这样表示
1.所以指针是什么呢?
- 指针是内存中一个最小单元的编号,也就是地址
- 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
2.我们怎么使用指针呢?
我们可以通过&(取地址操作符)取出变量在内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量
#include <stdio.h>
int main()
{
int a = 10;//在内存中开辟一块空间
//在内存的存储应该是原码的形式
//00000000 00000000 00000000 00001010
int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
//a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
return 0;
}
我们通过图理解了一遍,也发现地址的编号是连续的。我们在深入内存中来看看:
p里面放的是a的地址起始地址(0x004FF760),我们看到下一个内存的地址是(0x004FF764),编号相差4,就相差4个字节,这个我相信大家很容易搞混,作者自己也是理解了很长时间。
int*p=&a;,p是指针变量存放地址的,*是告诉我们p是指针变量,不是普通变量,int是指针所指向的类型,这个下一节会详细介绍
指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。
1.这里我们就明白:
在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
2.总结:
指针是用来存放地址的,地址是唯一标识一块地址空间的。指针的大小在32位平台是4个字节,在64位平台是8个字节
💖二、指针和指针类型
这里我们在讨论一下:指针的类型
我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?
准确来说是有的
对于普通变量来说,int是四个字节,char是一个字节等等,那么对于指针,我们在32位平台下,指针都是代表地址,都是四个字节,那么intp,charp不都是四个字节啊,那为什么指针还需要类型呢?
那指针类型的意义是什么呢?
2.1 指针的解引用
我们来看一个代码
int a=0x11223344;
int b=0x11223344;
int *p1=&a;
char*p2=&b;
*p1=0;//解引用得到地址里面的内容
*p2=0;
我们通过这个例子可以说明,指针类型决定了指针进行解引用操作的时候一次访问几个字节(访问权限受到类型的控制)
比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。
2.2 指针±整数
我们再来看一个代码:
int a=0x11223344;
int b=0x11223344;
int *p1=&a;
char*p2=&b;
printf("%p\n",p1+1);
printf("%p\n",p2+1);
我们看到结果了,说明指针的类型决定了指针向前或者向后走一步有多大(距离)
通过上面两个特点,我们是不是就可以对内存中任意数进行修改,只要找到地址,进行解引用操作即可,
来看代码
int a=0x11223344
char*p1=(char*)&</