Re: [問題] 索引值的型態

看板C_and_CPP (C/C++)作者 (←這人是超級笨蛋)時間11年前 (2014/10/03 21:46), 編輯推噓2(2038)
留言40則, 6人參與, 最新討論串2/2 (看更多)
※ 引述《bjiyxo (若自礌)》之銘言: : 如題 : 因為曾聽過不同型態的變數做運算的時候 : 會增加電腦的負擔 : 而索引值又常常用到 : 所以好奇想問 : 索引值的預設型態是什麼?

10/02 18:52,
其實只要是整數形態都差不多, 如果你堅持一定要挑一個,
10/02 18:52

10/02 18:52,
就用 ptrdiff_t 吧
10/02 18:52

10/02 19:44,
container 用裡面的 size_type, 不然就 size_t?
10/02 19:44

10/03 15:52,
STL裡面(或者說C++ Libs)都用size_t
10/03 15:52

10/03 15:53,
C就沒有一定標準了 typedef/#define滿天飛的....
10/03 15:53

10/03 15:55,
另外 size_t通常是long或者uint64(兩者大小一樣)
10/03 15:55
我想說一下我選 ptrdiff_t 的原因 首先, 根據標準, subscripting 只是指標運算 + dereferencing 的 syntax sugar 也就是對於一個陣列 a 與整數 i(注意這邊都還完全不考慮形態) a[i] 完全對等於 *(a + i) 這有兩個意義: 1. Subscript 使用的型別應該與 pointer 型別相同 其實我猜 compiler 都會最佳化, 不過如果完全照字面解答原 po 的問題, 那麼 我們要找的應該是 pointer 運算時使用的型別。 2. Subscript 值可以是負的 由於負方向的指標運算完全合法, negative subscript(e.g. a[-1])完全符合 標準, 即使並不直觀。 所以 size_t 並不符合。主要因為它是無號整數, 不過其實也沒人說過它和指標有什 麼關聯。我們要找的是用在指標運算, 且有號的型別: http://goo.gl/1Xpf6x (www.gnu.org) Data Type: ptrdiff_t This is the signed integer type of the result of subtracting two pointers. For example, with the declaration char *p1, *p2;, the expression p2 - p1 is of type ptrdiff_t. This will probably be one of the standard signed integer types (short int, int or long int), but might be a nonstandard type that exists only for this purpose. 延續前面的例子, 假設 a 是 foo 的 array, 且索引取值後的結果是 b: b = a [ i ] ↑ ↑ ↑ foo foo[] ?? b = *( a + i ) ↑ ↑ ↑ foo foo[] ?? 令 *c = b, 則 c = a + i ↑ ↑ ↑ foo* foo[] ?? i = c - a 讓 a decay 為指標 ↑ ↑ ↑ ?? foo* foo* 根據上面的規範, i 的型別顯然應該是 ptrdiff_t。 -- 「我最想要的同伴嘛,首先是要笑口常開,其次是我們能永遠不會發生誤會。 如果這些都能辦到的話,嗯,如果他是世界上第一流的橋手,也還不錯。」 -- 班尼多‧加羅素,前義大利藍隊成員 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.161.94.175 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1412343985.A.BD3.html

10/03 22:10, , 1F
個人覺得選 size_t 的原因是出自「索引值」的語意
10/03 22:10, 1F

10/03 22:10, , 2F
ptrdiff_t 比較屬於「索引值的差」這個語意
10/03 22:10, 2F

10/04 00:08, , 3F
感謝您長篇的詳細回答,我可以理解成因為索引值可以是負的
10/04 00:08, 3F

10/04 00:08, , 4F
所以型態應該是ptrdiff_t
10/04 00:08, 4F

10/04 04:22, , 5F
這其實是STL一個長久以來的legacy issue...
10/04 04:22, 5F

10/04 04:23, , 6F
size_t被廣泛用在包含std::string::find這些地方
10/04 04:23, 6F

10/04 04:23, , 7F
但是如你所說 那我要表示-1怎麼辦?std::string就引入
10/04 04:23, 7F

10/04 04:23, , 8F
了一個叫做std::string::npos的常數 他是((uint)-1) XD
10/04 04:23, 8F

10/04 04:24, , 9F
只能說這似乎是將錯就錯的一種做法就是....
10/04 04:24, 9F

10/04 04:25, , 10F
所以std::string::find會傳回一些debugger上根本難以
10/04 04:25, 10F

10/04 04:25, , 11F
理解的東西 反正,它就叫做npos XD
10/04 04:25, 11F

10/04 04:26, , 12F
這個我想uranusjr應該也很清楚 只是當作故事說給其他
10/04 04:26, 12F

10/04 04:27, , 13F
可能沒聽過這件事的人參考一下就是 :P
10/04 04:27, 13F

10/04 04:27, , 14F
http://tinyurl.com/84ne58c 算C++的歷史包袱吧
10/04 04:27, 14F

10/04 04:28, , 15F
nonsense
10/04 04:28, 15F

10/05 01:58, , 16F
覺得是 nonsense 就講點 sense 出來, 不要只會嘴啊 ^_<
10/05 01:58, 16F

10/05 03:15, , 17F
K大提的那個是否可以用 boost::optional 解決?
10/05 03:15, 17F

10/05 03:16, , 18F
其實用非負整數作爲索引值新手最容易犯的錯是
10/05 03:16, 18F

10/05 03:16, , 19F
for(size_t idx = LEN; idx > 0; --idx) 這樣吧XD
10/05 03:16, 19F

10/05 13:56, , 20F
可以這樣說沒錯,所以find回來的值不能直接for XD
10/05 13:56, 20F

10/05 13:56, , 21F
不過很玄妙的是 STL絕大多數的library(有例外)比方說
10/05 13:56, 21F

10/05 13:56, , 22F
std::copy, std::transform, std::for_each都可以正確
10/05 13:56, 22F

10/05 13:57, , 23F
的handle string::npos(用iterator先包一層就沒這問題)
10/05 13:57, 23F

10/05 13:58, , 24F
早期的if系列某些實作會因為這些爆掉 如std::enable_if
10/05 13:58, 24F

10/05 13:59, , 25F
當然現在應該沒有錯誤的了... 再錯這STL也沒人用了 XD
10/05 13:59, 25F

10/05 22:51, , 26F
指標相減有可能是未定義行為. 這推導的前提不完整
10/05 22:51, 26F

10/05 22:53, , 27F
基本上陣列到底能有多大跟 ptrdiff_t 的範圍之類的
10/05 22:53, 27F

10/05 22:55, , 28F
硬要選 ptrdiff_t 當然是比較好. 但我覺得這問題本身nonsens
10/05 22:55, 28F

10/05 22:56, , 29F
opreator+ 跟 operator- 是否是真的反運算也是該討論的
10/05 22:56, 29F

10/05 23:05, , 30F
看不出 c = a + i 跟 i = c - a 的絕對關係. 可能是我想錯
10/05 23:05, 30F

10/05 23:13, , 31F
有沒有可能 a[i] 存在但是 c - a 的結果不存在呢 ?
10/05 23:13, 31F

10/05 23:17, , 32F
要想想 size_t 跟 ptrdiff_t 之間是實作相依
10/05 23:17, 32F

10/05 23:22, , 33F
ptrdiff_t 是 "相減" 的結果. 而 "加" 的對象只需要是整數
10/05 23:22, 33F

10/05 23:23, , 34F
加完之後還落在陣列內就是合法的.
10/05 23:23, 34F

10/05 23:24, , 35F
看不出來 "加" 的整數只能是 ptrdiff_t 的必然性.
10/05 23:24, 35F

10/05 23:27, , 36F
我好像有表達障礙. 抱歉. 喝酒不推文. 推文不喝酒 : (
10/05 23:27, 36F

10/05 23:29, , 37F
簡言之就是 sizeof(ptrdiff_t) < sizeof(size_t) 時就怪怪的
10/05 23:29, 37F

10/05 23:30, , 38F
我的看法就是索引值是整數型別. It's all
10/05 23:30, 38F

10/05 23:32, , 39F
重點是這個整數會不會落在陣列內才是我們應該關心的
10/05 23:32, 39F

10/05 23:34, , 40F
ptrdiff_t 並不能保證你會存取到你要的元素
10/05 23:34, 40F
文章代碼(AID): #1KBgYnlJ (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1KBgYnlJ (C_and_CPP)