接下来要讲的是指标(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,而a
、aPtr
的型态皆为 int。
double b = 10.5;
double* bPtr = &b;
其中的bPtr
就是指向b
,存着b
的 address,而b
、bPtr
的型态皆为 double。
两个 pointer不能相加,但可相减。例如:
double a[3] = {10.5, 10.6, 10.7};
double* b = &a[0];
double* c = &a[2];
cout << c - b; // 2
这个2
代表b
、c
差两格。
所以到目前为止,整理一下:
&
: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。
宣告的时候,我们可以将一个指标初始化为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;
}
输出後,我们可以看到a
与b
值交换了,这是将a
和b
传入的address进行交换,之後在main 里面利用&
符号传入 address。
最後,要介绍前面就提过的动态阵列(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 的概念我还是有点似懂非懂,希望再多练习几题题目後,我能更熟悉!
>>: [前端暴龙机,Vue2.x 进化 Vue3 ] Day26. Vue3 Composition API 使用(二)
哈罗~ 昨天介绍清除Windows Event log, 我们今天要介绍清除Linux的轨迹。 清除...
前言 遥想(?) N 年前看着官方文件认识 Angular 时,充满回忆的 Heros 范例! 认...
您的订阅是我制作影片的动力 订阅点这里~ 影片程序码 (延续昨天) #均值 vs 列入各群权重 fi...
has_many 的设定 class_name 可以变更关联的类别名称,例如以下新增了paid_at...
<a href="https://www.w3.org/" target=...