TStringList 的指標 |
答題得分者是:dllee
|
jessechan
版主 發表:109 回覆:394 積分:254 註冊:2002-04-05 發送簡訊給我 |
參考以下 code AnsiString asTemp;
int nI;
nI = Edit1->Text.ToInt();
pslTest[1]->Clear();
pslTest[1]->Add("1 string");
pslTest[1]->Add("2 string");
pslTest[1]->Add("3 string");
pslTest[1]->Add("4 string");
pslTest[1]->Add("5 string");
asTemp.sprintf("[%d][%p][%s][%p][%s]",nI,&(pslTest[1]->Strings[nI]),pslTest[1]->Strings[nI].c_str(),&(pslTest[1]->Strings[0]),pslTest[1]->Strings[0].c_str());
Caption = asTemp; 不管 nI 等於多少, &(pslTest[1]->Strings[nI]) 的值始終不會變化, 請教是為何. Jesse Chan
------
Jesse Chan |
jessechan
版主 發表:109 回覆:394 積分:254 註冊:2002-04-05 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
測試程式如下:
TStringList *pslTest=new TStringList; AnsiString asTemp="12345678"; AnsiString asBuf; asBuf.printf("%p : %p : %s",asTemp.c_str(),&asTemp.c_str,asTemp.c_str()); ListBox1->Items->Add(asBuf); asBuf.printf("%p : %p :",&asTemp,&asTemp.c_str); asBuf.cat_printf(" %s",asTemp.c_str()); ListBox1->Items->Add(asBuf); for(int i=0;i<10;i ) pslTest->Add("12345678 " IntToStr(i)); for(int i=0;i<10;i ) { asBuf.printf("%p : %p :",&(pslTest->Strings[i]),&pslTest->Strings[i].c_str); asBuf.cat_printf("%p : %s",pslTest->Strings[i].c_str(),pslTest->Strings[i].c_str()); ListBox1->Items->Add(asBuf); } delete pslTest;結果 00954BAC : 00401A84 : 春? 0012FF20 : 00401A84 : 12345678 0012FF0C : 00401A84 :00954C00 : 12345678 0 0012FF0C : 00401A84 :00954C3C : 12345678 1 0012FF0C : 00401A84 :00954C54 : 12345678 2 0012FF0C : 00401A84 :00954C6C : 12345678 3 0012FF0C : 00401A84 :0095631C : 12345678 4 0012FF0C : 00401A84 :00956378 : 12345678 5 0012FF0C : 00401A84 :00956390 : 12345678 6 0012FF0C : 00401A84 :009563A8 : 12345678 7 0012FF0C : 00401A84 :009563C0 : 12345678 8 0012FF0C : 00401A84 :0095643C : 12345678 9由其中可得到 AnsiString asTemp 之 &asTemp 與 asTemp.c_str() 是不同的。我想這點應該比較好明瞭,因為 AnsiString 是一個 struct/object 而 c_str() 只是其中的 method 用來取得 AnsiString 內含字串的記憶體位址。 另外,就是 jessechan 大大提到的 &(pslTest->Strings[i]) 不論 i 為何值都是一樣! 這點,我的解釋是這樣的,因為 Strings[i] 對於 TStringList 來說是用 property tt xx[int Index]={read=yy,write=zz}; 的方式供外部來存取,但每次叫用時,等於是在叫用 yy 或 zz 的函式,所以,其指標位址並不會因 Index 而改變。就像是所有的 c_str() 這個函式的位址也都是相同的。 最後,要注意的是,printf() 的叫用... 由上述的程式及結果可以看到,當 &asTemp.c_str,asTemp.c_str() 放在一起時,會導致後面那個指標好像不知指到那裡去?!而這可能是 printf() 的 bug 但只要把它們分開就 >沒空更新的網頁... href="http://big5.to/吃軟也吃硬">http://big5.to/吃軟也吃硬 http://coolsite.to/ushells 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
Royce520
高階會員 發表:18 回覆:157 積分:100 註冊:2002-09-13 發送簡訊給我 |
jessechan 你好,
你問的"不管 nI 等於多少, &(pslTest[1]->Strings[nI]) 的值始終不會變化?" 的問題 其原因如下: 我先把程式片段改成這樣, 方便來看
asTemp.sprintf("[%d][%p][%s][%p][%p][%s]", // 我多加了一個
nI,
(pslTest[1]->Strings[nI]), // 請注意我把 & 去掉了, 原因以下說明
pslTest[1]->Strings[nI].c_str(),
&(pslTest[1]->Strings[0]),
&(pslTest[1]->Strings[0]), // 這是我多加的, 輸出值跟上一行不一樣 你應該可以明白的
pslTest[1]->Strings[0].c_str()
);
//------
(pslTest[1]->Strings[nI]) 的寫法才是真正得到之前插入的不同字串的位址的正確方式, 因為 pslTest[1]->Strings[nI] 本身就是一個 AnsiString, 在此處是呼叫 TStringList.Get 函數, 他會回傳一個 AnsiString 的物件到以上那個程式片斷, 請注意! 回傳後是存在一個系統配置並控制的的變數空間裡(講明白就是配置在 stack 上, 所以你原來的寫法 等於是取得 &variable_by_BCB 的位址, 因此...因此 每次以不同的 nI 值來呼叫這個函數 等於是取得相同記憶空間的位址(ps 因為 stack 空間沒有改變). 假如 你想要驗證或者得到不同值, 你可以這麼做, 把程式稍微修改 成遞迴呼叫的方式...在這個狀況下, > *真實的事物最美, 簡單的道理最好, 我能體會的 太少* 發表人 -
------
不要忘記呼吸,不要忘記編程! ∩__∩ |
jessechan
版主 發表:109 回覆:394 積分:254 註冊:2002-04-05 發送簡訊給我 |
|
jessechan
版主 發表:109 回覆:394 積分:254 註冊:2002-04-05 發送簡訊給我 |
|
Royce520
高階會員 發表:18 回覆:157 積分:100 註冊:2002-09-13 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
引言: 我想我應該了解了, 小弟覺得二位大大的解釋都對, 但是 Royce520 兄 stack 的解釋應該比較正確, 所以我把分數給他, dllee 大大抱歉, 小弟悟性不好, 如果只看你的解釋, 我可能只能懂一半, 不過也因為有你首先解答, 讓我對這個問題比較了解, 在此謝過. Jesse Chan對於 AnsiString 我也只懂一半,哈哈! 而且我不是科班出身的,書又讀得少,全都靠程式自行驗證,對於 stack/heap 之類的東西並不是很明瞭,看到 Royce520 的解釋,可以讓我了解更多... 立刻實作測試一下: //----------------------------------------------------------------------------// void __fastcall TForm1::Test(int Count) { TStringList *pslTest=new TStringList; AnsiString asTemp="12345678"; AnsiString asBuf; asBuf.printf("%p : %p : %s",asTemp.c_str(),&asTemp.c_str,asTemp.c_str()); ListBox1->Items->Add(asBuf); asBuf.printf("%p : %p :",&asTemp,&asTemp.c_str); asBuf.cat_printf(" %s",asTemp.c_str()); ListBox1->Items->Add(asBuf); for(int i=0;i<10;i ) pslTest->Add("12345678 " IntToStr(i)); for(int i=0;i<10;i ) { asBuf.printf("%p : %p : ",&(pslTest->Strings[i]),&pslTest->Strings[i].c_str); asBuf.cat_printf("%p : %s",pslTest->Strings[i].c_str(),pslTest->Strings[i].c_str()); ListBox1->Items->Add(asBuf); } asBuf.printf("%p : %p : Sizeof TStringList = %d",pslTest,&pslTest,sizeof(TStringList)); ListBox1->Items->Add(asBuf); ListBox1->Items->Add("---"); if(Count < 3) Test(Count); delete pslTest; } //----------------------------------------------------------------------------// __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Test(0); ListBox1->Items->SaveToFile("output.txt"); } //----------------------------------------------------------------------------//結果如下: 00954BAC : 00401A44 : 春? 0012FEE4 : 00401A44 : 12345678 0012FED0 : 00401A44 : 00954C00 : 12345678 0 0012FED0 : 00401A44 : 00954C3C : 12345678 1 0012FED0 : 00401A44 : 00954C54 : 12345678 2 0012FED0 : 00401A44 : 00954C6C : 12345678 3 0012FED0 : 00401A44 : 0095631C : 12345678 4 0012FED0 : 00401A44 : 00956378 : 12345678 5 0012FED0 : 00401A44 : 00956390 : 12345678 6 0012FED0 : 00401A44 : 009563A8 : 12345678 7 0012FED0 : 00401A44 : 009563C0 : 12345678 8 0012FED0 : 00401A44 : 0095643C : 12345678 9 00954B70 : 0012FE8C : Sizeof TStringList = 48 --- 00956488 : 00401A44 : d? 0012FE48 : 00401A44 : 12345678 0012FE34 : 00401A44 : 009564DC : 12345678 0 0012FE34 : 00401A44 : 009564F4 : 12345678 1 0012FE34 : 00401A44 : 0095650C : 12345678 2 0012FE34 : 00401A44 : 00956524 : 12345678 3 0012FE34 : 00401A44 : 0095653C : 12345678 4 0012FE34 : 00401A44 : 00956554 : 12345678 5 0012FE34 : 00401A44 : 0095656C : 12345678 6 0012FE34 : 00401A44 : 00956584 : 12345678 7 0012FE34 : 00401A44 : 0095659C : 12345678 8 0012FE34 : 00401A44 : 00956618 : 12345678 9 0095644C : 0012FDF0 : Sizeof TStringList = 48 --- 00956664 : 00401A44 : df? 0012FDAC : 00401A44 : 12345678 0012FD98 : 00401A44 : 009566B8 : 12345678 0 0012FD98 : 00401A44 : 009566D0 : 12345678 1 0012FD98 : 00401A44 : 009566E8 : 12345678 2 0012FD98 : 00401A44 : 00956700 : 12345678 3 0012FD98 : 00401A44 : 00956718 : 12345678 4 0012FD98 : 00401A44 : 00956730 : 12345678 5 0012FD98 : 00401A44 : 00956748 : 12345678 6 0012FD98 : 00401A44 : 00956760 : 12345678 7 0012FD98 : 00401A44 : 00956778 : 12345678 8 0012FD98 : 00401A44 : 009567F4 : 12345678 9 00956628 : 0012FD54 : Sizeof TStringList = 48 --- 00956840 : 00401A44 : @h? 0012FD10 : 00401A44 : 12345678 0012FCFC : 00401A44 : 00956894 : 12345678 0 0012FCFC : 00401A44 : 009568AC : 12345678 1 0012FCFC : 00401A44 : 009568C4 : 12345678 2 0012FCFC : 00401A44 : 009568DC : 12345678 3 0012FCFC : 00401A44 : 009568F4 : 12345678 4 0012FCFC : 00401A44 : 0095690C : 12345678 5 0012FCFC : 00401A44 : 00956924 : 12345678 6 0012FCFC : 00401A44 : 0095693C : 12345678 7 0012FCFC : 00401A44 : 00956954 : 12345678 8 0012FCFC : 00401A44 : 009569D0 : 12345678 9 00956804 : 0012FCB8 : Sizeof TStringList = 48 ---沒空更新的網頁... http://dllee.ktop.com.tw C及指標教學,計算機概論,資訊管理導論... http://big5.to/吃軟也吃硬 http://coolsite.to/ushells 介紹Shells,LiteStep,GeoShell....
------
http://www.ViewMove.com |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |