指向指針的指針,很早以前在說指針的時候說過,但后來發(fā)現(xiàn)很多人還是比較難以理解,這一次我們再次仔細(xì)說一說指向指針的指針。先看下面的代碼,注意看代碼中的注解:
#include
#include
using namespace std;
void print_char(char* array[],int len);
//函數(shù)原形聲明
void main(void)
{
//---------------------
--------段1----------
char *a[]={"abc","cde","fgh"};
//字符指針數(shù)組
char* *b=a;
//定義一個指向指針的指針,
并賦予指針數(shù)組首地址所指向的第一個字符串的
地址也就是abc\0字符串的首地址
cout<<*b<<"|"<<*(b+1)
<<"|"<<*(b+2)< //----------------
--------------------------
//----------
-------------------段2----------
char* test[]={"abc","cde","fgh"};
//注意這里是引號,表示是字符串,
以后的地址每加1就是加4位(在32位系統(tǒng)上)
int num=sizeof(test)/sizeof(char*);
//計算字符串個數(shù)
print_char(test,num);
cin.get();
//-------------------
-----------------------
}
void print_char(char* array[],
int len)
//當(dāng)調(diào)用的時候傳遞進(jìn)來的不是數(shù)組,
而是字符指針?biāo)考?也就是加上sizeof(char*)的長度
{
for(int i=0;i {
cout<<*array++< }
}
下面我們來仔細(xì)說明一下字符指針數(shù)組和指向指針的指針,
段1中的程序是下面的樣子:
char *a[]={"abc","cde","fgh"};
char* *b=a;
cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)< char *a[]定義了一個指針數(shù)組,注意不是char[], char[]是不能同時初始化為三個字符的,
定義以后的a[]其實(shí)內(nèi)部有三個內(nèi)存位置,
分別存儲了abc\0,cde\0,fgh\0,三個字符串的起始地址,
而這三個位置的內(nèi)存地址卻不是這三個字符串的起始地址,
在這個例子中a[]是存儲在??臻g內(nèi)的,
而三個字符串卻是存儲在靜態(tài)內(nèi)存空間內(nèi)的const區(qū)域中的,
接下去我們看到了char* *b=a;
這里是定義了一個指向指針的指針,
如果你寫成char *b=a;那么是錯誤的,
因為編譯器會返回一個無法將char* *[3]轉(zhuǎn)換給char *的錯誤,b=a的賦值,實(shí)際上是把a(bǔ)的首地址賦給了b,
由于b是一個指向指針的指針,
程序的輸出cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)< 結(jié)果是
abc
cde
fgh
可以看出每一次內(nèi)存地址的+1操作事實(shí)上是一次加sizeof(char*)的操作,我們在32位的系統(tǒng)中sizeof(char*)的長度是4,所以每加1也就是+4,實(shí)際上是*a[]內(nèi)部三個位置的+1,所以*(b+1)的結(jié)果自然就是cde了,我們這時候可能會問,為什么輸出是cde而不是c一個呢?答案是這樣的,在c++中,輸出字符指針就是輸出字符串,程序會自動在遇到\0后停止。
我們最后分析一下段2中的代碼,段2中我們調(diào)用了print_array()這個函數(shù),這個函數(shù)中形式參數(shù)是char *array[]和代碼中的char *test[]一樣,同為字符指針,當(dāng)你把參數(shù)傳遞過來的時候,事實(shí)上不是把數(shù)組內(nèi)容傳遞過來,test的首地址傳遞了進(jìn)來,由于array是指針,所以在內(nèi)存中它在棧區(qū),具有變量一樣的性質(zhì),可以為左值,所以我們輸出寫成了:
cout<<*array++< 當(dāng)然我們也可以改寫為:
cout<
這里在循環(huán)中的每次加1操作和段1代碼總的道理是一樣的,注意看下面的圖!
到這里這兩個非常重要的知識點(diǎn)我們都說完了,說歸說,要想透徹理解希望讀者多動手,多觀察,熟能生巧。
#include
#include
using namespace std;
void print_char(char* array[],int len);
//函數(shù)原形聲明
void main(void)
{
//---------------------
--------段1----------
char *a[]={"abc","cde","fgh"};
//字符指針數(shù)組
char* *b=a;
//定義一個指向指針的指針,
并賦予指針數(shù)組首地址所指向的第一個字符串的
地址也就是abc\0字符串的首地址
cout<<*b<<"|"<<*(b+1)
<<"|"<<*(b+2)<
--------------------------
//----------
-------------------段2----------
char* test[]={"abc","cde","fgh"};
//注意這里是引號,表示是字符串,
以后的地址每加1就是加4位(在32位系統(tǒng)上)
int num=sizeof(test)/sizeof(char*);
//計算字符串個數(shù)
print_char(test,num);
cin.get();
//-------------------
-----------------------
}
void print_char(char* array[],
int len)
//當(dāng)調(diào)用的時候傳遞進(jìn)來的不是數(shù)組,
而是字符指針?biāo)考?也就是加上sizeof(char*)的長度
{
for(int i=0;i
cout<<*array++<
}
下面我們來仔細(xì)說明一下字符指針數(shù)組和指向指針的指針,
段1中的程序是下面的樣子:
char *a[]={"abc","cde","fgh"};
char* *b=a;
cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<
定義以后的a[]其實(shí)內(nèi)部有三個內(nèi)存位置,
分別存儲了abc\0,cde\0,fgh\0,三個字符串的起始地址,
而這三個位置的內(nèi)存地址卻不是這三個字符串的起始地址,
在這個例子中a[]是存儲在??臻g內(nèi)的,
而三個字符串卻是存儲在靜態(tài)內(nèi)存空間內(nèi)的const區(qū)域中的,
接下去我們看到了char* *b=a;
這里是定義了一個指向指針的指針,
如果你寫成char *b=a;那么是錯誤的,
因為編譯器會返回一個無法將char* *[3]轉(zhuǎn)換給char *的錯誤,b=a的賦值,實(shí)際上是把a(bǔ)的首地址賦給了b,
由于b是一個指向指針的指針,
程序的輸出cout<<*b<<"|"<<*(b+1)<<"|"<<*(b+2)<
abc
cde
fgh
可以看出每一次內(nèi)存地址的+1操作事實(shí)上是一次加sizeof(char*)的操作,我們在32位的系統(tǒng)中sizeof(char*)的長度是4,所以每加1也就是+4,實(shí)際上是*a[]內(nèi)部三個位置的+1,所以*(b+1)的結(jié)果自然就是cde了,我們這時候可能會問,為什么輸出是cde而不是c一個呢?答案是這樣的,在c++中,輸出字符指針就是輸出字符串,程序會自動在遇到\0后停止。
我們最后分析一下段2中的代碼,段2中我們調(diào)用了print_array()這個函數(shù),這個函數(shù)中形式參數(shù)是char *array[]和代碼中的char *test[]一樣,同為字符指針,當(dāng)你把參數(shù)傳遞過來的時候,事實(shí)上不是把數(shù)組內(nèi)容傳遞過來,test的首地址傳遞了進(jìn)來,由于array是指針,所以在內(nèi)存中它在棧區(qū),具有變量一樣的性質(zhì),可以為左值,所以我們輸出寫成了:
cout<<*array++<
cout<
這里在循環(huán)中的每次加1操作和段1代碼總的道理是一樣的,注意看下面的圖!
到這里這兩個非常重要的知識點(diǎn)我們都說完了,說歸說,要想透徹理解希望讀者多動手,多觀察,熟能生巧。

