全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1212
推到 Plurk!
推到 Facebook!

TStringList 的指標

答題得分者是:dllee
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-23 13:12:07 IP:203.75.xxx.xxx 未訂閱
參考以下 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-04-23 13:15:42 IP:203.75.xxx.xxx 未訂閱
如果加一行      asTemp.sprintf("[%d][%p][%s][%p][%s][%p]",nI,&(pslTest[1]->Strings[nI]),pslTest[1]->Strings[nI].c_str(),&(pslTest[1]->Strings[0]),pslTest[1]->Strings[0].c_str(),&(pslTest[1]->Strings[0]));    結果更好玩, 自己好像不等於自己.    Jesse Chan
------
Jesse Chan
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-04-23 20:03:59 IP:61.231.xxx.xxx 未訂閱
測試程式如下:
  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

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-04-23 22:32:46 IP:61.59.xxx.xxx 未訂閱
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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-04-24 01:33:32 IP:61.228.xxx.xxx 未訂閱
感謝二位大大的回應, 今天比較晚有空, 所以目前還在設法參透二位的說明, 謝過先.    Jesse Chan
------
Jesse Chan
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-04-24 01:58:49 IP:61.228.xxx.xxx 未訂閱
我想我應該了解了, 小弟覺得二位大大的解釋都對, 但是 Royce520 兄 stack 的解釋應該比較正確, 所以我把分數給他, dllee 大大抱歉, 小弟悟性不好, 如果只看你的解釋, 我可能只能懂一半, 不過也因為有你首先解答, 讓我對這個問題比較了解, 在此謝過.    Jesse Chan
------
Jesse Chan
Royce520
高階會員


發表:18
回覆:157
積分:100
註冊:2002-09-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-04-24 02:25:11 IP:61.216.xxx.xxx 未訂閱
jessechan 你好,   如果你的年齡沒有錯報, 還是我得稱呼你一聲jessechan大哥呢,   所以別稱呼我 什麼什麼兄的...  . 後記: 其實 我剛開始看你的疑問, 我的直覺是不可能 怎麼執會一樣呢? 於是我就寫了程式 測試了依下...不過真如你說的 值是不會改變的 所以我就納悶了...於是我開始追 > *真實的事物最美, 簡單的道理最好, 我能體會的 太少*
------
不要忘記呼吸,不要忘記編程! ∩__∩
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-04-24 14:05:07 IP:61.231.xxx.xxx 未訂閱
引言: 我想我應該了解了, 小弟覺得二位大大的解釋都對, 但是 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
系統時間:2024-05-05 22:52:11
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!