指针 …

来源:互联网 发布:模糊控制算法 matlab 编辑:程序博客网 时间:2024/06/06 03:42

Treap

Q:为什么 root 是指针类型的呢?(我们可以根据 root 来对应所有节点)
A:
首先,我们考虑 Treap 的结构,很显然只需要记录根节点就可以表示整棵树了
所以存根节点的指针就可以。
注意到我们没有用一个数组来存下所有的节点
举个栗子,我们有一个数组 a[N],我们把一个很大的结构丢进去,我们想存下来一个东西,使得我们能访问到我们丢进去的那个值,我们要存的就是下标。
现在这个根节点不是被丢进某个数组里的,而是被丢进整个内存里的,所以就存下来指针。
我们把内存看成一个大数组的话,指针相当于的下标。

我们的 root 不是数组的一部分,那它是怎么来的呢
它是通过 new 得到的,new 这个运算符表示申请一块内存,并在这块内存上构造一个对象,返回它的指针
我们不需要知道这个对象在哪 —— 只需要有指针来找到它就好了

每个节点都是指向 Node 类型的指针


首先,指针是一种类型,它储存一个内存地址,它的本质是一个 long 类型的整数
数据在内存中是连续存储
就是一条线下去,一个一维的结构,就像数组一样
理解内存的结构是学习指针的基础


int p && int *p 的区别
第一个,p 是一个变量,存一个整数
第二个,p 是一个变量,存一个指针,这个指针指向一个 int
【整数】和【指向整数的指针】是两种类型

Node p && Node *p 相似


* 这个符号叫解引用,后跟一个指针,表示这个指针指向的值。
定义 一个指针变量 —— int *p;
指针所指向的类型 —— int
指针所指向的值 —— *p
指针的值(即指针所指向的内存区) —— p
指针本身所占据的内存区 —— &p


基本操作

int *p = NULL; NULL 是特殊的地址 0
int *p = new(int); 申请一个空间给 p,*p 的值不确定

int a[10]; int *p = a; p ++;
这里直接把指针 p 赋值为数组 a,表示让指针 p 指向数组 a 的首地址,也就是和 int *p = a[0] 是等价的
这里,数组名 a 和指针 p 在 几乎所有 情况下都是等价的
p ++; 不是 p 的值(地址) + 1,而是根据类型 int 增加 sizeof(int) ,刚好“跳过”一个整数的区间,达到下一个整数。
记住,指针的运算是以对象为单位的,不是以字节为单位的

·*p + 3*(p + 3) 是不同的。如果 p = &a*(p + 3) 相当于 a[3]*p + 3 相当于 a[0] + 3

两个指针的差不是地址的差,而是中间“类型”单位的差,即中间的“元素”个数。

一个结构体变量的指针就是该变量所占据的内存段的起始位置。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。

struct Node { int a, b; }; Node v; 这里 v 是结构体(类)的实例,叫做对象
Node *p = &v; 指向对象的指针
或者直接 struct Node { int a, b; } *p;

(*p).a p->a
箭头运算符,表示访问这个指针指向的结构体的成员
(*p).f(); p->f();
或者成员函数
(以上两种写法都等价

Node *p = new Node; 这叫 new 一个对象
就是申请一块内存,大小为 sizeof(Node),然后将在这个位置放一个 Node 对象,内存的地址赋值给 p

struct Node { int a, b; Node(int a, int b) : a(a), b(b) {} };
int main { Node *p = new Node(1, 2); }
构造函数
这样所有 Node 类型创建时都会调用一次构造函数,: a(a), b(b) 这是构造函数特有的语法,表示把 a 赋值为参数中的 a,b 赋值为参数中的 b
这里括号里 a 和 b 可以是任何 类型与对应成员变量相同的表达式

原创粉丝点击