C_and_CPP 板


LINE

※ 引述《clonsey1314 (Clonsey)》之銘言: : 最近剛接觸vector, 很方便, 省了很多初始化的工作 : 程式碼也變得簡潔多, 也較好維護 : 但是同時也降低的程式的效能(很明顯) : 請問若沒有要做太多複雜的增刪,是否繼續使用array或pointer就好? : 程式碼裡同時有vector和pointer/array混雜這樣的coding style會不會不好? : 謝謝 一般在 std::vector 和 C array 間作選擇的考量點主要在元素個數的 決定時機: 如果元素個數在編譯時期可以決定, 當然使用 C array 或 std::array; 如果只能在執行時期決定, 才需要考慮 std::vector, 但 也不是預設就使用 STL 容器, 端看你的使用情境. 簡單舉個例子: 假如我們現在需要一塊連續記憶體來儲存班上同學的期 末考成績, 班上同學的數目已知是 50 位, 分數是非負整數, 就可以用 std::array 來定義: using score_type = unsigned; std::array<score_type, 50> scores; 然後可能因為效能需求, 或到某個時機點才需要將這塊記憶體配置出來 (lazy initialization), 可以考慮 std::unique_ptr + std::array: std::unique_ptr<std::array<score_type, 50>> scores; 需要注意的是, 這裡和 std::unique_ptr<score_type[]> 的差別在於 元素個數的決定時機, 如果想使用後者, 代碼的長相需要像這樣: std::size_t n; std::cin >> n; auto scores = std::make_unique<score_type[]>(n); 兩者表達的語意完全不一樣. 另外 std::vector 雖然簡化了物件初始 化及複製, 但其附帶的可變長度性質, 也不適合用來描述上面的問題. 所以用什麼型別不是問題, 問題是有沒有用對型別. 最後整理給你作參 考: (考慮 owning 語意) 元素個數在編譯時期決定: 不需要改變大小: std::array<T, N> 元素個數在執行時期決定: 需要改變大小: STL container 不需要改變大小: std::unique_ptr<T[]> 選用何種 STL 容器就看需要哪些操作 (存取方式、存取成本、新增/刪 除元素的位置等..) 假如會在後端以外的地方新增元素, std::vector 就不是好的選擇. --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.85
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1549042751.A.DB1.html
1F:推 ilikekotomi: 感謝整理與分享 02/02 13:40
2F:→ tomsawyer: 題外話 請問如何存取vector string裡面的字元? 02/02 18:02
3F:推 achicn3: s1[0][0]這樣吧?樓上 02/02 18:22
4F:推 tomsawyer: 我試試看 謝謝樓上 02/02 18:57
比較好的方式是: using std::next; const std::vector<std::string> vs{"hello"s, "world"s}; const auto idx = 1z; // or const std::ptrdiff_t idx = 1; in pre-c++20 [[assert: idx < size(vs)]]; const std::string_view sv = *next(begin(vs), idx); [[assert: sv[1] == 'o']]; 雖然 std::vector 就有提供 operator[] 用來存取元素, 但並不是所有 的 STL 容器都有提供相同的介面, 當你寫下 vs[..] 的時候, 增加了對 容器的需求(requirement), 導致抽換容器實作的時候為了滿足(satisfy) 原本的需求必須實作這些介面. 不管是 generic programming 或是想要提供復用性更高的程式碼, 對容 器的操作盡可能地侷限在迭代器(iterator) 上是比較好的, 使用比較通 用的介面未來擴充性也比較高. 譬如上面這個例子, 若把 next()呼叫改 為: begin(vs) + idx // bad example 這個操作需要迭代器滿足 RandomAccessIterator 概念(concept), 因為 std::vector 本身滿足 ContiguousContainer, 很容易就會使用到不必要 的操作, 是比較不好的用法. 使用 begin() 讓 ADL(argument dependent lookup) 尋找合適的呼叫 (包含自定義函式), 多了 next() 間接呼叫讓 ForwardIterator 也能當作引數, 這段碼的復用性就大大地提高了. 最後建議透過 std::span 或 std::string_view 甚至是 ranges library 裏的適配器(adaptor)來存取容器元素, 也可以減少對容器介面的依賴.
5F:推 allensheng: 最近的文都太專業了吧 02/03 01:43
※ 編輯: poyenc (123.193.76.85), 02/03/2019 17:30:32
6F:推 leoloveivy: 剛轉回C/CPP版真D沒讓我失望XDDD 推個 02/03 19:42







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Soft_Job站內搜尋

TOP