感謝網友『阿仁』對於我BLOG裡面程式碼的訂正,在參考過『More Effective C++』中,對於指標使用上的補充順便加入Reference的一些資料。所以一併將這些資料整理在這裡,順便提一下今天侯捷老師講解一些關於Reference Counting 的概念。只能說很多東西要不斷的複習,不然真的都會遺忘,這幾次的面試有很多間公司都搞砸了也就是因為這個原因,原本五專時代都記得的東西,因為許久沒有使用,真的都忘的乾乾淨淨。
| 指標(Pointer) (type *p) |
參照(Reference) (type &p) |
|
| 記憶體配置 | 配置指標記憶體(4Byte) | 不配置記憶體,本身為別名(Alias) |
| 初始值給定 | 可以後來指定(不建議,但是允許這樣給值) | 必須在變數成立的時候,直接給定初始值 |
| 內容值(p) | 代表一個記憶體位置,指向給定的目標值 | 直接代表目標值 |
| 設定位置 (目標值Q) |
p=&Q | p=Q (在此為將Q另外設定一個名字p) |
| 給值 (目標值Q) |
*p=Q (將Q的值給*p) |
p=Q (在此為將Q另外設定一個名字p) |
根據以上的表格,順道提到一般課本常提到的Call by address與
Call by reference的參照方式,撰寫如下:
|
Call by Address |
Call by Reference |
|
#include <iostream.h> |
#include <iostream.h> void fun1(int & p, int & q) { p=p+q; } void main() { int i=3,j=4,k; fun1(i,j); cout <<i; } |
透過這個列表,可以清楚的兩者的差異,所以在之前文章所提到的錯誤為:
|
int x=10; |
在此錯誤為,由於我的指標 *v 並沒有初始化指標,所以v的值是一個系統給的亂數(或是之前變數留下來的資料),其實這樣去指定是相當危險的一件事情。所以要設定v去指定x的時候,應該使用
v=&x 去設定一個位置在v之中。之前會這樣想也因為我對於字串指標的設定有一點混淆
char *s="test ~~~ string~~~";
像這樣的句子,雖然也是起使一個指標,但是由於電腦會先根據字串"test
~~~ string~~~"去分配一個位置給他,然後再把位置指定給s
,所以不需要再配置一次位置(記得這個問題在趨勢與友立似乎也一直被問到~~)
但是這裡順道一提 char *s="test ~~~ string~~~"; 與 char
s[]="test ~~~ string~~~";
若要顯示整段文字,勢必得使用後者,因為cout <<*s;
只會顯示出第一個字元,而 cout <<sp[]; cout<<sp;
則會顯示整個字串,這也是字串與指標的一種混和運用。太久沒寫的人(像我),這邊也會有種混淆的感覺@﹍﹍﹍@
|
String a,b,c,d,e; |
在以上的程式之中,記憶體是會分配『五塊記憶體(大小為STRING)』,因為原來在String中的運算子『=』的定義是Assign
by Copy的方式,也就是會同樣的分配一塊記憶體,然後複製其內容值到每一塊記憶體之中。所以若是針對
『=』加以更改其作用值,若是在參考的時候(也就是單純的String
互傳值)的話,應該是將記憶體節省下來,直接讓LHS(左手邊的變數)直接指向RHS(右手邊)的變數才對。並且還要可以計數所有有參照到該記憶體的變數個數(所以才叫Reference
Counting),詳細說明,請看『More
Effective C++』的P.183
我又來了
char* s="test string!!";
cout<<"STRING:"<<s<<endl;
char a[]="test string!!";
cout<<"a="<<&a[0]<<endl; = cout<<"a="<<a<<endl;
so..
上面都可以顯示出來
cout<<"a="<<a[]<<endl; 語法錯誤
體會到侯捷老師的一句話
被讀者訂正錯誤,真是『又痛又快~~~』
感謝 阿仁兄的指正,不過也真怪~~ 我明明執行正確的,卻寫錯的給大家看
由 Evan 發表於 May 20, 2004 08:00 PM我想說的是
妳的內文
但是這裡順道一提 char *s="test ~~~ string~~~"; 與 char s[]="test ~~~ string~~~"; 若要顯示整段文字,勢必得使用後者,因為cout <<*s; 只會顯示出第一個字元
用cout<<s; 就可以全部字串顯示出了 就好比丟個字串array的位址給他就ok了
May 20, 2004 11:10 PM剛好路過看到這邊,覺得有些東西要補充一下
char* s = "abcde"; 和
char s[] = "abcde";
有著根本上的不同,你把他們丟到某些字串函數會有不同的行為
需要分清楚char*, const char*, const char[], text literal四者之間的區別
為了避免誤用,盡量使用const char* s = "something..."代替char* s = "something..."
見Effective C++ Item 21最後面的注解(我的是英文版,不知道中文版有沒有)
做個實驗就會發現
char* s1 = "abcde";
char* s2 = "abcde";
char s3[] = "abcde";
char s4[] = "abcde";
如果你去印出他們的指標值如
printf("%p\n", s1); //%p希望沒記錯
會發現s1和s2是一樣的,而s3和s4不同
而你再去宣告
char* skk = "abcde";
char* ppp = "abcde"; 記憶體位址仍然相同
在c語言中是沒有call by reference 與call by address的差異性這一回事的。應該是說call by pointer 與call by reference 的差異性,而這兩者皆屬於call by address。(候捷的書也是這麼說,請詳讀)
由 許大笨 發表於 December 8, 2005 08:47 AM