C++陣列與指標
阿新 • • 發佈:2018-12-18
一、一維陣列
1.1宣告並初始化一維陣列
- type 陣列名[整型常量表達式]={陣列元素}
- 宣告時可以不指明陣列長度,編譯器將根據初始化列表的長度作為陣列長度
- 若初始化列表的初始值數少於元素數目,則其餘元素均初始化為0
1.2使用一維陣列
- 陣列名[下標],從0開始,不能越界訪問,否則報錯
- 陣列不能進行整體賦值,整體比較以及char除外的整體I/O操作
- 陣列名是陣列首元素的記憶體地址,即陣列名是一個地址常量
- 陣列作為函式引數時,要將陣列名和陣列長度作為實參
1.3遍歷一維陣列
- for迴圈
二、二維陣列
2.1宣告並初始化二維陣列
- type 陣列名[整型常量表達式][整型常量表達式]={{陣列元素},{},..}
- 宣告時可以不指定行數(第一個)
- 陣列在記憶體中一行一行存放
2.2使用二維陣列
- 陣列名[下標][下標]
- 陣列作為函式引數時,要將陣列名和行數作為實參;被呼叫函式的第一個形參必須給出第二維的長度(即列數),且該列數需與實參的列數一致,第二個形參接收行數
2.3遍歷二維陣列
- for迴圈內再巢狀一個for迴圈
三、指標
3.1指標常量(指標型別的常量,即指標本身就是一個常量)
- &變數名/常量名,代表存放該變數/常量的記憶體地址
- 陣列名,數值上arr=&arr[0]
//指向變數XX的指標常量 //可以通過*ptr修改var1,*ptr也會隨著var1的改變而改變,ptr不可以指向其他變數/常量 int var1 = 10; int var2 = 20; const int var3 = 30; int* const ptr = &var1; *ptr = 40; //valid,now var1=40 var1 = 50; //valid,now *ptr=50 ptr = &var2; //invalid ptr = &var3; //invalid
//指向常量XX的指標常量
//不可以通過*ptr修改var1,var1本身也是常量,ptr不可以指向其他變數/常量
const int var1 = 10;
int var2 = 20;
const int var3 = 30;
const int* const ptr = &var1;
*ptr = 40; //invalid
var1 = 50; //invalid
ptr = &var2; //invalid
ptr = &var3; //invalid
3.2指標變數(指標型別的變數,即指標本身是一個變數)
int* ptr; //基資料型別* 指標變數名;強調ptr是一個指向int的指標(複合型別) int *ptr; //基資料型別 *指標變數名;強調*ptr是一個int型別的值,常用於定義多個指標變數
//指向XX型變數的指標變數
//可以通過*ptr修改var1,*ptr也會隨著var1的改變而改變,ptr可以指向其他變數,ptr不可以指向其他常量
int var1 = 10;
int var2 = 20;
const int var3 = 30;
int* ptr = &var1;
*ptr = 40; //valid,now var1=40
var1 = 50; //valid,now *ptr=50
ptr = &var2; //valid
ptr = &var3; //invalid
//指向XX型常量的指標變數
//不可以通過*ptr修改var1,var1本身也是常量,ptr可以指向其他變數/常量
const int var1 = 10;
int var2 = 20;
const int var3 = 30;
const int* ptr = &var1;
*ptr = 40; //invalid
var = 50; //invalid
ptr = &var2; //valid
ptr = &var3; //valid
3.3void* 型別指標
- malloc得到的指標是void型別
3.4解引用操作符*
- 一定要先為指標變數賦值再使用
- *指標變數就是該指標指向的變數/常量
3.5從編譯器角度
- 使用變數名是間接訪問indirect access
- 使用指標是直接訪問direct access
3.6指標運算
- 自加、自減
- 做差:ptrdiff_t diff=p2-p1; // 指標的減法可以計算兩個指標之間相隔的元素個數,所得結果是一個 ptrdiff_t 型別
- 比較:== != > >= < <=
3.7指標與函式
- 指標變數作為函式引數,是使被調函式獲得某變數的地址,從而使用這個地址訪問這個變數
- 引用變數作為函式引數,形參和實參是同一個變數,形參是實參的別名
3.8指標與一維陣列
- 陣列名是指標常量,可以賦值給指標變數,此時指標變數可以代替陣列名訪問陣列。二者均可用下標法:arr[i]和指標法:*(arr+i)
- 陣列作為函式引數時,形參是指標變數
- 指標本身並沒有指出陣列的長度,所以必要時還要增加引數傳入陣列的長度
- 對陣列名使用sizeof運算子,得到的是陣列的長度;對指標應用sizeof得到的是指標的長度,即使指標指向的是一個數組
short tell[10];
cout << tell << endl;
cout << &tell << endl;
cout << &tell + 1 << endl;
//兩個輸出地址相同,但是&tell[0](即tell)是一個2位元組的記憶體塊的地址,
//而&tell是一個20位元組記憶體塊的地址,所以tell+1將地址加2,而&tell+1是將地址加20;
3.9指標與二維陣列
- 二維陣列名是一個指向一維陣列的指標常量,指向整個二維陣列的地址,它的值正好等於一維陣列arr2[0],即第0行的地址
- 下標法arr[i][j],指標法*(*(arr+i)+j)
- 傳遞二維陣列時,列數通過指標型別確定,如void print(int arr[][5],int row)
//type (*p)[col] 定義p為指向“由col個type型元素組成的一維陣列”的指標
short (*p)[10] = &tell;
//pas指向包含10個元素的short陣列
//pas的型別為short (*)[10]
//*pas與tell是等價的
int *arr[4]; //宣告一個由4個指向int的指標組成的陣列
int (*arr)[4]; //宣告一個指向由4個int組成的陣列的指標
//指標與二維陣列
int arrt[2][3] = { {1,2,3},{4,5,6} };
cout << "arrt=" << arrt << endl; //二位陣列名,
cout << "arrt[0]=" << arrt[0] << endl; //第0行元素第0列的地址
cout << "*(arrt+0)=" << *(arrt + 0) << endl; //第0行元素第0列的地址
cout << "*arrt=" << *arrt << endl; //第0行元素第0列的地址
cout << "arrt+1=" << arrt + 1 << endl; //第一行的地址
cout << "&arrt[1]=" << &arrt[1] << endl; //第一行的地址
cout << "arrt[1]=" << arrt[1] << endl; //arr2[1][0]的地址
cout << "*(arrt+1)=" << *(arrt + 1) << endl; //arr2[1][0]的地址
cout << "arrt[1]+2=" << arrt[1] + 2 << endl; //arr2[1][2]的地址
cout << "*(arrt+1)+2=" << *(arrt + 1) + 2 << endl; //arr2[1][2]的地址
cout << "&arrt[1][2]=" << &arrt[1][2] << endl; //arr2[1][2]的地址
cout << "*(arrt[1]+2)=" << *(arrt[1] + 2) << endl; //arr2[1][2]
cout << "*(*(arrt+1)+2)=" << *(*(arrt + 1) + 2) << endl; //arr2[1][2]
cout << "arrt[1][2]=" << arrt[1][2] << endl; //arr2[1][2]
3.10建立動態陣列
//malloc和free
指標變數=(type*)malloc(sizeof(type)*length);
free(指標變數);
//new和delete
type *arr; //一維陣列
arr=new type[length];
delete []arr;
type **arr; //二維陣列
arr=new type*[col];
for(i=0;i<col;i++)
arr[i]=new type[row];
for(int i=0;i<col;i++)
delete []arr[i];
delete []arr;
3.11指標與結構
structname *pointer = &a_struct;
pointer->member = (*pointer).member = a_struct.member;
structname *pointer = new structname;
delete pointer;
3.12指標與物件
classname *pointer = &object;
pointer->member = (*pointer).member = object.member;
classname *pointer=new classname(arguments);
delete pointer;
3.13函式指標
- !=返回指標的函式
- type *函式名(形參列表);返回指向type型的指標
- 函式名是一個指標常量,可以賦給指標變數,然後指標變數可以代替函式名被呼叫
- type (*指標變數)(形參列表);type就是指標變數要指向的函式的返回值型別,形參列表也要和指標變數指向的函式的形參列表一致,可以沒有形參名字
bool min(int a,int b);
bool (*p)(int,int);
p = min;
p(3,4) = (*p)(3,4) = min(3,4);