指针进阶
指针进阶
C++中变量都储存在内存中,先在内存中开辟变量类型大小的空间,然后将数值存储在其中
1、指针和指针变量
定义:指针的实质就是数据在内存中的地址,而指针变量是用来保存这些地址的变量
1 | int a = 10;(在内存中分配四个字节的空间,首字节存储值) |
1、int p为指针:指向的是*数据在内存中的地址
2、p为指针变量:指向的是保存地址的变量(地址的编号)
3、通过取址运算符&获取指针变量的地址编号:&p
4、通过取值运算符*获取指针变量的内存空间存放的内存数据
左侧连续的十六进制编号就是内存地址,每个内存地址对应一个字节的内存空间(一个内存单元占一个字节)。而指针变量保存的就是这个编号,也即内存地址
2、指针和数组
1 | int *arr[10] // 声明一个指针数组,该数组有10个元素,其中每个元素都是一个指向 int 类型对象的指针 |
2.1、数组指针
数组指针:本质是一个指针变量,指向了一个数组(行指针)
1 | int a[3][4]; |
2.2、指针数组
指针数组:本质是一个数组,该数组中的每个元素都是一个指针
1 | int a[3][4]; |
本质:()的优先级最高,[]会优先与arr结合,然后再与*符号汇合。
2.3、利用指针访问一维数组
1 | int a[4]={1,2,3,4}; |
①数组中的各元素在内存中是连续分布的,故p++可以访问到数组的下个元素
②p++实际上是指针变量p的地址编号+sizeof(int *)
2.4、通过指针访问二维数组
2.4.1、指向元素的指针
1 | int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; |
2.4.2、指向每一行的指针(指针数组方式)
这种方式是定义指针来指向二维数组的某一行,定义方式如下:
1 | int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; |
2.4.3、指向整个数组的指针(数组指针方式)
这种方式是定义指针来指向整个数组,定义方式如下:
1 | int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}; |
3、指针和常量
3.1、指针常量
指针常量:const修饰的是常量,指向不能更改,指针对应的值可以更改
1 | int * const p //指针常量 |
3.2、常量指针
常量指针:const修饰的是指针,指针对应的值不能更改,指向能更改
1 | const int *p; |
4、指针和函数
4.1、函数指针
1、函数指针定义:函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,只不过这里是指向函数。
1 | int (*fun)(int x) //函数指针的定义 |
2、函数指针的赋值
1 | fun = &Function //函数指针的赋值方式1(这个用的多一点) |
3、函数指针的调用
1 | x = (*fun)(1,1); //函数指针的调用方式1 |
实例
1 |
|
用途:在C语言中,结构体不能直接包含函数。不过,你可以通过函数指针的方式将函数存储在结构体变量的成员中,从而在结构体对象中使用该函数
4.2、指针函数
1、指针函数定义:指针函数的落脚点是一个函数,这个函数的返回值是一个指针,与普通函数int function(int,int)
类似,只是返回的数据类型不一样而已。
1 | int *fun(int x) //指针函数的定义1 |
2、指针函数的初始化
1 | int *p=fun(2,3) |
3、实例:
1 |
|
5、指针和参数
将指针作为函数参数,形参与实参的区别(地址传递和值传递的区别,形参可以影响实参)
1 |
|
经过swap函数后,实参a和b的值已经发生了变化
6、指针和结构体
如果p是一个结构体指针,则可以使用p ->【成员】的方法访问结构体的成员
7、指针大小
32位系统下:sizeof(int *)=4,64位系统下,sizeof(int *)=8
8、
1、