C 手稿 函式與引數

2021-07-04 16:46:42 字數 1622 閱讀 2972

在函式宣告中可以設定若干個預設引數,這些引數在函式呼叫時可以省略。例如:

void

print

(inta=

3,intb=4

)print

();// 3 4

print(4

);// 4 4

print(,3

);// compile error

預設引數提供了更靈活的函式宣告。簡化函式邏輯的同時,也提供了一種擴充套件既有函式的方式。

在很多情況下,函式的宣告與定義是分開的。語法上講我們可以在宣告時給出缺省引數, 也可以在定義時給出缺省引數。然而在函式呼叫處,編譯器會進行語法檢查, 被呼叫的「函式簽名」是否存在、是否有歧義,只取決於呼叫處可見的那個函式(宣告或定義)。

我們知道可以通過引數個數的不同來進行函式過載。唯一需要注意的是過載函式呼叫的二義性。 通過引數個數進行過載的函式被呼叫時,便有可能存在歧義。例如:

void

print

(inta=

1){}

void

print

(inta=

1,intb=2

){}print

();

同時定義上述兩個print函式沒有問題,因為它們的函式簽名是不同的。但print()的呼叫存在歧義,此處會發生編譯錯誤。 因此,使用預設引數時,要避免函式過載的二義性。

除了虛函式外,函式呼叫的函式位址是在編譯期決定的。

可變引數是指乙個函式可以接受可變數目的引數,在c語言中最常見的便是printfscanf。 它們是如何實現的呢?

當然這不是函式過載,我們只定義乙個函式,它可以接受任意個引數。

我們知道函式呼叫前需要將引數壓棧,預設情況下c++會將引數從右向左順序壓棧。 棧空間是從高位址向低位址生長的,故第乙個引數擁有最低的位址。 獲取第乙個引數後,我們只要知道後續引數的型別和個數,就可以逐個按照位址取出來。

在dll生成和跨語言的過程呼叫時,常常遇到壓棧順序和由誰清空引數棧的問題,它們可以在函式宣告中加入類似_stdcall_cdecl等關鍵字來指定。

如何定義乙個可變引數的函式?c++提供了stdarg.h標頭檔案,它定義了若干巨集來方便上述的操作。 首先使用va_list來獲取引數棧,va_start來指定第乙個引數的位址。 此後便可以使用va_arg()來獲取後續的引數了,這時需要指定型別(因為需要確定空間大小)。 最後用va_end來釋放資源。乙個簡單的可變引數的函式像這樣:

#include 

void

my_print

(int

count

,...)

第乙個引數是必不可少的,我們需要用它來確定引數的個數。

python函式大全手稿

floor round ceil max min sum abs divmod 獲取商和餘數 pow index count upper lowwer swapcase capitalize eval exec help isinstance issubclass globals reversed ...

C 手稿 運算子過載

運算子過載就是對已有的c 運算子賦予更多的語義,讓乙個運算子可以作用於其他的資料型別。典型地,讓運算子接受乙個類的物件作為引數。通常有兩種方式來過載乙個運算子 宣告乙個普通函式,作為類的友元。宣告為類的成員方法。事實上,運算子的本質是函式。每個運算子呼叫會轉換為函式呼叫,運算子的運算元轉換為函式引數...

c 函式指標與預設引數

include using namespace std inline void printa void printb int int a 4 void printc int a,int b,int c 3,int d 4 預設引數寫右邊 typedef void mytypefunc int a,i...