c語言進階3-有參函數

1、       有參函數的定義

有參函數的定義格式以下:c++

類型標識符  函數名(形式參數表列)windows

{數組

   語句;函數

}lua

spa

void fun(int a,int b)3d

{指針

   printf(「a+b=%d」,a+b);code

}blog

固然類型標識符也能夠是int或float或char,但那是有返回值函數的範疇,咱們在下一章節再詳細講解。

2、       形式參數和實際參數

在上面的案例你們也看到了在函數頭後的括號裏有內容,咱們把它稱爲參數,在使用函數時,常常會用到形式參數和實際參數。二者都叫參數,那麼兩者有什麼關係?兩者之間的區別是什麼?兩種參數各自又起到什麼做用?

  1. 1.        經過名稱理解

形式參數:按照名稱進行理解就是形式上存在的參數。

實際參數:按照名稱進行理解就是實際存在的參數。

  1. 2.        經過做用理解

形式參數:在定義函數時,函數名後面括號中的變量名稱爲「形式參數」。在函數調用以前傳遞給函數的值將被複制到這些形式參數中。

實際參數:在調用一個函數時,也就是真正使用一個函數時,函數名後面括號中的參數爲「實際參數」。函數的調用者提供給函數的參數叫實際參數。實際參數是表達式計算的結果,而且被複制給函數的形式參數。

void fun(int num)

{

  -----

}

如定義或聲明函數,此時函數參數num爲形式參數,簡稱形參

void main()

{

   int number;

fun(number);

fun(99);

}

調用函數,此時的函數參數中的99或number爲實際參數,簡稱實參

  1. 3.        經過一個比喻來理解形式參數和實際參數

母親拿來了一袋牛奶,將牛奶倒入一個空奶瓶中,而後喂寶寶喝牛奶。函數的做用就至關於寶寶用奶瓶喝牛奶這個動做,實參至關於母親拿來的一袋牛奶,而空的奶瓶至關於形參。牛奶放入奶瓶這個動做至關於將實參傳遞給形參,使用灌好牛奶的奶瓶就至關於函數使用參數進行操做的過程。

下面經過一個實例對形式參數和實際參數進行實際的講解。

例:形式參數與實際參數的比喻實現

實例中將上面的比喻進行了實際的模擬,但願讀者能夠一邊實際動手操做,一邊經過上面的比喻對形式參數和實際參數加深理解,更好地掌握知識點。

 

#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 );

 

以上程序的執行結果以下:

 

 

3、       數組做函數參數

當數組做爲函數的實參時,只傳遞數組的地址,而不是整個數組賦值到函數中。當用數組名做爲實參調用函數時,指向該數組的第一個元素的指針就被傳遞到函數中。

聲明函數參數時必須具備相同的類型,根據這一點,下面將對使用數組做爲函數參數的各類狀況進行詳細的講解。

  1. 1.        數組元素做爲函數參數

因爲實參能夠是表達式形式,數組元素能夠是表達式的組成部分,所以數組元素能夠做爲函數的實參,與用變量做爲函數實參同樣,是單向傳遞。

例:數組元素做爲函數參數

#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); /*輸出數據*/

 

}

運行結果:

 

 

  1. 2.        數組名做爲函數參數

能夠用數組名做爲函數參數,此時實參與形參都使用數組名

例:

#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;

}

}

 

結果以下:

 

 

注:數組做爲參數在進行傳遞時,是以數組名做爲參數進行傳遞的。

  1. 3.        可變長度數組做爲函數參數

能夠將函數的參數聲明成長度可變的數組,在此基礎上利用上面的程序進行修改。聲明方式的代碼爲:

 

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();
    }
}
相關文章
相關標籤/搜索