CH8 Pointers
本文為 2021-Fall 學期旁聽台大資管系孔令傑教授開授的 Programming Design 所記錄的課程筆記。課程內容程式碼可以參閱我的 Github repo: C++ Programming-Design-2021-Fall
Basics of pointers
pointer是一種儲存記憶體位置的變數,Array也是儲存儲存記憶體位置的一種變數,但Array存的是一排變數中的第一個變數的記憶體位置。
-
To declare a pointer, use
*type pointed* pointer name;
-
Exp:
int *ptrInt; 儲存int變數記憶體位置的指標
Pointer assignment
We use the address-of operator & to obtain a variable’s address(取址)
pointer name = &variable name
Exp:
int a = 5;
int* ptr = &a;
Address operators
&: The address-of operator. It returns a variable’s address. (變數->變數的位址)*: The dereference operator. It returns the pointed variable.(指標->被指到的變數)
Exp:
int a = 10;
int* p1 = &a;
cout << "value of a = " << a << "\n"; // 10
cout << "value of p1 = " << p1 << "\n"; // 0x123450
cout << "address of a = " << &a << "\n"; // 0x123450
cout << "address of p1 = " << &p1 << "\n"; // 0x543210
cout << "value of the variable pointed by p1 = " << *p1 << "\n"; // 10
-
&returns avariable’s address.- We cannot use
&100,&(a++) - We can only perform
&on a variable. - We cannot assign a value to
&x(&xis a value!).
- We cannot use
-
*returns the pointed variable.- We can perform
*on a pointer variable. - We cannot perform
*on a usual variable.
- We can perform
-
&and*cancel each other.// if x is a variable
*&x == x
// if x is a pointer
&*x == x
Null pointers
If we dereference a pointers of unknown value, the outcome is unpredictable
int* ptr;
cout << *ptr; // ?
A pointer pointing to nothing should be assigned nullptr, NULL, or 0.(讓程式保證會出錯)
By using nullptr (instead of 0), everyone knows the variable must be a
pointer, and you are not talking about a number or character.
int* p2 = nullptr;
cout << "value of p2 = " << p2 << "\n"; // 0
cout << "address of p2 = " << &p2 << "\n"; // 0x123450
cout << "the variable pointed by p2 = " << *p2 << "\n"; // run-time error!
- When we use
*indeclaringa pointer, that*is not a dereference operator. - When we use
&indeclaringa reference, that&is not an address-of operator.
int* p, q; // p is int*, q is int
int *p, *q; // two pointers
int* p, *q; // two pointers
int* p, * q; // two pointers
Using pointers in functions
References and pointers
When invoking a function and passing parameters, the default scheme is to “call by value” (or “pass by value”)
- function會宣告自己的local variable,傳入的arguments values會被複製成local variable的initial values
當我們想要改變傳入的變數本身時,可以用“call by reference” or “call by pointer.”
References
-
A
referenceis a variable’salias. (變數的別名) -
int& d = cis to declare d as c’s reference- 這跟
address-of operator 的 &是不一樣的
- 這跟
Call by reference
Instead of declaring a usual local variable as a parameter, declare a reference variable. Thus we can call by reference and modify our arguments’ values.
原本x, y是兩個local value,現在變成兩個local reference。
通常reference只有call by reference的時候才會用。
void swap(int& x, int& y)
{
cout << &x << "\n";
int temp = x;
x = y;
y = temp;
}
Call by pointers
- Declare a pointer variable as a parameter.
- Pass a pointer variable or an address (e.g., returned by &) at invocation.
You can view calling by reference as a special tool made by using pointers.
void swap(int* ptrA, int* ptrB)
{
int temp = *ptrA;
*ptrA = *ptrB;
*ptrB = temp;
}
Returning a pointer
May a function return a pointer? Yes!
Why returning an address?
- With the address, we also know the value.
- If we only have the value, we do not know its address (and index).
- To obtain the index, we need
pointer arithmetic.
Dynamic memory allocation (DMA)
The operator new allocates a memory space and returns the address.(請求空間,並且回傳空間位址)
- In C, we use a different keyword melloc.
int* a = new int //makes a store the address of the 4-byte space.
int* a = new int(5) //makes the space contain 5 as the value.
int* a = new int[5] //allocates 20 bytes (for 5 integers).
- 動態宣告陣列就不能用
{}來初始化陣列。 - 動態宣告出來的空間是沒有變數名字的,只有空間與位址,因此必須使用指標。