1. 函數(shù)參數(shù)
- 函數(shù)參數(shù)在本質(zhì)上與局部變量相同在棧上分配空間番刊;
- 函數(shù)參數(shù)的初始值是函數(shù)調(diào)用時(shí)的實(shí)參值
- 函數(shù)參數(shù)的求值順序依賴(lài)于編譯器的實(shí)現(xiàn)(如下面的面試題)蚁廓;
// 函數(shù)求值順序問(wèn)題
#include <stdio.h>
int func(int i, int j)
{
printf("i = %d, j = %d\n", i, j);
return 0;
}
int main()
{
int k = 1;
func(k++, k++);
printf("k = %d\n", k);
return 0;
}
輸出結(jié)果:
i = 2, j = 1
k = 3
總結(jié):在C語(yǔ)言中觅捆,函數(shù)的求值順序是依賴(lài)于編譯器的先舷,并不是規(guī)律了從左向右的求值順序。上面程序中func(k++, k++);先求出了第二個(gè)k++途乃,然后再求出了第一個(gè)k++。
這個(gè)結(jié)論也使用C語(yǔ)言中的操作符幻枉,操作符中的求值順序也是依賴(lài)于編譯器碰声。
2. 程序中的順序點(diǎn)
- 程序中存在一定的順序點(diǎn)
- 順序點(diǎn)指的是執(zhí)行過(guò)程中修改變量值的最晚時(shí)刻
- 在程序到達(dá)順序點(diǎn)的時(shí)候, 之前所做的一切操作必須完成
- C語(yǔ)言中的順序點(diǎn)
(1)每個(gè)完整表達(dá)式結(jié)束時(shí)熬甫,即分號(hào)處
(2)&&胰挑, ||, ?:罗珍,以及逗號(hào)表達(dá)式的每個(gè)參數(shù)計(jì)算之后
(3)函數(shù)調(diào)用時(shí)所有實(shí)參求值完成后(進(jìn)入函數(shù)體之前)
程序說(shuō)明:C語(yǔ)言中的順序點(diǎn)
// 下面的程序運(yùn)行結(jié)束后k的值為多少洽腺?
#include <stdio.h>
int main()
{
int k = 2;
k = k++ + k++;
printf("k = %d\n", k);
return 0;
}
輸出結(jié)果:
在ubuntu10中:k = 6
在ubuntu14中: k = 5
總結(jié):在程序運(yùn)行中,必然存在一個(gè)時(shí)間點(diǎn)覆旱,在這個(gè)時(shí)間點(diǎn)前,所有對(duì)內(nèi)存操作必須完成核无。代碼中: k = k++ + k++; 兩個(gè)k++和一個(gè)加法運(yùn)算這三個(gè)操作會(huì)改變k所代表的內(nèi)存中的值扣唱,代碼中的順序點(diǎn)為";",在ubuntu10中团南,操作方式為:先做加法運(yùn)算噪沙,其左右操作數(shù)為都為k,而將k的自增運(yùn)算懸掛著吐根,加法運(yùn)算結(jié)束后正歼,再完成完成兩個(gè)自增運(yùn)算,所以結(jié)果為6拷橘。而在ubuntu14中局义,操作方式為:先做兩個(gè)自增運(yùn)算,最后做加法運(yùn)算冗疮,所以結(jié)果為5萄唇。
3 小結(jié)
- 函數(shù)的參數(shù)在棧上分配空間,本質(zhì)和局部變量一樣术幔;
- 函數(shù)的實(shí)參并沒(méi)有固定的計(jì)算次序另萤,是依賴(lài)于編譯器的實(shí)現(xiàn);
- 順序點(diǎn)是C語(yǔ)言中變量修改的最晚時(shí)機(jī)诅挑。