討論區快速選單
知識庫快速選單
掌握Salesforce雲端管理秘訣 程式設計俱樂部Facebook粉絲團 傑米的攝影旅遊筆記
[ 回上頁 ] [ 討論區發言規則 ]
初學STL裡的list遇到的問題
更改我的閱讀文章字型大小
作者 : wang3529(兔妹) 貼文超過200則人氣指數超過10000點
[ 貼文 307 | 人氣 27736 | 評價 50 | 評價/貼文 0.16 | 送出評價 36 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/10/20 下午 05:53:13
我最近開始嘗試用STL裡的list
但是遇到一些問題想請教網友
宣告部分
using namespace std;
struct Flushadd
{
int FlushAddBet;
int FlushAddMoney;
int FlushAddCount;
int FlushAddLoop;
};
struct Flushadd FlushAdd;
typedef list<Flushadd> FlashAddlist;
FlashAddlist FlashAddList;

//做LIST 程式裡預設資料 假設做3筆
FlushAdd.FlushAddLoop=10;
FlushAdd.FlushAddBet=100;
if(FlashAddList.empty()==true)
FlashAddList.push_front(FlushAdd);//做第一筆資料
else
FlashAddList.push_back(FlushAdd);//增加後面的資料

//要改第一筆資料時
if(FlashAddList.empty()!=true)
{
Flushadd NowFlushAdd=FlashAddList.front(); //拿最前面資料
NowFlushAdd.FlushAddLoop--;//改資料
NowFlushAdd.FlushAddMoney=FlushAdd.FlushAddCount*FlushAdd.FlushAddBet;//改資料
FlashAddList.pop_front(); //砍掉最前面資料
FlashAddList.push_front(FlushAdd);//把資料丟到最前面
}
-------------------------------------------------------
1.請問如何直接改第一筆資料
我現在是用取出第一筆資料,修改,然後砍掉,再把改過的新資料放在最前面...
2.再請問如何取第2筆資料 並且把修改直放回去
//這是我要取第2筆資料的寫法
FlashAddlist::iterator x;
int loop=0;
for (x = FlashAddList.begin(); x != FlashAddList.end(); x++)
{
loop++;
if(loop==2)
{
Flushadd NowFlushAdd;
NowFlushAdd=*x;
NowFlushAdd.FlushAddLoop--;
怎麼把資料放進去第2個位置.....後面就不會用了......
我試著用FlashAddList.erase(x);砍掉第2筆 再用FlashAddList.insert(FlashAddList.begin()+1,NowFlushAdd);
結果是insert編輯錯誤
把FlashAddList.begin()+1改成x是記憶體錯誤
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人wang3529註記此篇回應為最佳解答 2014/10/21 上午 12:41:10
>我最近開始嘗試用STL裡的list
>但是遇到一些問題想請教網友
>宣告部分
>using namespace std;
>struct Flushadd
>{
> int FlushAddBet;
> int FlushAddMoney;
> int FlushAddCount;
> int FlushAddLoop;
>};
>struct Flushadd FlushAdd;

struct 的 tag 可以直接當做類型使用:
  Flushadd FlushAdd;

同時也建議你加個建構子, 用來初始化它的成員.


>typedef list<Flushadd> FlashAddlist;
>FlashAddlist FlashAddList;
>
>//做LIST 程式裡預設資料 假設做3筆
>FlushAdd.FlushAddLoop=10;
>FlushAdd.FlushAddBet=100;

你忘了設 FlushAddMoney 及 FlashAddCount 成員. 建議你在 Flushadd 架構增添建構子, 把成員初始化.


>if(FlashAddList.empty()==true)
> FlashAddList.push_front(FlushAdd);//做第一筆資料
>else
> FlashAddList.push_back(FlushAdd);//增加後面的資料

沒有必要檢查是否 empty, 直接 push_back() 就可以了. 如果 list 是空的, 不管 push_back() 或是 push_front() 都是第一筆資料.

  Flushadd FlushAdd;
  FlashAddList.push_back(FlushAdd);


>//要改第一筆資料時
>if(FlashAddList.empty()!=true)
>{
>Flushadd NowFlushAdd=FlashAddList.front(); //拿最前面資料
>NowFlushAdd.FlushAddLoop--;//改資料
>NowFlushAdd.FlushAddMoney=FlushAdd.FlushAddCount*FlushAdd.FlushAddBet;//改資料

如果 FlushAddMoney 成員的內容是計算出來的, 那最好不要把它寫作成員. 需要的時候把它計算出來就好.
這是為了確保資料的一致性.


>FlashAddList.pop_front(); //砍掉最前面資料
>FlashAddList.push_front(FlushAdd);//把資料丟到最前面
>}
>-------------------------------------------------------
>1.請問如何直接改第一筆資料
>我現在是用取出第一筆資料,修改,然後砍掉,再把改過的新資料放在最前面...

不必要這麼麻煩. 如果你去看 list::front() 的說明, 你可以看到它傳回的是個 reference. 如果你用 reference 的方式來接收, 你就可以直接修改它裡面的資料:
  Flushadd& data = FlashAddList.front();
  --data.FlushAddLoop; // 改資料
  data.FlushAddMoney = data.FlushAddCount * data.FlushAddBet; // 改資料

>2.再請問如何取第2筆資料 並且把修改直放回去
>//這是我要取第2筆資料的寫法
>FlashAddlist::iterator x;
>int loop=0;
>for (x = FlashAddList.begin(); x != FlashAddList.end(); x++)
>{
> loop++;
> if(loop==2)
> {
> Flushadd NowFlushAdd;
> NowFlushAdd=*x;
> NowFlushAdd.FlushAddLoop--;
>怎麼把資料放進去第2個位置.....後面就不會用了......

要取第二筆資料, 用 std::advance() (頭檔是 <iterator>), 你必須確保 advance 不會超出 container 的大小. 得到 iterator 後, 就可以把它當做指標來用:

  if (FlashAddList.size() > 2)
  {
    FlashAddList::iterator it = FlashAddList.begin();
    std::advance(it, 2);
    --it->FlushAddLoop;
    it->FlushAddMoney = it->FlushAddCount * it->FlushAddBet;
  }

建議參考書: "The C++ Standard Library - A Tutorial and Reference" by Nicolai M. Josuttis (http://www.cppstdlib.com/)

作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2014/10/21 下午 10:10:23
>for (x = FlashAddList.begin(); x != FlashAddList.end(); x++)

如果 'x' 是個 iterator, 應該用前置的 ++ 或 --, 如 ++x. 效率上, ++x 絕對不會比 x-- 底, 至少相同或更好 (看 x 的類型而定).

後置的 ++ 或 -- (x++ 或 x--) 必須要傳回舊值, 在實施上它要先複製物件, 然後做增或減的動作, 最後再傳回複製的物件. 就是這個複製物件的動作導致效率的降低.

  http://www.gotw.ca/gotw/002.htm

如果 x 是內建類型, 只要它是單獨使用的情況下, ++x 跟 x++ 其實不會有太大的差別. 但 C++ 程式員不可永遠停留在內建類型. iterator 遲早會用得到, 所以為了養成習慣, 我一直都在回覆時建議初學者盡量習慣使用前置的 ++ 或 --.
 板主 : 青衫 , Raymond
 > Visual C++ - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - Visual C++ - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
Visual C++
1 青衫 11070 
2 Raymond 10090 
3 Clier 7630 
4 小約翰 2500 
5 Cog 2030 
6 coco 1870 
7 aming 1410 
8 牧童哥 1400 
9 r2109 1380 
10 Akira 1350 
Visual C++
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.140625