C++指针和结构体的浅显认知
因为数据结构中会设计到C++的一些基本指针操作,在进行算法的时候或多或少链表,哈希表,二叉树也会涉及一些相应的指针操作,而本人对于C++这么博大精深的语言体系又只有浅浅的一些了解,所以将这些数据结构涉及到的底层的指针做一个简单的知识梳理,方便以后在理解算法的时候尽量少花点笔墨放在基础语法知识上。
1. 指针
1.1 指针的意义
对于C++程序的一个数据,我们一般需要做到关注他如下的三个部分:
data
: 数据的内容address
: 数据的地址(存储位置)dtype
: 数据的类型
那么平时我们在定义一个变量的时候,一般只会定义他的数据类型和数据的内容(int a = 5
),那么他的地址又指的是什么呢?
我们可以这样去理解:代码中出现的变量存放在主机里存储器中的一个个存储单元中,每一个存储单元都有一个地址。换而言之,我们作为程序员更多的会去关注字面值的内容,而地址更像是计算机底层程序自己考虑的。当我们定义完一个变量要去调用他的时候,我们需要进行的操作仅仅是运用运算符=
, 而计算机底层则需要对应的去寻找这个变量的地址,再将其调用出来。指针像是一种工具,模拟了这种过程,我们可以通过指针直接知道其指向的地址,也可以获取他指向的值。
用听起来厉害一点的话来讲就是:**指针可以精准控制了内存中的地址,从而高效率的传递和更改数据。**
1.2 指针和引用
& : 取地址运算符
针对于变量,& + 变量名称
表示的是该变量在内存中的地址。1
2int a = 10;
cout<< &a << endl;输出的结果是:
004FFDE0
*: 间接运算符
针对的是指针,* + 指针名称
表示引用该指针指向的值。*p
表示取p指针指向地址的值int* p
表示p的数据类型是指向int类型的指针
1 | int a = 10; |
输出的结果是:004FFDE0
; 10
某种意义上,int* p =int * p ; 但是他们表示的含义完全不同。左值定义了一个指针,右值定义了一个变量。但是他们最终的结果是相等的。但是要注意的是,在程序编译器中,int* p1, p2指的是定义一个p1为指向int类型的指针,p2为int类型的变量。
2. 结构体
2.1 结构体的定义
类似于类,可以表示一个需要用各种数据类型表示的数据集体,如学生有他的姓名年龄,那么此时就需要进行结构体的定义,将学生封装为char
类型的姓名和包括int
类型的年龄。
具体在C++中表达如下:
1 | struct Student { |
他在数据结构中用处十分之大,比如链表中需要定义data
和next
,又比如在二叉树中需要定义双亲和头节点等。都需要用到结构体。
2.2 结构体的初始化
结构体的初始化有如下两种方式:
- 通过直接定义初始化
struct Student s1;
:表示构造出一个数据类型为Student
的学生变量s1
。
注意:此类型构造需要确定结构体定义的位置,如果在同一个方法内可以调用,在不同方法内不能调用。如果结构体被设置为全局则每个方法都可以引用。 - 在构造时完成初始化这样就表示
1
2
3
4struct Student {
char[20] name;
int age;
},s1,s2s1,s2
两个变量是Student
类型,并且再后续无需再定义就可以直接使用,在构造的时候就完成了初始化。
2.3 typedef关键字
typedef
关键字可以简化结构体变量的初始化,通过该关键字可以给结构体起别名,从而直接实现通过别名来进行调用。
1 | typedef struct Student { |
其中,S为结构体的别名,s1为结构体类型的变量。
2.4 结构体成员变量的调用
通过.
的形式调用。
如s1.age
表示第一名学生的年龄;s2.name
表示第二名学生的姓名。
3. 指向结构体的指针
此时结构体可以视为数据类型,所以指针定义写法和原先指针写法差别不大。struct Student* p= &s1
指向结构体Student的指针p(左值),指向(=)数据类型为Student的s1的地址(右值)。
- 指针访问结构体成员变量
用箭头函数:p->name
无需带变量名,因为p指向了地址,知道需要获取哪个变量的值
本篇只针对于目前个人认为可能会在数据结构中用到的知识点,对于真正的指针和结构体的知识知识九牛一毛不尽完整,而对于有关于理解数据结构语法有帮助的知识点,如有遗漏或者后续想到的,接下来再来进行补充。