文章目录
1.内存和地址
1.在计算机中为了方便管理内存,内存会被划分为以字节为单位的内存空间,也就是说一个内存单元的大小是一个字节
为了方便找到这个内存单元,我们会给每个内存单元一个编号,就像生活中每个房间都有门牌号
有了内存单元的编号,就可以快速找到内存单元
所以我们可以理解为:
编号 =地址 =地址
在c语言中也被称为指针
2.指针变量和地址
2.1取地址操作符(&)
在C语⾔中创建变量其实就是向内存申请空间
#include <stdio.h>
int main()
{
int a = 10;
return 0;
}
可以看出a的地址为
0x006FFD70
0x006FFD71
0x006FFD72
0x006FFD73
那我们如何能得到a的地址呢?
使用一个操作符(&)-取地址操作符
#include <stdio.h>
int main()
{
int a = 10;
&a;//取出a的地址
printf("%p\n", &a);
return 0;
}
2.2指针变量和解引用操作符
2.2.1指针变量
变量创建的本质是:**在内存上开辟的空间**
int a=10;
要向内存申请4个字节的空间,存放数据10
&a;//&-----取地址操作符
printf("%p\n",&a);
对于a来说,我们拿到的是a所占4个字节的第一个字节的地址(地址较小的那个字节的地址)
return 0;
int * ptr = &a; //ptr叫指针变量(因为是存放指针的变量,所以叫指针变量)
**指针变量就是用来存放地址的
存放在指针变量中的值,都会被当成地址使用**
2.2.1解引用操作符
只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)。
int main()
{
int a=10;
int * p = & a;
*p=0;//解引用操作符/间接访问操作符
//*p的意思是通过p中存放的地址,找到地址指向的空间,*p就是a
printf("%d\n",a)//结果为0;
return 0;
}
这里*说明p是指针变量
p指向的对象是int类型的
2.3指针变量的大小
32位的机器上,有32根地址线,地址线上传输过了的电信号,转换成数字信号后,的32个0/1组成的二进制序列就是地址
地址都是32个0/1组成的二进制序列的话,那么存放这个地址需要空间大小就是4个字节所以指针变量的大小都是4个字节!
以下是在(86)的情况下运行的代码结果可以看出指针变量大小为4:
x86(32位)环境下为什么char的指针变量和int的指针变更量都是4个字节呢?是为了存放地址的,指针变量的大小是取决于存放一个地址需要多大的空间的!
X64环境,64位环境
64个地址线,地址就是64个0/1组成的二进制序列,要存放这样的地址,就需要8个字节所以指针变量的大小就是8个字节
以下是在(86)的情况下运行的代码结果可以看出指针变量大小为8:
指针变量的大小不是取决于对象,而是取决于存放的地址。
俗话说,不要在门缝里看人,把人看扁了
不要在门缝里看指针,把指针看扁了!!
3.指针类型的意义
3.1指针的解引用
对⽐,下⾯2段代码,主要在调试时观察内存的变化。
int main()
{
int n=0x11223344;
int *p = &n;
*p=0;
return 0;
}
int main()
{
int n=0x11223344;
char *p = &n;
*p=0;
return 0;
}
可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0
结论:
1.指针类型是有意义的
2.指针类型决定了指针在解引用操作的权限,也就是第一次解引用访问几个字节。
char类型的指针解引用访问1个字节,
int类型的指针解引用访问4个字节
3.2 指针±整数
#include <stdio.h>
int main()
{
int n = 0x112233344;
int *p = &n;
char *pc = &n;
printf("p=%p\n", p);
printf("p+1=%p\n", p+1);
printf("%pc\n", pc);
printf("%pc+1\n", pc+1);
return 0;
}
调试时观察地址的变化
char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。
这就是指针变量的类型差异带来的变化
结论:
1.指针类型是有意义的
2.指针类型决定了,指针进行+1/-1操作的时候,一次跳过几个字节(指针的步长)
那么指针类型的这些特点,怎么使用呢?
如在数组{1,2,3,4,5,6,7,8,9,10}中
1.常规数组下标的方式访问
2.指针方式访问
4.const修饰指针
const如果放在*
的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。
但是指针变量本⾝的内容可变。
const如果放在*
的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指
向的内容,可以通过指针改变。