筆者最近在複習C語言函數時遇到了一個本身在寫函數聲明時時常會犯的一個錯誤,因此如今想把它寫出來跟你們分享一下。編程
筆者以前在寫沒有參數的函數的聲明時,一般會將void省略,以下:函數
void showMessage(); //不規範的寫法
在筆者的潛意識裏,這種寫法和下面的寫法是同樣的,但其實是不同的,並且差異很大。那麼,它們之間的差異在哪呢,這就是筆者接下來要討論的問題。spa
void showMessage(void);//規範的寫法
想必你們都知道ANSI C (不知道的能夠自行度娘),在ANSI C中,須要使用函數原型(function prototype)來聲明函數的返回值類型、參數個數以及各個參數的類型。而在ANSI C以前,函數聲明並不涉及函數參數,只須要聲明函數的返回值類型便可。因此如今擺在你們面前的有兩種函數聲明方式:prototype
一、符合ANSI C標準的函數聲明方式;code
二、老式的函數聲明方式。ci
對於上文中筆者省略void關鍵字的函數聲明,ANSI C編譯器會將其認定爲老式的函數聲明方式,即沒用用函數原型聲明函數,因此編譯器在編譯的時候不會進行參數檢查,將發現不了函數調用時傳遞的參數與函數定義的參數不匹配的錯誤。原型
爲了說明這點,筆者寫了以下代碼進行驗證:編譯器
#include<stdio.h> void showMessage(); int main(void) { showMessage("HelloWorld!",3.14); return 0; } void showMessage() { printf("I am running now!\n"); return; }
從代碼中咱們能夠看到,筆者在調用showMessage()函數時向其傳遞了兩個參數,但實際上showMessage()函數並不須要參數,那麼程序到底能不能運行呢?咱們來試一下:io
從上圖咱們能夠知道,代碼0錯誤,0警告,程序正常運行了,編譯器並無發現函數參數不匹配的錯誤!編譯
或許有人看了會說這個函數本來就不須要參數,即便如今傳遞了參數也不影響程序的正確性啊。但這終究是不規範的寫法,咱們應該抱着嚴謹的態度去寫代碼,養成良好的編程習慣很重要!
但願筆者的這篇文章能對你們有所幫助。
參考文獻:《C Primer Plus》(第五版)