C++ premier Plus書之—C++指標,陣列,指標算術
阿新 • • 發佈:2018-11-28
首先看一下c++裡的動態建立陣列
int* p_array = new int[10];
new運算子返回第一個元素的地址, 也就是會把陣列的第一個元素的地址賦給指標p_array
當使用完new分配的記憶體時, 應該使用delete來釋放他們:
delete[] p_array;
注意new分配記憶體的時候如果是[], delete的時候也需要加[]
動態建立陣列相比與靜態建立陣列的區別是: 動態建立陣列只有在需要的時候才會去真正申請記憶體空間
看一個簡單的例子:
#include "iostream" using namespace std; int main() { // 通過new來分配的記憶體時動態載入的, double* p_double = new double[3]; // c++裡可以將指標當做陣列的名稱一樣使用, 來訪問陣列中的元素 // 這是因為c++裡陣列本身就是用指標來處理的 p_double[0] = 1.1; p_double[1] = 1.2; p_double[2] = 1.3; cout << "p_double[1] = " << p_double[1] << endl; // 下面的程式碼展示了指標和陣列名的不同 // 可以對指標進行加減操作, 相當於將指標向後/向前移動 // 這行的+1 就相當於指標指向了陣列的第二個元素 // +1增加的量, 相當於指標指向的型別的位元組數 p_double = p_double + 1; cout << "Now p_double[0] = " << p_double[0] << endl; cout << "Now p_double[1] = " << p_double[1] << endl; // 之所以要-1後再釋放陣列空間, 是因為new的時候是3 // 所以釋放的時候也需要釋放完全 p_double = p_double - 1; delete [] p_double; return 0; }
程式的執行結果:
c++允許對指標和整數相加, +1 的結果相當於在原來的基礎上加上指標指向的物件所佔的位元組數
再看一個數組和指標相互關係的例子:
#include "iostream" using namespace std; int main(){ double d_arr[] = {100.0, 200.0, 300.0}; short s_arr[] = {1, 2, 3}; // 兩種將陣列的首地址賦值給指標變數的方式 // 1.將陣列名賦值給指標變數 double* p_d_arr = d_arr; // 2.將陣列的第一個元素的首地址賦值給指標變數 short* p_s_arr = &s_arr[0]; cout << "p_d_arr = " << p_d_arr << ", *p_d_arr = " << *p_d_arr << endl; // 指標向後移動了8個位元組, 也就是指向了陣列的第二個元素 p_d_arr = p_d_arr + 1; cout << "add 1 to the p_d_arr pointer : " << endl; cout << "p_d_arr = " << p_d_arr << ", *p_d_arr = " << *p_d_arr << endl; cout << "p_s_arr = " << p_s_arr << ", *p_s_arr = " << *p_s_arr << endl; p_s_arr = p_s_arr + 1; cout << "add 1 to the p_s_arr pointer : " << endl; cout << "p_s_arr = " << p_s_arr << ", *p_s_arr = " << *p_s_arr << endl; cout << "*********************************" << endl; cout << "s_arr[0] = " << s_arr[0] << ", s_arr[1] = " << s_arr[1] << endl; cout << "*s_arr = " << *s_arr << ", *(s_arr + 1) = " << *(s_arr + 1) << endl; cout << "size of d_arr = " << sizeof(d_arr) << endl; cout << "sizeof(p_d_arr) = " << sizeof(p_d_arr) << endl; }
執行結果如下:
從程式的執行結果可以看出:
從執行結果可以看出:
- 一般情況下c++把陣列名解釋為陣列的第一個元素的地址(10~12行程式碼)
- 如果arr是陣列名, 那麼arr[i] 被解釋為*(arr + 1)
- p_d_arr = p_d_arr + 1執行情況就是將指標移動到陣列的下一個元素的地址(在這裡是向後移動了8個位元組)
- 還可以看出s_arr [1] 等價於*( s_arr + 1), 也就是c++在遇到s_arr[1]的時候會相當於做了*(s_arr + 1)這種操作.
- 指標和陣列名的區別就是陣列名是常量, 而指標是可以修改指標的值的(也就是可以對指標進行加減等操作), 另外對陣列名進行sizeof得到的是陣列的長度, 而對指標進行sizeof得到的是指標的長度
再看一個更為詳細的陣列和指標的相互關係的demo:
#include "iostream"
using namespace std;
int main(){
short s_arr[10] = {1, 2, 3};
// 由於s_arr是陣列名,也就是相當於指標, 指向陣列的首地址
cout << s_arr << endl;
// 輸出陣列的第一個元素
cout << s_arr[0] << endl;
// s_arr相當於指標, *指標 也就是指標指向的地址裡的元素
cout << *s_arr << endl;
// 陣列第一個元素的地址
cout << &s_arr[0] << endl;
// 由於s_arr相當於指標所以&s_arr 相當於首元素的地址
cout << &s_arr << endl;
cout << "************" << endl;
// 由於s_arr相當於指標, 而又指向的是short型陣列
// 因此+1相當於向後移動了兩個位元組
cout << "s_arr + 1 = " << s_arr + 1 << endl;
// &s_arr指向的是一個20個位元組記憶體塊的地址
// 因此&s_arr + 1, 相當於加了20個位元組的地址
cout << "&s_arr + 1 = " << &s_arr + 1 << endl;
cout << "*************" << endl;
// 和&s_arr類似, 也就是p_short這個指標指向了一個20個位元組記憶體塊的地址
short (*p_short)[10] = &s_arr;
// p_short的地址和s_arr一樣
cout << "p_short = " << p_short << endl;
// 輸出s_arr地址
cout << "&s_arr = " << &s_arr << endl;
// 輸出s_arr首元素的地址
cout << "&s_arr[0] = " << &s_arr[0] << endl;
// 輸出s_arr首元素
cout << "s_arr[0] = " << s_arr[0] << endl;
// 由於p_short指向的是&s_arr, 因此*p_short 就和 s_arr一樣
cout << "(*p_short)[0] = " << (*p_short)[0] << endl;
cout << "p_short + 1" << p_short + 1 << endl;
}
執行的結果為:
注意:陣列名被解釋為陣列的第一個元素的地址, 而對陣列名應用地址運算子(&)的時候, 得到的是整個陣列的地址.
看上面的執行結果, 雖然說s_arr和&s_arr的地址相同, 但是代表的含義不同, s_arr代表的是陣列首元素的地址, 而&s_arr代表的是一個20位元組記憶體塊的地址, 所以&s_arr + 1 實際加的是20個位元組