亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

函數聲明與原型的替代(K&R)C語法

函數聲明與原型的替代(K&R)C語法

C
白衣非少年 2019-06-15 13:40:05
函數聲明與原型的替代(K&R)C語法這有什么用?C語法-使用‘K&R’風格的函數聲明?int func (p, p2)     void *p;     int  p2;{     return 0;}我在VisualStudio2010測試版上寫了這篇文章//yes the params are flippedvoid f(){     void *v=0;     func(5,v);}我不明白。這種語法有什么意義?我可以寫:int func (p, p2)     int  p2;{     return 0;}//and writeint func (p, p2){     return 0;}它似乎唯一指定的是它使用了多少參數和返回類型。我想沒有類型的參數是很酷的,但是為什么允許它和int paranName在函數聲明器之后?很奇怪。這還是標準C嗎?
查看完整描述

3 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

你提出的問題實際上是兩個問題,而不是一個問題。到目前為止,大多數回復都試圖用通用的毯子“這是K&R風格”來回答整個問題,而實際上只有一小部分與所謂的K&R風格有關(除非你以某種方式將整個C語言看作是“K&R風格”):

第一部分是函數中使用的奇怪語法。定義

int func(p, p2)void *p;int  p2; /* <- optional in C89/90, but not in C99 */{
  return 0;}

這是一個K&R型函數的定義。其他答案也很好地說明了這一點。其實也沒什么大不了的。語法不受歡迎,但即使在C99中仍然完全支持(C99中的“無隱式int”規則除外),這意味著在C99中您不能省略p2).

第二部分與K&R風格無關。我指的是可以用“交換”參數調用函數,即在這樣的調用中不進行參數類型檢查。這與K&R風格的定義本身沒有什么關系,但它與您的功能沒有原型有關。您看,在C中,當您聲明這樣的函數時

int foo();

它實際上聲明了一個函數foo這需要未知類型的未指定數目的參數..你可以稱之為

foo(2, 3);

和AS

j = foo(p, -3, "hello world");

ANS等等(你有這個想法);

只有帶有適當參數的調用才能“工作”(這意味著其他調用會產生未定義的行為),但完全由您來確保其正確性。即使編譯器以某種方式神奇地知道正確的參數類型及其總數,也不需要對不正確的參數進行診斷。

實際上,這種行為是特征C語言。一個危險的,但仍然是一個特征。它允許你做這樣的事情

void foo(int i);void bar(char *a, double b);void baz(void);int main(){
  void (*fn[])() = { foo, bar, baz };
  fn[0](5);
  fn[1]("abc", 1.0);
  fn[2]();}

也就是說,在沒有任何類型轉換的“多態”數組中混合不同的函數類型(不過,在這里不能使用各種函數類型)。同樣,這種技術的內在危險是顯而易見的(我不記得曾經使用過它,但我可以想象它在哪里是有用的),但這畢竟是C。

最后,將答案的第二部分與第一部分聯系起來的位。當你做一個K&R風格的函數定義時,它不會為這個函數引入一個原型。就函數類型而言,func定義聲明func

int func();

也就是說,既不聲明參數的類型,也不聲明參數的總數。在您最初的帖子中,您會說“.它似乎指定了它使用了多少個參數.”。從形式上說,它不是!在你的雙參數K&R風格之后func定義仍然可以調用func

func(1, 2, 3, 4, "Hi!");

也不會有任何違反約束的地方。(通常,高質量的編譯器會給您一個警告)。

另外,一個有時被忽視的事實是

int f(){
  return 0;}

也是一個K&R風格的函數定義,不引入原型。要使它成為“現代”,你必須明確地指出void在參數列表中

int f(void){
  return 0;}

最后,與流行的觀點相反,在C99中完全支持K&R風格的函數定義和非原型函數聲明。如果我沒記錯的話,前者自C89/90以來就被否決了。C99要求在第一次使用之前聲明函數,但聲明不需要是原型。這種混淆顯然源于流行的術語混淆:許多人稱任何函數聲明為“原型”,而實際上“函數聲明”與“原型”并不相同。


查看完整回答
反對 回復 2019-06-15
?
慕工程0101907

TA貢獻1887條經驗 獲得超5個贊

這是相當古老的K&R C語法(早于ANSI/ISO C)。現在,您不應該再使用它了(因為您已經注意到它的主要缺點:編譯器不會為您檢查參數的類型)。參數類型實際上默認為int在你的例子中。

在使用這個語法的時候,人們有時會發現這樣的函數

foo(p, q) {
    return q + p;}

的類型,實際上是一個有效的定義。foop,和q默認為int.


查看完整回答
反對 回復 2019-06-15
?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

這只是一個古老的語法,早于你可能更熟悉的“ANSI C”語法。這叫“K&R C“,典型的。

當然,編譯器支持它是完整的,并且能夠處理舊的代碼庫。


查看完整回答
反對 回復 2019-06-15
  • 3 回答
  • 0 關注
  • 1153 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號