有參函數的定義格式以下:c++
類型標識符 函數名(形式參數表列)windows
{數組
語句;函數
}lua
如spa
void fun(int a,int b)3d
{指針
printf(「a+b=%d」,a+b);code
}blog
固然類型標識符也能夠是int或float或char,但那是有返回值函數的範疇,咱們在下一章節再詳細講解。
在上面的案例你們也看到了在函數頭後的括號裏有內容,咱們把它稱爲參數,在使用函數時,常常會用到形式參數和實際參數。二者都叫參數,那麼兩者有什麼關係?兩者之間的區別是什麼?兩種參數各自又起到什麼做用?
形式參數:按照名稱進行理解就是形式上存在的參數。
實際參數:按照名稱進行理解就是實際存在的參數。
形式參數:在定義函數時,函數名後面括號中的變量名稱爲「形式參數」。在函數調用以前傳遞給函數的值將被複制到這些形式參數中。
實際參數:在調用一個函數時,也就是真正使用一個函數時,函數名後面括號中的參數爲「實際參數」。函數的調用者提供給函數的參數叫實際參數。實際參數是表達式計算的結果,而且被複制給函數的形式參數。
void fun(int num) { ----- } |
如定義或聲明函數,此時函數參數num爲形式參數,簡稱形參 |
void main() { int number; fun(number); fun(99); } |
調用函數,此時的函數參數中的99或number爲實際參數,簡稱實參 |
母親拿來了一袋牛奶,將牛奶倒入一個空奶瓶中,而後喂寶寶喝牛奶。函數的做用就至關於寶寶用奶瓶喝牛奶這個動做,實參至關於母親拿來的一袋牛奶,而空的奶瓶至關於形參。牛奶放入奶瓶這個動做至關於將實參傳遞給形參,使用灌好牛奶的奶瓶就至關於函數使用參數進行操做的過程。
下面經過一個實例對形式參數和實際參數進行實際的講解。
例:形式參數與實際參數的比喻實現
實例中將上面的比喻進行了實際的模擬,但願讀者能夠一邊實際動手操做,一邊經過上面的比喻對形式參數和實際參數加深理解,更好地掌握知識點。
#include "stdio.h" void drinkmilk(char cbottle); /*聲明函數*/ void main() { char c; printf("Mother wanna give the baby:"); c=getchar(); drinkmilk(c); } void drinkmilk(char cbottle) { printf("Theb Baby drink the %c\n",cbottle); }
函數的聲明方式
Void drinkmilk(char cbottle);分號不能少放在函數的開頭或函數被調用以前。
也能夠轉換爲
Void drinkmilk(char );
以上程序的執行結果以下:
當數組做爲函數的實參時,只傳遞數組的地址,而不是整個數組賦值到函數中。當用數組名做爲實參調用函數時,指向該數組的第一個元素的指針就被傳遞到函數中。
聲明函數參數時必須具備相同的類型,根據這一點,下面將對使用數組做爲函數參數的各類狀況進行詳細的講解。
因爲實參能夠是表達式形式,數組元素能夠是表達式的組成部分,所以數組元素能夠做爲函數的實參,與用變量做爲函數實參同樣,是單向傳遞。
例:數組元素做爲函數參數
#include "stdio.h" void fun(int a); /* 聲明函數*/ void main() { int score[10]; /* 定義一個整型的數組*/ int i; /* 定義整型變量,用於循環*/ for(i=0;i<10;i++)/* 進行賦值循環*/ { score[i]=i; /*爲數組中的元素進行賦值操做*/ } for(i=0;i<10;i++) /* 循環操做*/ { fun(score[i]); /*執行輸出函數操做*/ } } void fun(int a) /*函數定義*/ { printf("show the member is %d \n",a); /*輸出數據*/ }
運行結果:
能夠用數組名做爲函數參數,此時實參與形參都使用數組名
例:
#include "stdio.h" void evaluate(int Aarray[10]); /* 聲明賦值函數*/ void display(int Aarray[10]); /*聲明顯示函數*/ void main() { int iarray[10]; /* 定義一個具備10個元素的整型數組*/ evaluate(iarray); /*調用函數進行賦值,將數組名做爲參數*/ display(iarray); /*調用函數進行輸出,將數組名做爲參數*/ } void display(int Aarray[10]) { int i; for(i=0;i<10;i++) { /*在函數中執行輸出操做*/ printf("the member number is %d\n",Aarray[i]); } } void evaluate(int Aarray[10]) { int i; for(i=0;i<10;i++) { /*在函數中執行賦值操做*/ Aarray[i]=i; } }
結果以下:
注:數組做爲參數在進行傳遞時,是以數組名做爲參數進行傳遞的。
能夠將函數的參數聲明成長度可變的數組,在此基礎上利用上面的程序進行修改。聲明方式的代碼爲:
void fun(int array[]); int iarray[10]; fun(iarray); 從上面的代碼中能夠看到,在定義和聲明一個函數時將數組做爲函數參數,而且沒有指明數組此時的大小,這樣就將函數參數聲明爲數組長度可變的數組。 例 : #include "stdio.h" void evaluate(int Aarray[10]); /* 聲明賦值函數*/ void display(int Aarray[10]); /*聲明顯示函數*/ void main() { int iarray[10]; /* 定義一個具備10個元素的整型數組*/ evaluate(iarray); /*調用函數進行賦值,將數組名做爲參數*/ display(iarray); /*調用函數進行輸出,將數組名做爲參數*/ } void display(int Aarray[]) { int i; for(i=0;i<10;i++) { /*在函數中執行輸出操做*/ printf("the member number is %d\n",Aarray[i]); } } void evaluate(int Aarray[]) { int i; for(i=0;i<10;i++) { /*在函數中執行賦值操做*/ Aarray[i]=i; } }
結果以下:
#include "stdio.h" #include "stdlib.h" #include "conio.h" #include "string.h" #include "windows.h" //控制dos界面 #define MAXIMUS 15 //定義棋盤大小 int p[MAXIMUS][MAXIMUS];//存儲對局信息 char buff[MAXIMUS * 2 + 1][MAXIMUS * 4 + 3]; //輸出緩衝器 int Cx, Cy; //當前光標位置 int Now;//當前走子的玩家,1表明黑,2表明白 int wl, wp; //當前寫入緩衝器的列數和行數位置 char* showText;//在棋盤中央顯示的文字信息 int count;//回合數 char* Copy ( char* strDest, const char* strSrc ) //修改過的字符串複製函數,會忽略末端的\0 { char* strDestCopy = strDest; while ( *strSrc != '\0' ) { *strDest++ = *strSrc++; } return strDestCopy; } void Initialize() //初始化一個對局函數 { int i, j; //循環變量 showText = ""; //重置顯示信息 count = 0; //回合數歸零 for ( i = 0; i < MAXIMUS; i++ ) //重置對局數據 { for ( j = 0; j < MAXIMUS; j++ ) { p[i][j] = 0; } } Cx = Cy = MAXIMUS / 2; //重置光標到中央 Now = 1; //重置當前爲黑方 } char* getStyle ( int i, int j ) //得到棋盤中指定座標交點位置的字符,經過製表符拼成棋盤 { if ( p[i][j] == 1 ) //1爲黑子 return "●"; else if ( p[i][j] == 2 ) //2爲白子 return "○"; else if ( i == 0 && j == 0 ) //如下爲邊緣棋盤樣式 return "┏"; else if ( i == MAXIMUS - 1 && j == 0 ) return "┓"; else if ( i == MAXIMUS - 1 && j == MAXIMUS - 1 ) return "┛"; else if ( i == 0 && j == MAXIMUS - 1 ) return "┗"; else if ( i == 0 ) return "┠"; else if ( i == MAXIMUS - 1 ) return "┨"; else if ( j == 0 ) return "┯"; else if ( j == MAXIMUS - 1 ) return "┷"; return "┼";//中間的空位 } char* getCurse ( int i, int j ) //得到指定座標交點位置左上格的樣式,經過製表符來模擬光標的顯示 { if ( i == Cx ) { if ( j == Cy ) return "┏"; else if ( j == Cy + 1 ) return "┗"; } else if ( i == Cx + 1 ) { if ( j == Cy ) return "┓"; else if ( j == Cy + 1 ) return "┛"; } return " ";//若是不在光標附近則爲空 } void write ( char* c ) //向緩衝器寫入字符串 { Copy ( buff[wl] + wp, c ); wp += strlen ( c ); } void ln() //緩衝器寫入位置提行 { wl += 1; wp = 0; } void Display() //將緩衝器內容輸出到屏幕 { int i, l = strlen ( showText ); //循環變量,中間文字信息的長度 int Offset = MAXIMUS * 2 + 2 - l / 2; //算出中間文字信息居中顯示所在的橫座標位置 if ( Offset % 2 == 1 ) //若是位置爲奇數,則移動到偶數,避免混亂 { Offset--; } Copy ( buff[MAXIMUS] + Offset, showText ); //講中間文字信息複製到緩衝器 if ( l % 2 == 1 ) //若是中間文字長度爲半角奇數,則補上空格,避免混亂 { * ( buff[MAXIMUS] + Offset + l ) = 0x20; } system ( "cls" ); //清理屏幕,準備寫入 for ( i = 0; i < MAXIMUS * 2 + 1; i++ ) //循環寫入每一行 { printf ( "%s", buff[i] ); if ( i < MAXIMUS * 2 ) //寫入完每一行須要換行 printf ( "\n" ); } } void Print() //將整個棋盤算出並儲存到緩衝器,而後調用Display函數顯示出來 { int i, j; //循環變量 wl = 0; wp = 0; for ( j = 0; j <= MAXIMUS; j++ ) //寫入出交點左上角的字符,由於須要打印棋盤右下角,因此很以橫縱各多一次循環 { for ( i = 0; i <= MAXIMUS; i++ ) { write ( getCurse ( i, j ) ); //寫入左上角字符 if ( j == 0 || j == MAXIMUS ) //若是是棋上下盤邊緣則沒有鏈接的豎線,用空格填充位置 { if ( i != MAXIMUS ) write ( " " ); } else//若是在棋盤中間則用豎線承接上下 { if ( i == 0 || i == MAXIMUS - 1 ) //左右邊緣的豎線更粗 write ( "┃" ); else if ( i != MAXIMUS ) //中間的豎線 write ( "│" ); } } if ( j == MAXIMUS ) //若是是最後一次循環,則只須要處理邊側字符,交點要少一排 { break; } ln();//提行開始打印交點內容 write ( " " ); //用空位補齊位置 for ( i = 0; i < MAXIMUS; i++ ) //按橫座標循環正常的次數 { write ( getStyle ( i, j ) ); //寫入交點字符 if ( i != MAXIMUS - 1 ) //若是不在最右側則補充一個橫線承接左右 { if ( j == 0 || j == MAXIMUS - 1 ) { write ( "━" ); //上下邊緣的橫線更粗 } else { write ( "—" ); //中間的橫線 } } } ln();//寫完一行後提行 } Display();//將緩衝器內容輸出到屏幕 } int Put() //在當前光標位置走子,若是非空,則返回0表示失敗 { if ( p[Cx][Cy] == 0 ) { p[Cx][Cy] = Now; //改變該位置數據 return 1;//返回1表示成功 } else { return 0; } } int Check() //勝負檢查,即判斷當前走子位置有沒有形成五連珠的狀況 { int w = 1, x = 1, y = 1, z = 1, i; //累計橫豎正斜反邪四個方向的連續相同棋子數目 for ( i = 1; i < 5; i++ ) if ( Cy + i < MAXIMUS && p[Cx][Cy + i] == Now ) w++; else break;//向下檢查 for ( i = 1; i < 5; i++ ) if ( Cy - i > 0 && p[Cx][Cy - i] == Now ) w++; else break;//向上檢查 if ( w >= 5 ) return Now; //若果達到5個則判斷當前走子玩家爲贏家 for ( i = 1; i < 5; i++ ) if ( Cx + i < MAXIMUS && p[Cx + i][Cy] == Now ) x++; else break;//向右檢查 for ( i = 1; i < 5; i++ ) if ( Cx - i > 0 && p[Cx - i][Cy] == Now ) x++; else break;//向左檢查 if ( x >= 5 ) return Now; //若果達到5個則判斷當前走子玩家爲贏家 for ( i = 1; i < 5; i++ ) if ( Cx + i < MAXIMUS && Cy + i < MAXIMUS && p[Cx + i][Cy + i] == Now ) y++; else break;//向右下檢查 for ( i = 1; i < 5; i++ ) if ( Cx - i > 0 && Cy - i > 0 && p[Cx - i][Cy - i] == Now ) y++; else break;//向左上檢查 if ( y >= 5 ) return Now; //若果達到5個則判斷當前走子玩家爲贏家 for ( i = 1; i < 5; i++ ) if ( Cx + i < MAXIMUS && Cy - i > 0 && p[Cx + i][Cy - i] == Now ) z++; else break;//向右上檢查 for ( i = 1; i < 5; i++ ) if ( Cx - i > 0 && Cy + i < MAXIMUS && p[Cx - i][Cy + i] == Now ) z++; else break;//向左下檢查 if ( z >= 5 ) return Now; //若果達到5個則判斷當前走子玩家爲贏家 return 0;//若沒有檢查到五連珠,則返回0表示尚未玩家達成勝利 } int RunGame() //進行整個對局,返回贏家信息(雖然有用上) { int input;//輸入變量 int victor;//贏家信息 Initialize();//初始化對局 while ( 1 ) //開始無限回合的死循環,直到出現勝利跳出 { Print();//打印棋盤 input = getch(); //等待鍵盤按下一個字符 if ( input == 27 ) //若是是ESC則退出程序 { exit ( 0 ); } else if ( input == 0x20 ) //若是是空格則開始走子 { if ( Put() ) //若是走子成功則判斷勝負 { victor = Check(); Now = 3 - Now; //輪換當前走子玩家 count++; if ( victor == 1 ) //若是黑方達到勝利,顯示提示文字並等待一次按鍵,返回勝利信息 { showText = "黑方得到了勝利!"; Print(); if ( getch() == 0xE0 ) { getch(); } return Now; } else if ( victor == 2 ) //若是白方達到勝利,顯示提示文字並等待一次按鍵,返回勝利信息 { showText = "白方得到了勝利!"; Display(); if ( getch() == 0xE0 ) { getch(); } return Now; } else if ( count == MAXIMUS * MAXIMUS ) //若是回合數達到了棋盤總量,即棋盤充滿,即爲平局 { showText = "平局!"; Display(); if ( getch() == 0xE0 ) { getch(); } return 0; } } } else if ( input == 0xE0 ) //若是按下的是方向鍵,會填充兩次輸入,第一次爲0xE0表示按下的是控制鍵 { input = getch(); //得到第二次輸入信息 switch ( input ) //判斷方向鍵方向並移動光標位置 { case 0x4B:// Cx--; break; case 0x48: Cy--; break; case 0x4D: Cx++; break; case 0x50: Cy++; break; } if ( Cx < 0 ) Cx = MAXIMUS - 1; //若是光標位置越界則移動到對側 if ( Cy < 0 ) Cy = MAXIMUS - 1; if ( Cx > MAXIMUS - 1 ) Cx = 0; if ( Cy > MAXIMUS - 1 ) Cy = 0; } } } int main() //主函數 { system ( "title 簡易五子棋 ——Etsnarl製做" ); //設置標題 system ( "mode con cols=63 lines=32" ); //設置窗口大小 system ( "color E0" ); //設置顏色 while ( 1 ) //循環執行遊戲 { RunGame(); } }