A. 什麼叫「編譯時」與「函數調用時」
望文生義。編譯時,應該就是在編譯的時候,此時程序處在生成狀態,函數調用老拍時,應該是指在程序運行的時判友候,有某個函數調用。結合具體的上下文掘含槐看看吧。
B. 程序開發中函數定義與調用的理解與運用
函數就是把特定的代碼整理到一個代碼塊裡面去,並起個名字,哪裡需要使用就調用這個名字。
一個函數定義是一個可執行的表達式, 執行結果是晌耐一個類型為 function 的值。 當 Lua 預編譯一個代碼塊時, 代碼塊作為一個函數,整個函數體也就被預編譯了。 那麼,無論何時 Lua 執行了函數定義, 這個函數本身就進行了 實例化(或者說是 關閉了)。 這個函數的實例(或者說是 閉包)是表達式的最終值。
形參被看作是一些局部變數, 它們將由實參的值來初始宴鬧春化
當一個函數被調用, 如果函數並非一個 可變參數函數, 即在形參列表的末章節附註明三個點 ('...'), 那麼實參列表就會被調整到形參列表的長度。 變長參數函數不會調整實參列表; 取而代之的是,它將把所有額外的參數放在一起通過 變長參數表達式傳遞給函數, 其寫法依舊是三個點。 這個表達式的值是一串實參值的列表, 看起來就跟一個可以返回多個結果的函數一樣。 如果一個變長參數表達式放在另一個表達式中使用, 或是放在另一串表達式的中間, 那麼它的返回值就會被調整為單個值。 若這個表達式放在了一系列表達式的最後一個, 就不會做調整了
結果由 return 來返回。 如果執行到函數末尾依舊沒有遇到任何 return 語句, 函數就不會返回任何結果。
關於函數可返回值的數量限制和系統有關。 這個限制一定大於 1000 。
冒號 語法可以用來定義 方法, 就是說,函數可以有一個隱式的形參 self。 因此,
函數調用時, 第一步,prefixexp 和 args 先被求值。 如果 prefixexp 的值的類型是 function, 那麼這個函數就被用給出的參數調用。 否則 prefixexp 的元方法 "call" 就被調用, 第一個參數是 prefixexp 的值,
所有參數的表達式求值都在函數調用之前。 這樣的調用形式 f{fields} 是一種語法糖用於表示 f({fields}); 這里指參數列表是一個新創建出來的列表。 而這樣的形式 f'string' (或是 f"string" 亦或是 f[[string]]) 也是一種語法糖,用於表示 f('string'); 此時的參數列表是一個單獨的字元串。
return functioncall 這樣的調用形式將彎掘觸發一次 尾調用。 Lua 實現了 完全尾調用(或稱為 完全尾遞歸): 在尾調用中, 被調用的函數重用調用它的函數的堆棧項。 因此,對於程序執行的嵌套尾調用的層數是沒有限制的。 然而,尾調用將刪除調用它的函數的任何調試信息。 注意,尾調用只發生在特定的語法下, 僅當 return 只有單一函數調用作為參數時才發生尾調用; 這種語法使得調用函數的所有結果可以完整地返回。
C. 使用什麼函數編譯器在編譯時並不生成真正的函數而將程序中每一個函數調用表達式直接用該函數的函數體替換
內聯函數是這樣。內聯函數在定義時函數頭前要用inline修飾,這樣的函數在編譯時一般將函數體直接插入到該函數的調用處。但這不是絕對的,智能編譯器會根據情況選擇。內聯函數的函數體不得寫行太復雜,好像不得有輸入輸出以及循環等語句,當寫入不允許的語句時編譯器就會編成一個獨立的函數。
D. C/C++語言中編譯階段,編譯到 函數調用的語句時,是怎麼編譯的
函數體被編譯成對應的一段匯編代碼,在符號表中會生成一個函數名指向這段代碼的入口地址。所有調用此函數的地方都會被編譯成CALL 函數名指令,然後連接時將函數名替換為函數的入口地址。
E. 什麼是函數調用C語言
通常在C語言中,一個完整的項目程序是不可能在一個函數中實現所有的功能。而是由若干功能不同的函數來實現,並且函數之間會存在互相調用的情況數遲。
函數是C語言的基本組成元素,如果你要想實現函數的功能,那麼你就必須學會正確調用函數。當我們調用一個函數時,需要明確函數名和實參列表。實參列表中的參數可以是常量、變數、表達式或者空,並且各參數之間要使用英文逗號分隔開來。
在數學運算中,會遇到計算多個連續自然數之間的和的情況。例如要計算1~n之間自然數之和,就需要先計算1加2的結果,用這個結果加3再得到一個結果,用新得到的結果加4,以此類推,直到用1~(n-1)之間所有數的和加n。
在程槐罩序開發中,要想完成上述功能,就需要使用函數的遞歸調用,所謂的遞歸調用就是函數內部調用自身的過程。需要注意的是,遞歸必須要求有結束條件,不然就會陷入薯明李無限遞歸的狀態,永遠無法結束調用。接下來通過一個計算自然數之和的案例來學習遞歸調用。
(5)函數編譯與函數調用擴展閱讀
在C++中,為了允許操作符重載和函數重載,C++編譯器往往按照某種規則改寫每一個入口點的符號名,以便允許同一個名字(具有不同的參數類型或者是不同的作用域)有多個用法,而不會打破現有的基於C的鏈接器。
這項技術通常被稱為名稱改編(Name Mangling)或者名稱修飾(Name Decoration)。許多C++編譯器廠商選擇了自己的名稱修飾方案。
F. 函數體裡面能調用函數嗎
「當然是可以的,最簡單的就是在主函數中調用另外一個自定義函數。
main函數中也不能定義函數,一個完整的函數至少包括函數名、返回值類型、函數體。把一個完整的函數定義到main()函數里編譯一下就知道了。
函數調用計算機編譯或運行時,使用某個函數來完成相關命令。對無參函數調用時則無實際參數表。實際參數表中的參數可以是常數、變數或其它構造類型數據及表達式,各實參之間用逗號分隔。
函數調用一般形式。
程序中通過對函數的調用來執行函數體,其過程與其它語言的子程序調用相似。C語言中,函數調用的一般形式為:函數名(實際參數表)對無參函數調用時則無實際參數表。實際參數表中的參數可以是常數、變數或其它構造類型數據及表達式。各實參之間用逗號分隔。
函數作為表達式中的一項出現在表達式中,以函數返回值參與表達式的運算。這種方式要求函數是有返回值的。例如:z=max(x,y)是一個賦值表達式,把max的返回值賦予變數z。
G. C語言中什麼叫調用函數為什麼函數和函數之間是調用關系
函數調用是指:簡單來講,假如小明是班長,小紅是本班的生活委員,小明要想收班費,但每個人都有不同的職責,而班長是用來組織和統籌工作的,而作為生活委員的小紅的職責之一就是收取和管理班費,所以這樣的話,小明只需讓小紅去做就行,也就是說只需發出指令給小紅就可以了,而小紅就是執行這項活動的承擔者;在這里小紅就相當於被調用函數,小明是調用函數。
函數調用總共有三種方式:
1.
函數表達式:
1函數作為表達式中的一項出現在表達式中,以函數返回值參與表達式的運算。這種方式要求函數是有返回值的。例如:z=max(x,y)是一個賦值表達式,把max的返回值賦予變數z。
2.
函數語句:
函數調用的一般形式加上分號即構成函數語句。例如:
printf
("%d",a);scanf
("%d",&b);都是以函數語句的方式調用函數。
3.
函數實參:
函數作為另一個函數調用的實際參數出現。這種情況是把該函數的返回值作為實參進行傳送,因此要求該函數必須是有返回值的。例如:
printf("%d",max(x,y));
即是把max調用的返回值又作為printf函數的實參來使用的。在函數調用中還應該注意的一個問題是求值順序的問題。所謂求值順序是指對實參表中各量是自左至右使用呢,還是自右至左使用。對此,各系統的規定不一定相同。
注意的是:1.假如在你的那句調用語句開始,例如:
#include
int
max(int
x,int
y){
if(x>y||x=y)
return
x;
else
return
y;
}
void
main(){
int
a,b;
scanf("%d%d",&a,&b)
;
printf("%d",max(a,b));
printf("程序結束\n");
}
在這個函數中,我們是在main()函數中用函數實參進行調用的,這樣的話。main()函數是一個程序的入口,
在執行
printf("%d",max(a,b));
這條語句的max(a,b)時候,開始轉到max(int,int)函數中執行,執行完後在回到printf("%d",max(a,b));
進行輸出a,b中的最大值,然後再接著執行main()函數的剩下語句
printf("程序結束\n");推出程序。但我們調用的時候,main()函數(即調用函數)需要給被調用函數提供必要的具體數據,即x,y的值。所以表達式max(a,b)即把a的值賦給x,b的值賦值給y;如此執行下去。
即若輸入
3
4
程序結果為:
4
程序結束
2.還是上面的那個例子,若int
max(int
x,int
y)在main()函數的下面,要調用的話,就需要在main()函數之前進行聲明,聲明格式為:
函數返回值類型
函數名
(形參類型1
形參名1,形參類型2
形參名2......);其中分號不可少,形參名可以省去,但是形參類型和返回值類型均不可省!!!如下所示:
#include
int
max(int
x,int
y);
//函數聲明1
或者int
max(int
,int
);
//函數聲明2
void
main(){
或者
int
max(int
x,int
y);
//函數聲明3
或者int
max(int
,int
);
//函數聲明4
int
a,b;
scanf("%d%d",&a,&b)
;
printf("%d",max(a,b));
printf("程序結束\n");
}
int
max(int
x,int
y){
if(x>y||x=y)
return
x;
else
return
y;
}
函數聲明的作用是讓調用函數認識被調用函數,這樣才可以想被調用函數發送指令!
至於為什麼用調用這個名字,個人覺得這個是因為很貼切吧,便於理解!!!
你明白了嗎?不明白可以追問哦!希望採納哦!
H. c語言函數調用規則
_stdcall是Pascal程序的預設調用方式,通常用於Win32 Api中,函數採用從右到左的壓棧方式,自己陸睜在退出時清空堆棧。VC將函數編譯後會在函數名前面加上下劃線前綴,在函數名後加上"@"和參數的位元組數。
_cdecl 按從右至左的順序壓參數入棧,由調用者把參數彈出棧。對於傳送參數的內存棧是由調用者來維護的(正因為如此,實現可變參數的函數只能使用該調用約定)是C和C++程序的默認調用約定。__cdecl調用約定僅在輸出函數名前加上一個下劃線棗納前綴,格式為_functionname。
_fastcall方式的函數採用寄存器傳遞參數,VC將函數編譯後會在函數名前面加上"@"前綴,在函數名後加上"@"和參數的位元組數。實際上,它用ECX和EDX傳送前兩個雙字(DWORD)或更小的參數,剩下的參數仍舊自右向左壓棧傳送,被調用的函數在返回前清理傳送參數的內存棧。__fastcall調用約定在輸出函數名前加上一凳悉沒個「@」符號,後面也是一個「@」符號和其參數的位元組數,格式為@functionname@number。
I. 一直有個疑惑,C/C++編譯器是如何調用函數的
函數的調用就是 跳轉到函數體的入口地址。
函數體本身的存儲空間是在exe里txt段,然後運行載入的時候映射到地址空間。不過看你的問題,你關注的不是這個的佔用。
關於你問的問題, 其實是因為一旦定義了虛函數,在C++類型的頭部,就會有一個指針的隱藏變數被定義,從而該類型的每個對象都會有這個變數的大小。 這個只有類型有和沒有虛函數的區別,虛函數的個數造成內存增長只是虛表裡(每class一個),每個對象里只是存的一個指針,不會有size變化。
對於非虛的函數,編譯的時候,直接就是填寫的函數體的入口地址; 而虛函數,則是要經過計算,先通過對象頭部寸的虛表指針找到虛表,再去找對應的虛表項 ,裡面存儲的就是需要的函數的入口地址。
建議樓主看看 C++布局方面的書,比如 <Inside C++ Object Model>, 以及平時多用VS操練一下調試技巧,然後適當熟悉簡單的匯編代碼,對融會貫通很有幫助。