Pointers and Linked Lists
Linked data structures(链表数据结构)
一些集合使用节点的链接序列来存储数据。
每个节点存储一个元素及一个指向其他节点的链接。
例子:集合(Set)、映射(Map)、链表(LinkedList)
优点:在任何位置添加/删除速度快;不需要移动、不需要调整大小。
缺点:需要额外的内存空间来存储链接。访问列表的某些部分较慢。
Structs(结构体)
结构体是一种数据类型,它可以包含多个成员变量。
结构体就是一个小型的类,它可以包含数据成员和函数成员。
但是一般用来存放数据,而不是用来定义行为。
例如我们定义一个名为 date 的结构体:
struct Date{
int month;
int day;
};
Memory addresses(内存地址)
内存地址是一个数字,它唯一地标识一个内存位置。
在 C++中,可以使用&
运算符来获取变量的内存地址。
十六进制表示法:内存地址以十六进制表示,以0x
开头。
例如,0x7fff0000
是一个常用的地址,表示系统的堆栈区。
有趣的是:结构体的内存地址和结构体变量的第一个成员的内存地址是一样的。而,第二个变量比前地址向前偏移了若干字节.
Pointers(指针)
type* name = address
指针是一个变量,它存储着另一个变量的内存地址。
引用是指针的简化版本,它只存储一个变量的内存地址。
指针可以指向任意类型的变量,包括结构体。
指针可以用来访问变量的值,也可以用来修改变量的值。
几种指针的变体:
- 空指针(null pointer): 指针变量没有指向任何内存地址。
如果你想输出一个*空指针,那么你的程序会崩溃.
- 未初始化指针(uninitialized pointer): 指针变量没有被初始化。
如果你试图使用一个未初始化的指针,那么你的程序也会崩溃.
int* p1 = nullptr; // 空指针
if(p1 == nullptr)// true
if(p1) // false
if(!p1) // true
- 野指针(dangling pointer): 指针变量指向一个已经被释放的内存地址。
Point to a struct(指向结构体):
type* name = new type(parameters);
符号->
用来访问结构体的成员变量。
struct Person{
string name;
int age;
};
int main(){
Person* p = new Person;
p->name = "John";
p->age = 25;
cout << p->name << " " << p->age << endl;
delete p;
return 0;
}
我们来进行一个比较:
// 1) non-pointer
Date d1;
d1.month = 7;
d1.day = 13;
// 2) pointer
Date* d2 = new Date();
d2->month = 7;
d2->day = 13;
很线性第一种语法更为简洁,有时我们会采用这种语法.
该问题和作用域有关,第一种在函数中定义的变量,其生命周期只在函数内,而在函数外,其生命周期则是整个程序的生命周期.
但是第二种就不会被销毁,直到程序结束.或是我们主动 delete
A list node structure(链表节点结构)
struct ListNode{
int date;
ListNode* next;
};
每一个链表节点都包含:
- 一个整数值(date)
- 一个指向下一个节点的指针(next)
你会发现,如果你将链表连起来,指针就可以连起来.就是可以如图所示