三點要記住這裏:
static
變量到功能,只要他們首次
該變量返回創建堅持通過程序的整個持續時間也有後綴 ++操作符,意思是:「使用該值(即返回它)並將其遞增」AFTERWARDS「:不會返回遞增的值。
這就是爲什麼該變量具有所發生的事情的「記憶」,並得到增加。
- >爲什麼你看到「3 2 1」而不是「1 2 3」?
其中參數進行評估是不知道「先天」,它是給編譯器的順序決定吧,看https://stackoverflow.com/a/12960263/1938163
如果你真的想知道它是如何可能的值被第一返回,然後遞增,看看所生成的彙編代碼:
demo(): # @demo()
movl demo()::i, %eax # move i and put it into eax
movl %eax, %ecx # Move eax into ecx -> eax will be used/returned!
addl $1, %ecx # Increment ecx
movl %ecx, demo()::i # save ecx into i -> this is for the next round!
ret # returns!
main: # @main
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $0, -4(%rbp)
callq demo() # Call demo()
movl %eax, -8(%rbp) # save eax in rbp-8 (contains 1, demo::i is 2 for the next round)
callq demo() # Call demo()
movl %eax, -12(%rbp) # save eax in rbp-12 (contains 2, demo::i is 3 for the next round)
callq demo() # Call demo()
leaq .L.str, %rdi # load str address
movl -8(%rbp), %esi # esi points to 1
movl -12(%rbp), %edx # edx points to 2
movl %eax, %ecx # move eax (3) into ecx (demo::i is 4 but doesn't get used)
movb $0, %al # needed by the ABI to call printf
callq printf # call printf() and display 3 2 1
movl $0, %ecx
movl %eax, -16(%rbp)
movl %ecx, %eax
addq $16, %rsp
popq %rbp
ret
demo()::i:
.L.str:
.asciz "%d %d %d\n"
64位ABI使用寄存器(RDI,RSI,RDX,RCX,R8和R9),而不是堆棧參數傳遞。
postfix ++返回舊*值*,*和*增量*變量*。不要混淆這兩個概念。增量是操作員的副作用。 – Elazar
編譯此程序時,使用gcc的'-Wall'選項,它會向您顯示警告行爲可能未定義! – Nullpointer
與[此問題]很相似(http://stackoverflow.com/questions/21808791/struct-vrs-classes-padding-templates)問了一會兒。 – devnull