簡體   English   中英

C 帶返回值的 void 函數

[英]C void function with return value

據我所知,void 函數中的return語句會拋出錯誤。

但在下面的程序中,情況並非如此。

這里顯示的輸出是1 怎么會?

main()
{
    int i=5;
    printf("%d",fun(fun(fun(i))));
}

void fun(int i)
{
    if (i%2)
    {
        return (i+(7*4)-(5/2)+(2*2));
    }
    else
    {
        return (i+(17/5)-(34/15)+(5/2));
    }
}

沒有表達式的return語句:

void func(void) {
    return;
}

void函數中是完全合法的。 帶有表達式的return語句的合法性取決於您使用的 C 語言版本。

1990 C 標准說:

帶有表達式的return語句不應出現在返回類型為void的函數中。

該標准的 1999 年和 2011 年版本都說:

帶有表達式的return語句不應出現在返回類型為void的函數中。 沒有表達式的return語句只能出現在返回類型為void的函數中。

這是一個約束,意味着編譯器必須為任何違反它的程序發出診斷(可能是非致命警告)。

由於歷史原因,C90 允許在非void函數中使用沒有表達式的return語句。 Pre-ANSI C 沒有void關鍵字,因此無法定義不返回值的函數。 程序員會省略返回類型(默認為int )並簡單地忽略它。 C90 規則允許這樣的舊代碼編譯而不會出錯。 您仍然可能無法從非void函數返回值; 如果調用者嘗試使用(不存在的)結果,則程序的行為是未定義的。 1999 年的標准稍微收緊了規則。

你的程序的另一個問題是你在它的聲明可見之前調用了fun 根據 C99 和更高版本的規則,這是非法的(盡管編譯器可能只是對此發出警告)。 在 C90 規則下,這是合法的,但編譯器會假設函數返回int 您的程序的行為是未定義的,但您的void函數fun可能恰好表現得好像它返回了一個值,而對它的調用可能恰好表現得好像它使用了該值。

C 編譯器往往對某些錯誤相當寬松,因此不會拒絕舊代碼(有時在第一個實際標准發布之前編寫)。 但是您的編譯器至少應該警告您有關return語句的信息,以及可能有關無效調用的信息。 您應該密切注意編譯器警告; 應該像對待致命錯誤一樣對待它們。 並且您應該使用選項來增加編譯器警告您的事情的數量。 如果您使用 gcc,請使用-std=c90-std=c99-std=c11以及-pedantic來強制執行標准一致性。 您可以添加-Wall -Wextra 以啟用更多警告。

由於各種原因,您提供的代碼實際上在 C99 中無效,但最痛苦的一個如下:

foo.c:5:17: warning: implicit declaration of function 'fun' is invalid in C99 [-Wimplicit-function-declaration]
    printf("%d",fun(fun(fun(i))));
                ^
foo.c:8:6: error: conflicting types for 'fun'
void fun(int i)
     ^
foo.c:5:17: note: previous implicit declaration is here
    printf("%d",fun(fun(fun(i))));
                ^

請注意,如果您為fun()提供了一個函數原型,您確實應該這樣做,那么您將得到一組不同的錯誤:

foo.c:7:25: error: passing 'void' to parameter of incompatible type 'int'
    printf("%d",fun(fun(fun(i))));
                        ^~~~~~

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM