欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

C之函數(shù)參數(shù)(三十九)-創(chuàng)新互聯(lián)

    我們上節(jié)博文講了函數(shù)的意義,那么我們今天來講下函數(shù)參數(shù)。函數(shù)參數(shù)在本質上與局部變量相同在棧上分配空間,函數(shù)參數(shù)的初始值是函數(shù)調用時的實參值。用下圖來實際說明

為蘆溪等地區(qū)用戶提供了全套網(wǎng)頁設計制作服務,及蘆溪網(wǎng)站建設行業(yè)解決方案。主營業(yè)務為成都網(wǎng)站設計、網(wǎng)站制作、蘆溪網(wǎng)站設計,以傳統(tǒng)方式定制建設網(wǎng)站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

C之函數(shù)參數(shù)(三十九)

        函數(shù)參數(shù)的求值順序依賴于編譯器的實現(xià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("%d\n", k);
    
    return 0;
}

        我們理論上分析,func 函數(shù)先進行 k++,那么 i 就對應為 1,再次進行 k++,對應于 j 為 2。那么第 14 行應打印 i = 1, j = 2,。這時 k 為 3,所以第 16 行打印的值應為 3。我們來看看編譯結果是否如我們所分析的那樣,編譯結果如下

C之函數(shù)參數(shù)(三十九)

        我們看到 i 和 j 和我們所分析的正好相反,那么這是怎么回事呢?原來在gcc 編譯器中,函數(shù)參數(shù)的實現(xiàn)是從右向左進行操作的,并非是我們所想的從左向右進行計算的。我們再在 BCC 編譯器中進行編譯,看看結果是怎樣?

C之函數(shù)參數(shù)(三十九)

        那么我們看到在 BCC 編譯器中也是這樣實現(xiàn)的。函數(shù)參數(shù)的操作是從右向左的,在現(xiàn)代的編譯器中,基本上是按照從右向左的順序進行函數(shù)參數(shù)的操作的。在一些古老的編譯器中,也有從左向右的實現(xiàn),這個的實現(xiàn)就依賴于具體的編譯器的實現(xiàn)了。

        下來我們來講一個 C 語言中的知識點:順序點!那么在程序中存在一定的順序點,順序點是指執(zhí)行過程中修改變量值的最晚時刻,在程序到達順序點的時候,之前所做的一切操作必須完成。那么 C 語言中的順序點都在那些時刻呢?a> 每個完整表達式結束時,即分號處;b> &&,||,?: 以及逗號表達式的每個參數(shù)計算之后;c> 函數(shù)調用時所有實參求值完成后(即進入函數(shù)之前);

        下面我們以代碼為例進行分析,代碼如下

#include <stdio.h>

int main()
{
    int k = 2;
    int a = 1;
    
    k = k++ + k++;
    
    printf("k = %d\n", k);
    
    if( a-- && a )
    {
        printf("a = %d\n", a);
    }
    
    return 0;
}

        我們看到第 8 行的進行兩次 k++ 的相加,我們分析結果應該為 5;第 12 行的 a-- 執(zhí)行完之后 a 為 0,但是此時它和 a 相與之后條件仍然為真,所以 第14行應該打印出 a = 0;我么來看看結果是這樣嗎?

C之函數(shù)參數(shù)(三十九)

        那么我們看到我們分析的第一個是正確的,但是 a = 0 并沒有打印出來,我們再來看看 BCC 編譯器是多少

C之函數(shù)參數(shù)(三十九)

        我們看到竟然 k = 6,a = 0 依然沒有打印出來。我們再來看看 VS 編譯器

C之函數(shù)參數(shù)(三十九)

        我們進到反匯編看看它是怎么執(zhí)行的

C之函數(shù)參數(shù)(三十九)


        我們看到它是這樣執(zhí)行的,先是進行相加操作,這時的++操作被懸掛起來,程序看到;才意識到到了順序點了,所以執(zhí)行完那兩次++操作,所以最后 k 的值為6。我們再來看看第14行怎么執(zhí)行的

C之函數(shù)參數(shù)(三十九)

        我們看到它是執(zhí)行完 a-- 后看到 && 操作便意識到順序點到了,便返回了。那么這時 a 的值已經變?yōu)?0 了,此時 if 語句條件為假,所以不會執(zhí)行到它里面的打印語句。

        下來我們再來看看參數(shù)入棧的順序,函數(shù)參數(shù)的計算次序是依賴編譯器實現(xiàn)的。那么函數(shù)參數(shù)的入棧次序是如何確定的呢?這塊就涉及到里一個概念:調用約定。當函數(shù)調用發(fā)生時:a> 參數(shù)會傳遞給被調用的函數(shù);b> 而返回值會被返回給函數(shù)調用者;調用約定描述參數(shù)如何傳遞到棧中以及棧的維護方式,參數(shù)傳遞順序,調用棧清理。

       調用約定是預定義的可理解為調用協(xié)議,調用約定通常用于庫調用和庫開發(fā)的時候。我們來看看一些常用的操作:a>從右到左依次入棧:__stfcall, __cdecl, __thiscall;b> 從左到右依次入棧:__pascall, __fastcall;那么我們一般的 C 程序開發(fā)遵循的就是上面的 __cdecl 這種方式的。

        那么我們如果要編寫一個計算平均數(shù)的函數(shù),我們肯定首先想到的是下面這種

#include <stdio.h>

float average(int array[], int size)
{
    int i = 0;
    float avr = 0;
    
    for(i=0; i<size; i++)
    {
        avr += array[i];
    }
    
    return avr / size;
}

int main()
{
    int array[] = {1, 2, 3, 4, 5};
    
    printf("%f\n", average(array, 5));
    
    return 0;
}

        我們利用一個數(shù)組就完成這個功能,那么我們還得去定義一個數(shù)組。有什么辦法可以使我們不用定義數(shù)組就可以完成這個功能呢?答案就是我們可以利用可變參數(shù)的函數(shù)來實現(xiàn)這個功能。在 C 語言中可以定義參數(shù)可變的函數(shù),參數(shù)可變函數(shù)的實現(xiàn)依賴于 stdarg.h 頭文件。我們得介紹幾個概念:a> va_list -- 參數(shù)集合;b> va_arg -- 取具體參數(shù)值;c> va_start -- 標識參數(shù)訪問的開始;d> va_end -- 標識參數(shù)訪問的結束;

        下來我們來看看可變參數(shù)版的程序是怎樣實現(xiàn)的,代碼如下

#include <stdio.h>
#include <stdarg.h>

float average(int n, ...)
{
    va_list args;
    int i = 0;
    float sum = 0;
    
    va_start(args, n);
    
    for(i=0; i<n; i++)
    {
        sum += va_arg(args, int);
    }
    
    va_end(args);
    
    return sum / n;
}

int main()
{
    printf("%f\n", average(5, 1, 2, 3, 4, 5));
    printf("%f\n", average(4, 1, 2, 3, 4));
    
    return 0;
}

        我們在第 6 行定義了 args 參數(shù),在第 10 行開始,14 行進行參數(shù)的相加,在 17 行結束。我們來看看第24, 25 行的這樣的定義可行嗎?來看看編譯結果

C之函數(shù)參數(shù)(三十九)

        結果已經正確實現(xiàn)了,這樣是不是很方便呢?我們可以隨時定義它的大小和內容。那么可變參數(shù)也有限制:a> 可變參數(shù)必須從頭到尾按照順序逐個訪問;b> 參數(shù)列表中至少要存在一個確定的命名參數(shù);c> 可變參數(shù)函數(shù)無法確定實際存在的參數(shù)的數(shù)量,同樣也無法確定參數(shù)的實際類型,只能我們手動指定;注意:va_arg 中指定了錯誤的類型,那么結果是不可預測的!

        通過對函數(shù)參數(shù)的學習,總結如下:1、函數(shù)的參數(shù)在棧上分配空間;2、函數(shù)的實參并沒有固定的計算次序;3.順序點是 C 語言中變量修改的最晚時機;4、調用約定指定了函數(shù)參數(shù)的入棧順序以及棧的清理方式;5、可變參數(shù)的函數(shù)提供了一種函數(shù)設計技巧,提供了一種更方便的函數(shù)調用方式;6、可變參數(shù)必須順序的訪問,無法直接訪問中間的參數(shù)值。

        歡迎大家一起來學習 C 語言,可以加我QQ:243343083。

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

網(wǎng)站名稱:C之函數(shù)參數(shù)(三十九)-創(chuàng)新互聯(lián)
網(wǎng)頁鏈接:http://aaarwkj.com/article34/cogppe.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供ChatGPT、微信小程序品牌網(wǎng)站設計、全網(wǎng)營銷推廣、App開發(fā)、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網(wǎng)站建設
黄片大全在线免费视频观看| 欧美一区二区三区久久束缚| 欧美日本一道本一区二区三区| 91成年精品一区在线观看| av中文字幕啊嗯不要| 偷窥偷拍原味一区二区三区| 国产美女口爆吞精久久| 亚洲一区二区福利视频| 欧美特黄在线免费观看| 亚洲国产综合亚洲综合国产| 国产女主播在线观看一区| 精品国产乱码久久蜜桃| 亚洲国产中文日韩欧美在线| 偷拍丝袜美腿在线观看| 日韩一二卡在线观看视频| 男女在线视频网站免费| 粉嫩欧美一区二区三区| 国产伦奸在线播放免费| 精品国产亚洲av未满十八| 99热在线精品国产观看| 人妻熟女一区二区视频| 久久国产精品成人av| 日韩三级视频一区二区| 亚洲欧美精品一区二区三区| 久久好大好爽要死了欧美| 亚洲av蜜臀在线播放| 精品国产欧美成人一区| 中文字幕在线视频黄字幕| 国产日韩精品综合一区| 亚洲精品成人综合色在线| 日韩一区二区精品网站| 精品国产乱码一区二区三区四区| 国产av超爽剧情系列| 中文字幕乱码日韩一区| 夫妻性生活视频一级片| 亚洲精品啪啪一区二区| 人妻口爆视频一区二区三区| 亚洲中文字幕视频在看| 正在播放蜜臀av在线| 久久精品亚洲毛片美女极品| 在线高清视频无卡不码|