Re: [討論] 大家都怎麼學STL?
※ 引述《loveme00835 (高髮箍)》之銘言:
[恕刪]
抱歉小弟只是針對loop的case聊一下天, 其實有點離題^^||
: 推 QQ29:請問for( int i 那個型態 要改成甚麼呢 09/25 20:53
: → diabloevagto:u_int 09/25 20:56
: → diabloevagto:array位址的變數不會有負 09/25 20:56
: → james732:我想 size_t 應該也可以? 09/25 20:57
: 推 stonehomelaa:size_t 09/25 22:05
: 推 Fenikso:可是用unsigned會不小心踩到一格洞 09/25 22:10
: → Fenikso:for(size_t i = n - 1; i >= 0; i--) {...} 爆炸 09/25 22:11
: → Fenikso:所以用signed int我覺得是比較好的選擇 09/25 22:11
: 推 tsiteowy:同意樓上 09/25 22:17
: for 通常都是計數用的
:
: for(size_t i = n - 1; i >= 0; --i) /**/;
:
: 以上的敘述雖可以反著尋訪元素, 但也多出了 n - 1 這樣離奇的敘述,
: 如果正向/反向交互使用, 個人覺得code會雜亂許多, STL 提供
小弟在我們家的driver看過這樣子的code(只是是ULONG)
然後就迴圈index underflow, 然後又做為array index讀寫....
跟著就BSOD了....XD
for loop也很常搭array index使用....
n-1 -> 0 或 0 -> n-1 有時只是演算法實作的選擇....
小弟倒是覺得寫n-1出現有時候無可厚非....
: std::reverse_iterator 配接器, 且多數容器皆提供rbegin()、rend()
: , 不用因判斷邊界條件錯誤而當機, 所以還蠻方便的!
:
: FIDS 加入了 std::array 模版, 更減少了魔法數字的使用
: ※ 編輯: loveme00835 來自: 140.121.197.115 (09/25 23:24)
: 推 Fenikso:當然是用iterator最好 09/25 23:32
: → Fenikso:只是看到很多人推size_t, 這樣寫真的要很小心.. 09/25 23:33
: 推 tropical72:love大那段size_t loop,指出了我在 C 還是選int的理由 09/25 23:46
: → uranusjr:for 迴圈計數器要用什麼形態是千古戰文, 挑別人這個錯誤 09/26 09:19
: → uranusjr:實在沒有意義, 第一部份會讓很多人莫名其妙中槍 -_- 09/26 09:19
: 推 developers:推C++ In-Depth Series,還有Meyers的Effective series 09/26 09:57
: 推 klandor:我有聽說有部門內部規定for一定要反向寫的 因為效率問題 09/26 23:37
: 推 tropical72:@klandor:反向效率會較佳的可能是? zero flag? 或其他? 09/26 23:39
: → firejox:減比加快 (我猜) 09/26 23:52
: 推 tropical72:減比加快??我以為減法器 ret要考慮補數問題比較慢說 XD 09/26 23:56
: 推 farmerlu:減和加是一樣快的, 但加/減之後要做判斷, 則減有可能快. 09/27 00:47
: → farmerlu:因 x86 組合語言有 loop 這個指令,減完會順便判斷到0了嗎 09/27 00:48
: → farmerlu:不知是不是指以上 compiler / 組語 的原因 ? 09/27 00:49
: 推 Ross0916:我沒有看過 compiler 編出 loop 指令的 原因不知@@ 09/27 01:17
: → Ross0916:應該不差那麼一點吧 還有 inc/dec 比 add/sub 慢.... 09/27 01:18
: 推 littleshan:loop只能跳前後128byte,現代的compiler早就沒在用了 09/27 01:19
: → cgcheng:inc/dec要比add/sub快吧?inc/dec最基本的 09/27 03:00
: 推 littleshan:其實是一樣快的 09/27 10:41
: 推 Ross0916:真的嗎 我是看某個 optimisation manual 看到的...忘了 09/27 18:46
小弟以前印象中也是認知inc/dec比add/sub快....
不過以現代的CPU來說到底還有沒有差就很難說了....
只是loop正著跑或倒著跑, 小弟以為還是跟算法比較有關....
但是一定要說的話, 倒不如說以 0 為compare的對象會比較有效率....
所以n-1 -> 0每個都要跑, 倒著跑快一點; 負數 -> 0, 或許正著跑快些....
理由是t大提到的zero flag, 然後剛查了一下還有sign flag....
以下貼兩段VC2008 release build, 跑迴圈從0~9與9~0的disasm code:
/* for(i=0; i<10; ++i) */
#include <stdio.h>
int main()
{
00401000 push esi
00401001 push edi
int i;
for(i=0; i<10; ++i)
00401002 mov edi,dword ptr [__imp__printf (4020A0h)]
00401008 xor esi,esi
0040100A lea ebx,[ebx]
{
printf("%d\n", i);
00401010 push esi
00401011 push offset string "%d\n" (4020F4h)
00401016 call edi
00401018 add esi,1
0040101B add esp,8
0040101E cmp esi,0Ah
00401021 jl main+10h (401010h)
00401023 pop edi
}
return 0;
00401024 xor eax,eax
00401026 pop esi
}
00401027 ret
/* for(i=10-1; i>=0; --i) */
#include <stdio.h>
int main()
{
00401000 push esi
00401001 push edi
int i;
for(i=10-1; i>=0; --i)
00401002 mov edi,dword ptr [__imp__printf (4020A0h)]
00401008 mov esi,9
0040100D lea ecx,[ecx]
{
printf("%d\n", i);
00401010 push esi
00401011 push offset string "%d\n" (4020F4h)
00401016 call edi
00401018 add esp,8
0040101B sub esi,1
0040101E jns main+10h (401010h)
00401020 pop edi
}
return 0;
00401021 xor eax,eax
00401023 pop esi
}
00401024 ret
以上, 只是效率是不是真的卡在這一條asm的差異, 就....^^||
另外, 迴圈用i++還是++i, 這個case下build出來的asm一模一樣XD
==
抱歉離題佔用版面....<(_ _)>
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.134.18.177
※ 編輯: VictorTom 來自: 220.134.18.177 (09/28 00:37)
推
09/28 00:40, , 1F
09/28 00:40, 1F
→
09/28 00:42, , 2F
09/28 00:42, 2F
推
09/28 00:50, , 3F
09/28 00:50, 3F
推
09/29 12:21, , 4F
09/29 12:21, 4F
→
09/29 22:30, , 5F
09/29 22:30, 5F
討論串 (同標題文章)