| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1712 人关注过本帖
标题:看看三目运算符?:到底是怎么回事
取消只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
结帖率:100%
收藏
 问题点数:0 回复次数:6 
看看三目运算符?:到底是怎么回事
程序代码:
void main(void)
{
    int a = 1;
    int b = 2;
    int max;

    max = (a > b) ? a : b;
}


下面是编译得到的汇编代码:

程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE    c:\Users\TonyDeng\documents\visual studio 2010\Projects\test4\test4\test.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    _main
EXTRN    __RTC_Shutdown:PROC
EXTRN    __RTC_InitBase:PROC
;    COMDAT rtc$TMZ
; File c:\users\tonydeng\documents\visual studio 2010\projects\test4\test4\test.cpp
rtc$TMZ    SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ    ENDS
;    COMDAT _main
_TEXT    SEGMENT
tv65 = -232                        ; size = 4
_max$ = -32                        ; size = 4
_b$ = -20                        ; size = 4
_a$ = -8                        ; size = 4
_main    PROC                        ; COMDAT

; 2    : {

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    81 ec e8 00 00
    00         sub     esp, 232        ; 000000e8H
  00009    53         push     ebx
  0000a    56         push     esi
  0000b    57         push     edi
  0000c    8d bd 18 ff ff
    ff         lea     edi, DWORD PTR [ebp-232]
  00012    b9 3a 00 00 00     mov     ecx, 58            ; 0000003aH
  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001c    f3 ab         rep stosd

; 3    :     int a = 1;

  0001e    c7 45 f8 01 00
    00 00         mov     DWORD PTR _a$[ebp], 1

; 4    :     int b = 2;

  00025    c7 45 ec 02 00
    00 00         mov     DWORD PTR _b$[ebp], 2

; 5    :     int max;
; 6    :
; 7    :     max = (a > b) ? a : b;

  0002c    8b 45 f8     mov     eax, DWORD PTR _a$[ebp]
  0002f    3b 45 ec     cmp     eax, DWORD PTR _b$[ebp]
  00032    7e 0b         jle     SHORT $LN3@main
  00034    8b 4d f8     mov     ecx, DWORD PTR _a$[ebp]
  00037    89 8d 18 ff ff
    ff         mov     DWORD PTR tv65[ebp], ecx
  0003d    eb 09         jmp     SHORT $LN4@main
$LN3@main:
  0003f    8b 55 ec     mov     edx, DWORD PTR _b$[ebp]
  00042    89 95 18 ff ff
    ff         mov     DWORD PTR tv65[ebp], edx
$LN4@main:
  00048    8b 85 18 ff ff
    ff         mov     eax, DWORD PTR tv65[ebp]
  0004e    89 45 e0     mov     DWORD PTR _max$[ebp], eax

; 8    : }

  00051    33 c0         xor     eax, eax
  00053    5f         pop     edi
  00054    5e         pop     esi
  00055    5b         pop     ebx
  00056    8b e5         mov     esp, ebp
  00058    5d         pop     ebp
  00059    c3         ret     0
_main    ENDP
_TEXT    ENDS
END
搜索更多相关主题的帖子: Microsoft generated documents visual Users 
2011-09-04 10:31
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
以下是传统判断语句的结果:

程序代码:
void main(void)
{
    int a = 1;
    int b = 2;
    int max;

    if (a > b)
    {
        max = a;
    }
    else
    {
        max = b;
    }
}


程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE    c:\Users\TonyDeng\documents\visual studio 2010\Projects\test4\test4\test.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    _main
EXTRN    __RTC_Shutdown:PROC
EXTRN    __RTC_InitBase:PROC
;    COMDAT rtc$TMZ
; File c:\users\tonydeng\documents\visual studio 2010\projects\test4\test4\test.cpp
rtc$TMZ    SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
; Function compile flags: /Odtp /RTCsu /ZI
rtc$IMZ    ENDS
;    COMDAT _main
_TEXT    SEGMENT
_max$ = -32                        ; size = 4
_b$ = -20                        ; size = 4
_a$ = -8                        ; size = 4
_main    PROC                        ; COMDAT

; 2    : {

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    81 ec e4 00 00
    00         sub     esp, 228        ; 000000e4H
  00009    53         push     ebx
  0000a    56         push     esi
  0000b    57         push     edi
  0000c    8d bd 1c ff ff
    ff         lea     edi, DWORD PTR [ebp-228]
  00012    b9 39 00 00 00     mov     ecx, 57            ; 00000039H
  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001c    f3 ab         rep stosd

; 3    :     int a = 1;

  0001e    c7 45 f8 01 00
    00 00         mov     DWORD PTR _a$[ebp], 1

; 4    :     int b = 2;

  00025    c7 45 ec 02 00
    00 00         mov     DWORD PTR _b$[ebp], 2

; 5    :     int max;
; 6    :
; 7    :     if (a > b)

  0002c    8b 45 f8     mov     eax, DWORD PTR _a$[ebp]
  0002f    3b 45 ec     cmp     eax, DWORD PTR _b$[ebp]
  00032    7e 08         jle     SHORT $LN2@main

; 8    :     {
; 9    :         max = a;

  00034    8b 45 f8     mov     eax, DWORD PTR _a$[ebp]
  00037    89 45 e0     mov     DWORD PTR _max$[ebp], eax

; 10   :     }
; 11   :     else

  0003a    eb 06         jmp     SHORT $LN3@main
$LN2@main:

; 12   :     {
; 13   :         max = b;

  0003c    8b 45 ec     mov     eax, DWORD PTR _b$[ebp]
  0003f    89 45 e0     mov     DWORD PTR _max$[ebp], eax
$LN3@main:

; 14   :     }
; 15   : }

  00042    33 c0         xor     eax, eax
  00044    5f         pop     edi
  00045    5e         pop     esi
  00046    5b         pop     ebx
  00047    8b e5         mov     esp, ebp
  00049    5d         pop     ebp
  0004a    c3         ret     0
_main    ENDP
_TEXT    ENDS
END


授人以渔,不授人以鱼。
2011-09-04 10:33
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
1楼的汇编代码文件是2210byte,2楼的是2158byte。

熟悉汇编的请分析一下哪个的效率较高?

授人以渔,不授人以鱼。
2011-09-04 10:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 5楼 pangding
等我开优化再看看如何.

授人以渔,不授人以鱼。
2011-09-04 20:03
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 8楼 dreamofgod
不知道,VS2010就出来这样的。有其它编译器的朋友可以试一试。

授人以渔,不授人以鱼。
2011-09-04 20:04
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
打开全局优化和速度优先是这样:

程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

    TITLE    C:\Users\TonyDeng\Documents\Visual Studio 2010\Projects\test4\test4\test.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB OLDNAMES

EXTRN    @__security_check_cookie@4:PROC
PUBLIC    _main
; Function compile flags: /Odtp /RTCsu
; File c:\users\tonydeng\documents\visual studio 2010\projects\test4\test4\test.cpp
_TEXT    SEGMENT
tv65 = -16                        ; size = 4
_max$ = -12                        ; size = 4
_b$ = -8                        ; size = 4
_a$ = -4                        ; size = 4
_main    PROC

; 2    : {

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    83 ec 10     sub     esp, 16            ; 00000010H
  00006    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0000b    89 45 f0     mov     DWORD PTR [ebp-16], eax
  0000e    89 45 f4     mov     DWORD PTR [ebp-12], eax
  00011    89 45 f8     mov     DWORD PTR [ebp-8], eax
  00014    89 45 fc     mov     DWORD PTR [ebp-4], eax

; 3    :     int a = 1;

  00017    c7 45 fc 01 00
    00 00         mov     DWORD PTR _a$[ebp], 1

; 4    :     int b = 2;

  0001e    c7 45 f8 02 00
    00 00         mov     DWORD PTR _b$[ebp], 2

; 5    :     int max;
; 6    :
; 7    :     max = (a > b) ? a : b;

  00025    8b 45 fc     mov     eax, DWORD PTR _a$[ebp]
  00028    3b 45 f8     cmp     eax, DWORD PTR _b$[ebp]
  0002b    7e 08         jle     SHORT $LN3@main
  0002d    8b 4d fc     mov     ecx, DWORD PTR _a$[ebp]
  00030    89 4d f0     mov     DWORD PTR tv65[ebp], ecx
  00033    eb 06         jmp     SHORT $LN4@main
$LN3@main:
  00035    8b 55 f8     mov     edx, DWORD PTR _b$[ebp]
  00038    89 55 f0     mov     DWORD PTR tv65[ebp], edx
$LN4@main:
  0003b    8b 45 f0     mov     eax, DWORD PTR tv65[ebp]
  0003e    89 45 f4     mov     DWORD PTR _max$[ebp], eax

; 8    : }

  00041    33 c0         xor     eax, eax
  00043    8b e5         mov     esp, ebp
  00045    5d         pop     ebp
  00046    c3         ret     0
_main    ENDP
_TEXT    ENDS
END

授人以渔,不授人以鱼。
2011-09-04 20:14
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
回复 8楼 dreamofgod
查了一下資料,據説根據運算是否生成邏輯結果0、1,與目標機器有關,那個東西可能是修正這個問題的。

從彙編碼看,三目運算的效率其實及不上判斷語句:按資料的説法,三目運算符實際上被編譯器擴展為if語句,並非源代碼看到的那樣,從而警告我們說不要以爲“一行清”代碼等價于高效,事實往往相反。從我編程的實踐來看也確實是這樣的——執行效率與代碼量是守恆的,高效的算法代碼經常是碼字量大的。其實有一個很簡單的例子就可以説明這個問題,一百行賦值語句比三行的循環語句快。

無論多複雜的程序,在控制臺下,也不過是一條(行)指令而已。由此可見,命令的行數與實際動作之間其實沒有必然聯係的,千萬不要以爲寫出來的文字(代碼)行數很少,就意味著執行的效率也高。printf()函數在你看來只是一個“固有的”指令,但其實它的彙編代碼成千上萬行(機器碼有2Kbyte以上,"Hello,world"程序編譯出來有8kbyte之大),是一個很複雜低效的小型解釋器(類似于BASIC解釋執行語句的設計)。同樣的輸出程序,如果你僅輸出字符串,用puts()比printf()高效得多,無論時間還是空間都是如此;就算輸出複雜的數據,用write()也比printf()強。

[ 本帖最后由 TonyDeng 于 2011-9-11 13:19 编辑 ]

授人以渔,不授人以鱼。
2011-09-11 12:54
快速回复:看看三目运算符?:到底是怎么回事
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.041751 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved