C語言中定義原型

orginate from http://hi.baidu.com/shirdrn/item/6aa992f2d5198ecc531c26af

本來想研究一下Minix操作系統的源代碼,但是因爲剛剛從Java轉過來,有很多東西感覺不是很熟悉,而且感觸最深刻的就是,曾經學過的那個C語言根本一點沒有掌握,此時此刻C語言基礎完全成爲0了。

在Minix中,遇到一個_PROTOTYPE的定義,其實研究了一下,感覺就是C語言中的預定義,一種我從沒有見過的宏的定義方式(僅僅對我而言)。

我知道的,宏定義可以有兩種方式:一種是不帶參數的宏,一種是帶參數的宏。第一種就不說了,定義常量。第二種雖然比較複雜一些,但是基本上是那些用帶參數的宏名來替換一個帶參數的字符串而已。

現在,遇到的讓我真是大開眼界(對應於Minix源代碼中的include/ansi.h文件):

#ifdef _ANSI

/* Keep everything for ANSI prototypes. */
#define _PROTOTYPE(function, params) function params
#define _ARGS(params)    params

#define _VOIDSTAR void *
#define _VOID   void
#define _CONST   const
#define _VOLATILE volatile
#define _SIZET   size_t

#else

/* Throw away the parameters for K&R prototypes. */
#define _PROTOTYPE(function, params) function()
#define _ARGS(params)    ()

#define _VOIDSTAR void *
#define _VOID   void
#define _CONST
#define _VOLATILE
#define _SIZET   int

#endif /* _ANSI */

上面定義了基於兩種標準的C代碼風格,一種就是ANSI C標準,其他的爲另一種,這裏給出的是K&R風格的原型的定義。

再看一下具體是如何使用定義的這個原型的(對應於Minix源代碼中的kernel/main.c文件):

#include "kernel.h"
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <a.out.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include "proc.h"

/* Prototype declarations for PRIVATE functions. */
FORWARD _PROTOTYPE( void announce, (void)); 
FORWARD _PROTOTYPE( void shutdown, (timer_t *tp));

/*===========================================================================*
*     announce         *
*===========================================================================*/
PRIVATE void announce(void)
{
/* Display the MINIX startup banner. */
kprintf("MINIX %s.%s." 
      "Copyright 2006, Vrije Universiteit, Amsterdam, The Netherlands\n", 
      OS_RELEASE, OS_VERSION);

/* Real mode, or 16/32-bit protected mode? */
kprintf("Executing in %s mode.\n\n",
      machine.protected ? "32-bit protected" : "real");
}

這裏,省略了一些無關的代碼。其中,PRIVATE和FORWARD是預定義,定義如下(對應於Minix源代碼中的include/minix/const.h文件):

#define PRIVATE       static /* PRIVATE x limits the scope of x */
#define FORWARD       static /* some compilers require this to be 'static'*/

他們隱藏了C中的關鍵字static。

這下,上面的代碼就非常容易理解了。其實,就是展開宏以後,就是下面的代碼:

#include "kernel.h"
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <a.out.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include "proc.h"

/* Prototype declarations for PRIVATE functions. */
static _PROTOTYPE( void announce, (void)); 
static _PROTOTYPE( void shutdown, (timer_t *tp));

/*===========================================================================*
*     announce         *
*===========================================================================*/
static void announce(void)
{
/* Display the MINIX startup banner. */
kprintf("MINIX %s.%s." 
      "Copyright 2006, Vrije Universiteit, Amsterdam, The Netherlands\n", 
      OS_RELEASE, OS_VERSION);

/* Real mode, or 16/32-bit protected mode? */
kprintf("Executing in %s mode.\n\n",
      machine.protected ? "32-bit protected" : "real");
}

下面,我們使用這種預處理的定義方式來做個簡單的例子,熟悉一下。

定一個頭文件shitype.h,內容如下:

#define _PROTOTYPE(function, params) function params

這裏,只是使用define定義了一個原型。

測試文件如下所示:

#include <stdio.h>
#include "shitype.h"

_PROTOTYPE( void DisplayYourname, (char* yourname)); // 聲明原型

int main(){
DisplayYourname("Shirdrn");
return 0;
}

void DisplayYourname(char* yourname){
printf("Your name is : %s",yourname);
}

編譯運行結果如下所示:

Your name is : ShirdrnPress any key to continue

其實,聲明一個原型的過程,就是在聲明一個函數。

我們可以不使用聲明,但是需要將函數的定義放到主函數main的前面,如下所示:

#include <stdio.h>
// #include "shitype.h"

// _PROTOTYPE( void DisplayYourname, (char* yourname));

void DisplayYourname(char* yourname){
printf("Your name is : %s",yourname);
}


int main(){
DisplayYourname("Shirdrn");
return 0;
}

編譯運行,結果與上面是一樣的。

如果像上面一樣不進行聲明,就和頭文件shitype.h沒有關係了。

發佈了20 篇原創文章 · 獲贊 21 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章