一、指針

1、指針是一種存放內存地址的數據類型

2、指針的創建

typename * p;//空格可有可無

此時p的類型為(typename *)

(*p)的類型為typename

初始化一個指針後,該指針變數會被存放在內存中的某個地址

指針創建時可以不初始化

如:int * p1;//p1的類型為(int *),(*p1)的類型為int
float * p2;//p2的類型為(float *),(*p2)的類型為float
char * p3;//p3的類型為(char *),(*p3)的類型為char

3、對其賦值後,其對應內存位置存放的值被解釋為一個地址,稱該地址為其所指向的地址或內存空間

如:p1=(int *)50000;//p1在內存中的地址為xxxxx,p所指向的地址為50000
float a = 1;
p2= &a; //p1在內存中的地址為yyyyy,p所指向的地址為a所在的地址

4、間接引用運算符*

①類型名執行*運算得到一個指向該類型的指針類型,即地址

即(typename *)表示一個指向typename類型的指針類型

②變數名執行*運算得到該變數指向的內容,即去地址

即當p為一個(typename *)類型的指針變數時,(*p)代表從p所指向的地址處起始的大小為sizeof(typename)個位元組的內容,這些內容的數據類型被解釋為typename

如:p = (int*)a;//將a轉換為指向int的指針類型,賦值給p
int length = sizeof(typename *);//length為該環境下地址變數的長度
*p = 4000;//向地址從50000處開始的sizeof(int)個位元組的內存空間里寫入4000
int n = *p;//將地址從50000處開始的sizeof(int)個位元組的內存空間里表示的int型數據,即4000,賦值給n

5、指針常量、常(量)指針和常(量)指針常量

①指針常量:typename * const p = &a;

指針是常量

指針p的指向不能改變,但指針p指向的內容,即a的值,可以改變

相當於一個引用,創建時必須初始化

②常(量)指針:const typename * p;

常量的指針

指針p的指向可以改變,但指針p指向的內容必須是常量

創建時可以不初始化

③常(量)指針常量:const typename * const p = &a;

既是常量指針又是指針常量

指針p的指向和指針p指向的內容都不能改變

相當於一個指向常量的引用,創建時必須初始化

6、空指針

空指針是指向地址0的指針,其值為NULL或0

創建後未經初始化的指針都是空指針

7、指針傳遞

傳遞指針時,形參在棧中新開闢一塊內存空間,並將實參的值,即地址,賦值給形參

形參的值是實參的值的拷貝或副本

例1:

void main(){
int a=1;
int * p = & a;
f(p);
}
void f(int * pr){//此時pr的地址和p不同,但存放的值是同一個地址
(*pr)++;
}//運行結果為a的值變為了2

例2:

void main(){
int a=1;
int * p = & a;
f(&p);
}
void f(int ** pr){//此時pr的地址和p不同,但存放的值是同一個地址
(*pr)++;//此時pr存放的值發生了改變
}//運行結果為p指向了下一個地址

8、一些特性

①sizeof(typename *)和sizeof(p)表達式的結果為該環境下指針類型,即地址,所佔的位元組

②支持多級指針,即(typename **)

③指針變數,即p,執行++、--運算的含義是指針p指向下一個地址

指針變數執行*運算符後,即(*p),執行++、--運算的含義是(*p)表示的值的加減

④由於指針變數可以為空,所以使用指針變數之前必須進行判空操作

二、引用

1、引用是一個對象的別名,本質上還是一個指針常量或地址

2、引用的初始化

typename & q = a;//空格可有可無

引用對象創建時必須初始化,且引用的值一經初始化即不得改變

如:int a = 1;
int & q1 = a;//q1始終為a的引用

3、取地址運算符&

①類型名執行&運算,即(typename &),得到一個引用類型

②變數名執行&運算得到一個地址,即取地址

即當a為一個變數名時,(& a)表示a在內存中的地址

4、常(量)引用

const typename & q = a;

常量的引用

引用q的內容,即a,是一個常量

相當於一個常量指針,創建時必須初始化

沒有引用常量和常(量)引用常量,因為引用本身就具有其指向不能改變的特性

5、引用傳遞

傳遞引用時,形參不會在內存中開闢一塊存儲空間,而是形參和實參共用相同的地址,形參的值和實參的值是同一個

例一:

void main(){
int a = 1;
int & q = a;
f(q);
}
void f(int & qr){
qr++;//運行結果為a的值變為了2
//(*qr)++;錯誤,編譯器不認為qr是一個地址,而認為是一個int型的變數,即a的類型
}

6、一些特性

①sizeof(typename &)表達式的結果為typename類型所佔的位元組

sizeof(q)表達式的結果為引用q的對象所佔的位元組

②不支持多級引用

③引用q執行++、--運算的含義是引用q的對象的值的加減

④由於引用不會為空,所以使用引用之前不必進行判空操作

推薦閱讀:

相关文章