1. 程式人生 > >C++陣列與指標

C++陣列與指標

一、一維陣列

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);