C++指针类型介绍
1 int i; //定義一個int型的變量
  2 int *p; //定義一個指向int的指針
  3 int a[n]; //定義一個數組
  4 int *p[n]; //定義一個指針數組
  5 int (*p)[n]; //定義一個數組指針
  6 int f(); //聲明一個返回值為int的函數
  7 int *p(); //聲明一個返回值為int*的函數
  8 int (*p)(); //定義一個函數指針
  9 int **p; //定義一個指向int的指針的指針
  &引用運算符:
  1.引用只是變量的別名,而不是指向變量的指針(區(qū)別于取址運算符"&")不占內存空間,對變量引用的改變其相應的變量也會改變。
  2.不能對引用使用指針間接運算符“*”進行復引用操作
  3.引用必須在聲明時初始化 int &c = count;(c是count的別名)
  指針的算術操作
  和整數的加法,減法,自身的增量、減量
  指針增量后指向下一個與指針基類同型的元素,增減單位是所指類型的長度。
  同類型直接賦值,異類型要進行轉換。
  強制轉換:可以把表達式結果硬性轉換為指定類型
  char * p;(int *)p 把p強制轉換為int型,記住轉換過程中要注意兩個類型的大小,大轉小時可能會有數據丟失(如int到double)
  涉及void *的:
  c 中void *類型可賦值給任何類型的指針,反之亦然
  c++ 中都需要強制轉換
  void * 可似為無窮大能接納任何類型賦值,反之不行int * p =9;void * t= p(正確);p=t(錯誤)
  const 是“最靠近”為原則
  指向整數常量的指針:const int * p;它所指向的值只讀不能被修改 *p = 4(錯誤),p = 5(正確)
  指向一個整數的常量指針:int * const p;不允許修改指針變量的值,*p = 5 (正確),p = 5 (錯誤)
  指針優(yōu)點:
  1.為函數提供修改調用變元的手段;
  2.支持C++動態(tài)分配子程序
  3.可以改善某些子程序的效率
  4.為動態(tài)數據結構(如二叉樹、鏈表)提供支持
  注:指針為程序引入了一層間接性,可以操控指針而不直接操控對象。
  1.可操控指針內含的地址也可操控指針所指的對象2.指針可能并不指向任何對象,寫*pi時,可能會使程序在執(zhí)行期錯誤,如尋址到某個對象,則提領操作,不指向任何對象,會出錯,所以在提領前先確定它的確指向某對象。
  一個未指向任何對象的指針,內含地址為0,有時稱為null指針,assert (p != 0)可檢測是否分配成功。也可用if (pi),只有在pi含非零值時,才為true.
  引用和指針的比較(1)引用在創(chuàng)建的同時必須初始化,即引用到一個有效的對象;而指針在定義的時候不必初始化,可以在定義后面的任何地方重新賦值。
  (2)不存在NULL引用,引用必須與合法的存儲單元關聯;而指針則可以是NULL.
  (3)引用一旦被初始化為指向一個對象,它就不能被改變?yōu)榱硪粋€對象的引用;而指針在任何時候都可以改變?yōu)橹赶蛄硪粋€對象。給引用賦值并不是改變它和原始對象的綁定關系。
  (4)引用的創(chuàng)建和銷毀并不會調用類的拷貝構造函數
  (5)在語言層面,引用的用法和對象一樣;在二進制層面,引用一般都是通過指針來實現的,只不過編譯器幫我們完成了轉換。
  總的來說:引用既具有指針的效率,又具有變量使用的方便性和直觀性。 
C++數組速學
1.一維數組的定義與初始化
1.1定義一維數組
int a[3];
該定義表示一個整型數組,共有3個元素,下標分別為[0],[1],[2]。
1.2一維數組初始化
可以用下面幾種方式進行初始化。
①在定義數組時分別對數組元素賦初值。
int a[3]={0,1,2};
②只給一部分元素賦值。
int a[3]={0,1};
這表示只給前面兩個元素賦初值,后面的元素值默認為0。
③在對全部數組元素賦初值時,可以不指定數組長度。
int a[3]={0,1,2};
可以寫成
int a[]={0,1,2};
在第二種寫法中,花括號中有3個元素,系統(tǒng)就會據此自動定義a數組的長度為3。但若被定義的數組長度與提供初值的個數不相同,則數組長度不能省略。
2.二維數組的定義與初始化
2.1定義二維數組
int a[3][4];
改定義表示一個3x4(3行4列)的整型數組。可以把該二維數組看作:
|---a[0]:a[0][0],a[0][1],a[0][2],a[0][3]
a |--a[1] :a[1][0],a[1][1],a[1][2],a[1][3]
|--a[2] :a[2][0],a[2][1],a[2][2],a[2][3]
C++中,二維數組種元素排列的順序是:按行存放,即在內存中先順序存放第一行的元素,在存放第二行元素,依次往下。
2.2二維數組初始化
可以用下面幾種方式進行初始化。
①分行給二維數組賦初值。
int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}};
②將所有數據寫在一個花括號內,按數組排列的順序對各元素賦初值。
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
③只對部分元素賦初值。
int a[3][4]={{1},{2},{4}};
1 0 0 0
2 0 0 0
4 0 0 0
int a[3][4]={{1},{0,2},{0,0,4}};
1 0 0 0
0 2 0 0
0 0 4 0
int a[3][4]={{1},{3,2}};
1 0 0 0
3 2 0 0
0 0 0 0
int a[3][4]={{1},{},{9}};
1 0 0 0
0 0 0 0
9 0 0 0
④如果對全部元素賦初值,則定義數組時對第一維長度可以不指定,但第二維長度必須指定。
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
可以寫成
int a[][4]={0,1,2,3,4,5,6,7,8,9,10,11};
在定義時也可以對部分元素賦初值而省略第一維的長度,但應分行賦初值。
int a[][4]={{0,0,1},{},{0,9}};
0 0 1 0
0 0 0 0
0 9 0 0
3.用數組名作函數參數
3.1一維數組名作函數參數
數組名代表數組首元素的地址,并不代表數組中的全部元素。因此用數組名作函數參數時,是將實參數組首元素的地址傳遞給形參。形參可以是數組名,也可以是指針變量,它們用來接收實參傳來的地址。如果形參是數組名,它代表的是形參數組首元素的地址。
在調用函數時,將實參數組首元素的地址傳遞給形參數組名。這樣,實參數組和形參數組共占同一段內存單元。形參數組中各元素的值如果發(fā)生變化就意味著實參數組元素的值發(fā)生變化。這一點區(qū)別于變量作函數參數的情況。在變量作函數參數時,只能將實參變量的值傳遞給形參變量,在調用函數過程中如果改變了形參的值,對實參沒有影響,即實參的值不因形參的值的改變而改變。
實際上,聲明形參數組并不意味著真正建立一個包含若干元素的數組,在調用函數時也不對它分配內存單元,只是用array[]這樣的形式表示array是一維數組名,以接受實參傳來的地址。因此array[]中方括號內的數值并無實際作用,編譯系統(tǒng)對一維數組方括號內的內容不予處理。函數定義中的形參數組可以寫元素個數,也可以不寫。
以下幾種寫法都是正確的。
void select_sort(int array[10],int n){…}
void select_sort(int array[],int n){…}
void select_sort(int array[5],int n){…}
C++實際上只把形參數組名作為一個指針變量來處理,用來接收從實參傳過來的地址。
3.2二維數組名作函數參數
如果是二維數組名作為實參和形參,在對形參數組聲明時,必須指定第二維(列)的大小,且應與實參的第二維的大小相同。第一維的大小可以指定,也可以不指定。
下面兩種寫法都是正確的。
void max_value(int array[3][4]{…}
void max_value(int array[][4]){…}
不能把第二維的大小省略是因為,二維數組是由若干個一維數組組成的,在內存中數組是按行存放的,因此在定義二維數組時必須指定列數。假如一個二維數組有12個元素,可以是2x6,3x4,4x3,等不同的形式,如果指定了列數有4,則只有一種形式3x4。
形參數組的列(第二維)定義必須與實參數組的列(第二維)定義相同,但行(第一維)定義可以不同。
//實參
int array[3][4]
//形參
int array[3][4]
int array[8][4]
4.字符數組
4.1字符數組的定義與初始化
可以這樣定義:
char c[10];
c[0]='I';c[1]=' ';c[2]='a';c[3]='m';c[4]=' ';
c[5]='h';c[6]='a';c[7]='p';c[8]='p';c[9]='y';
也可以:
char c1[10]={'I',' ','a','m',' ','h','a','p','p','y'};
如果花括號提供的初始個數(即字符個數)大于數組長度,則按語法錯誤處理。如果初值個數小于數組長度,則只將這些字符賦給數組中前面的元素,其余的元素自動定為空字符(即’’)。
如果提供的初值個數與預定的數組長度相同,在定義時可以省略數組長度,系統(tǒng)會自動根據初值個數確定數組長度。如,
char c1[]={'I',' ','a','m',' ','h','a','p','p','y'};
數組c的長度自動設定為10。
4.2字符數組的賦值與引用
只能對字符數組的元素賦值,而不能用賦值語句對整個數組賦值。
char c[5];
c={'C','H','I','N','A'};//error
c[0]='C';c[1]='H';c[2]='I';c[3]='N';c[4]='A';//ok
如果已定義了a和b是具有相同類型和長度的數組,且b數組已被初始化,
a=b;//error
a[0]=b[0];//ok
4.3 字符串和字符串結束標志
對于,
char str[12]={'I',' ','a','m',' ','h','a','p','p','y'};
字符串str只有10個字符,所以系統(tǒng)會對字符數組最后兩位自動填補’’,這是“字符串結束標志”。在上面的數組中,第11個字符為’’,就表明字符串的有效字符為其前面的10個字符。也就是說,遇到字符’’就表示字符串就此結束。
對一個字符串常量,系統(tǒng)會自動在所有字符的后面加一個’’作為結束符。例如字符串”I am happy”共有10個字符,但內存中它共占11個字節(jié),最后一個字節(jié)’’是系統(tǒng)自動加上的。
在程序中往往依靠檢測’’的位置來判定字符串是否結束,而不是根據數組的長度來決定字符串長度。
下面用字符串常量來初始化字符數組,
char str[]={"I am happy"};
也可以
char str[]="I am happy";
注意字符串的兩端是用雙引號而不是單引號。這里str數組的長度為11,因為系統(tǒng)在最后自動加上一個’’。上面的初始化等價于
char str[]={'I',' ','a','m',' ','h','a','p','p','y', ''};
而不等價于
char str[]={'I',' ','a','m',' ','h','a','p','p','y'};
需要說明的是,字符數組并不要求它的最后一個字符為’’。下面的寫法是合法的(最后沒有’’),
char str[5]={'C','H','I','N','A'};
char str[]={'C','H','I','N','A'};
是否加’’是選擇性的,而C++編譯系統(tǒng)會對字符串常量自動加一個’’,因此為了使處理方法一致,便于測定字符串的實際長度,推薦人為加上’’,即
char str[6]={'C','H','I','N','A',''};
char str[6]={'C','H','I','N','A'};
char str[]={'C','H','I','N','A',''};
5.字符串數組
string name[5];//定義一個字符串數組,包含個字符串元素
string name[5]={"Jeff","Tom","Ada","Mike","Bill"};//定義一個字符串數組并初始化
每個字符串元素中只包含字符串本身的字符而不包括’’;
在本例中,就是把字符串”Jeff”的地址存放在name[0], 把字符串”Tom”的地址存放在name[1], 把字符串”Ada”的地址存放在name[2], 把字符串”Mike”的地址存放在name[3], 把字符串”Bill”的地址存放在name[4]。
轉載于:https://www.cnblogs.com/qnbs1/articles/1746936.html
總結
                            
                        - 上一篇: 静态技术详解
 - 下一篇: 收集下阿里集团下的技术BLOG