【Day 23】Pointer 指标

接下来要讲的是指标(pointer),其实之前在讲阵列的时候,就已经有出现过 pointer 的应用,现在我们要来真的说说什麽是 pointer!

Pointer 是一种可以储存 memory address 的变数,可以指向任何一种型态,不论 int、float。

其宣告方式为:

type pointed* pointer name;

常常与pointer搭配的还有&,我们称&为 address-of operator,可以用这个符号来取得指标指向的变数之地址。

其使用方式为:

pointer name = &variable name;

要注意的是,当赋予 pointer 一个 address 的时候,那个变数与指标的 type 要相同。

例如:

int a = 5;
int* aPtr = &a;

其中的aPtr就是指向a,存着a的 address,而aaPtr的型态皆为 int。

double b = 10.5;
double* bPtr = &b;

其中的bPtr就是指向b,存着b的 address,而bbPtr的型态皆为 double。

两个 pointer不能相加,但可相减。例如:

double a[3] = {10.5, 10.6, 10.7};
double* b = &a[0];
double* c = &a[2];

cout << c - b;	// 2

这个2代表bc差两格。

Address operators

所以到目前为止,整理一下:
&:address-of operator ->回传 variable’s address
*:dereference operator -> 回传 pointed variable

举例来说:

int a = 5;
a:5
&a:回传`a`的地址
int* aPtr = &a;
aPtr:存`a`的地址
&aPtr:回传’aPtr’的地址
*aPtr:回传`a`

其实有点像是逻辑问题,搞懂需要一点时间....

如果搞懂的话,这边再补充一下:

int a = 10;
int* ptr = &a;
*ptr = 5;

若程序码长这样,a的值就会变成 5。

Null pointers

宣告的时候,我们可以将一个指标初始化为nullptr,也就是他并没有指向任何东西:

int* ptr = nullptr;

此时若cout << *ptr,会发生 run-time error到情况!

接下来要说説传值的两种方法:
Call by reference
什麽是“reference”呢?其实就是一个变数的别名!

例如我们写

int &d = c;

就是宣告 d 是 c 的 reference,也就是说,d = 20 的话,c 就是 20。

但是不能写

int &d = 10;

Call by pointers
其实就是 call by address,举个例,我们写一个叫swap的函数,若将两数值传入,就能将其交换:

void swap(int *ptrA, int *ptrB) {
    int temp = *ptrA ; 
    *ptrA = *ptrB;
    *ptrB = temp;
}

int main() {

    int a = 1;
    int b = 0;

    cout << a << "," << b << "\n";		// 1, 0

    swap(&a, &b);	// 传入a, b的address进行交换

    cout << a << "," << b << "\n";	// 0, 1

    return 0;
}

输出後,我们可以看到ab值交换了,这是将ab传入的address进行交换,之後在main 里面利用&符号传入 address。

最後,要介绍前面就提过的动态阵列(dynamic memory allocation)。

Dynamic memory allocation

int* a = new int[5];

我们都知道这是宣告一长度为5的动态阵列,不过我到现在才知道,原来其中的new是代表:配一块空间并回传其 address。

Memory leak
在动态阵列中,且还在 run time 时,系统不会自己释放动态阵列的记忆体(若是固定的阵列就会),因为这个空间是没有名字的。

因此,为了避免 code 占太多记忆体空间,下面要写 delete statement,来手动释放记忆体空间:


int* a = new int[5];

// statements

delete [] a;

二维动态阵列
若我们要宣告一个 n X m 的二维阵列,里面各项都是 0:

int** array = new int*[n];
for (int i = 0; i < n; i++) {
    array[i] = new int[m];
    for (int j = 0; j < m; j++) {
	array[i][j] = 0;
    }
}

// statements

delete [] array;

最後也要记得加上 delete statement。

Pointer 的笔记就到此为止,对於 pointer 的概念我还是有点似懂非懂,希望再多练习几题题目後,我能更熟悉!


<<:  D21 - 「不断线的侏罗纪」:萃取 DNA

>>:  [前端暴龙机,Vue2.x 进化 Vue3 ] Day26. Vue3 Composition API 使用(二)

【Day29】清除轨迹 ─ Linux篇

哈罗~ 昨天介绍清除Windows Event log, 我们今天要介绍清除Linux的轨迹。 清除...

[番外] 来个 Weather App (序)

前言 遥想(?) N 年前看着官方文件认识 Angular 时,充满回忆的 Heros 范例!  认...

[Day-17] R语言 - 分群应用(一) GMM数值补值-下 ( Fill.NA with GMM in R.Studio )

您的订阅是我制作影片的动力 订阅点这里~ 影片程序码 (延续昨天) #均值 vs 列入各群权重 fi...

Rails has_many

has_many 的设定 class_name 可以变更关联的类别名称,例如以下新增了paid_at...

a连结标签基础方法

<a href="https://www.w3.org/" target=...