1. 程式人生 > >C語言程式設計基礎-09函式與返回值及形參

C語言程式設計基礎-09函式與返回值及形參

函式
返回值
形參實參


函式

在大規模的程式中需要對語句進行分組管理,把相互之間聯絡比較緊密的語句合併成一組;
分組可以在多個不同層次上進行,最低一級分組的結果叫程式碼塊,程式碼塊由{}大括號包括;
在大括號前面新增
    型別名 函式名()的就是函式;
函式的形式如
void func() {
    do something;
}
任何函式一定包含若干條語句;
任何C語言程式都是由一個或多個函式構成的;
絕大多數語句必須屬於某個函式;
在C語言中函式名字是唯一的;
在程式進行過程中不同函式之間一定要存在聯絡和協作;
任何一次函式之間的協作一定發生在兩個函式之間,不排除函式與自身的反饋(自己呼叫自己);
函式之間的協作只在某個時間範圍內有效
兩個函式之間的一次協作叫做一次函式呼叫
函式呼叫過程中發起呼叫的函式叫做呼叫函式(類似於校學生會主席)
被動的接受呼叫的函式叫做被呼叫函式(類似於院系學生會主席)

絕大多數函式呼叫過程中存在資料傳遞現象;(下達任務,完成後彙報情況);
任何函式呼叫過程中存在兩個方向相反的資料傳遞過程(下達任務,或反饋是否完成);
這個資料傳遞的過程是我們研究的重點;

任何一個函式作為被呼叫函式參與一次函式呼叫過程時,為了實現兩個方向的資料傳遞,需要各準備一組相關的變數(都有自己的一套組織)用來存放;

呼叫函式向被呼叫函式傳遞的資料稱為實參,即實際引數;
被呼叫函式使用與實參相對應的資料型別(派相關人員對接)接收傳遞過來的引數,這個引數叫形參,即形式引數;
形式引數可以與實參名字相同,但不代表同一個儲存空間(傳遞複製的資料)(比如都叫外聯部);
實參和形參的個數可以不止一個;

被呼叫函式執行結束或因某種條件而結束時,可以向呼叫者返回自己執行的情況或結果,這個值用return關鍵字來實現(結果由院主席向校主席統一彙報),而且一個函式在一次被呼叫結束時只能返回一個值;

當一個主調函式呼叫另一個被調函式時,程式將進入被調函式執行,直到被調函式執行結束才會回來繼續執行主調函式的下一條語句;

返回值

返回值變數用來實現從被掉用函式向呼叫函式傳遞資料;
任何函式最多隻能有一個返回值變數;
常用來反饋函式執行的結果(負數或零,或非負數或指標等),或者其他一些標誌;
函式返回值的型別由函式宣告時在函式名前指定;

返回值變數只能在函式結束的那一刻才能使用
對返回值變數的賦值需要使用 return 關鍵字實現;
只有呼叫函式才能從返回值變數中獲得資料
在被掉用函式結束的時候才能拿到資料;
把函式呼叫語句當數字使用表示從返回值變數中獲得資料;

/*
 * 返回值演示
 */
#include <stdio.h>

int add() {
    return 2 + 4;
}

int main() {
    int num = 0;
    num = add();
    printf("return %d\n", num);
    return 0;
}

練習
    編寫一個多函式程式,用一個函式從鍵盤得到數字;
    主函式得到這個數字並列印在螢幕上;
/*
 * 用一個函式從鍵盤得到數字,主函式得到數字並列印在螢幕上
 */
#include <stdio.h>
/* 返回一個int型的值 */
int read() {
    int num;
    printf("請輸入一個數字: ");
    scanf("%d", &num);
    return num;
}

/* 不返回任何值 */
void show() {
    printf("I am show()\n");
}

int show1() {
    printf("I am show1()\n");
    // printf("1\n");
    // return 0;
    // 應該返回int型的值,但函式沒有明確指定,結果不確定
}

int main() {
    int num = read(); //呼叫一次
    int num1;
    printf("步驟1>\n");
    printf("輸入的數字是:%d\n", num); //直接適用num的值
    printf("步驟2>>\n");
    printf("輸入的數字是:%d\n", read()); //呼叫一次read()
    printf("步驟3>>>\n");
    printf("輸入的數字是:%d\n", num);    //不再呼叫read()
    printf("步驟4>>>\n");
    show();
    num1 = show1();        //結果不確定
    printf("show1 is %d\n", num1);
    return 0;
}


使用void宣告函式表示返回值變數型別為空,意味著不使用返回值變數型別;
如果沒有明確指出返回值變數型別則計算機預設認為返回值變數型別是整型;

如果沒有使用 return 關鍵字對返回值變數賦值,則返回的變數內容不確定;
如果對返回值變數進行賦值時兩邊的型別不一致,則可能出現意想不到的結果;

return關鍵字可以立刻結束函式的執行,只要函式在執行時碰到該語句就會立刻結束函式的執行;
exit()標準函式可以立刻結束整個程序的執行,需要包含檔案stdlib.h;它比return更暴力,結束的更徹底;
/*
 * exit練習
 */
#include <stdio.h>
#include <stdlib.h>
void func() {
    printf("我在func中2\n");
    return;
    printf("3\n");
}

void func1() {
    printf("我在func1中5\n");
    exit(0);        //0與return的0是一樣的含義
    printf("6\n");
}

int main() {
    printf("我在main中1\n");
    func();
    func1();
    printf("4\n");
    return 0;
}

練習
    從鍵盤得到兩個數,計算二者和,主函式打印出求和結果;
/*
 * 返回值練習
 */
#include <stdio.h>
int add() {
    int i = 0, j = 0;
    printf("請輸入兩個數字: ");
    scanf("%d%d", &i, &j);
    return i + j;
}

int main() {
    printf("sum is %d\n", add());
    return 0;
}


形參與實參

    為了實現從呼叫函式向被呼叫函式傳遞資料,被呼叫函式需要準備一組變數,這組變數叫形式引數;
    他們只能在被調函式中使用;只靠這些資料是不能完成整個資料的傳遞的,還需要更原始的資料;
    為了實現資料的傳遞,需要呼叫函式提供這些資料,呼叫函式提供的這些資料叫實際引數;
    實際引數既可以是變數也可以是其他方式表示;
    傳遞的是資料而不是儲存位置,值傳遞;不能通過函式改變實參本身;
    函式的形參型別和個數沒有限制,但返回值最多隻能有一個;
/*
 * 引數演示
 */
#include <stdio.h>
void show(int num) {
    printf("show(%d)\n", num);
}

void sum(int num, int num1) {
    printf("sum is %d\n", num + num1);
}

int main() {
    int num = 10;
    show(5);
    show(num);
    sum(13, 7);
    return 0;
}

/*
 * 引數與返回值演示
 */
#include <stdio.h>
void show(int num) {
    printf("show(%d)\n", num);
}

int sum(int num, int num1) {
    return num + num1;
}

int main() {
    int num = 10;
    show(5);
    show(num);

    int sum = show1(13, 7);
    printf("sum is %d\n", sum);
    return 0;
}

作業
    1.編寫程式在螢幕上列印如下內容:
1 x 9 = 9
2 x 8 = 16
...
5 x 5 = 25
每一行使用一個函式呼叫語句實現列印
/*
 * 編寫程式在螢幕上列印如下內容,
 * 每一條使用一個函式呼叫語句實現列印;
 * 1 x 9 = 9
 * 2 x 8 = 16
 * 3 x 7 = 21
 * 4 x 6 = 24
 * 5 x 5 = 25
 */
#include <stdio.h>
void show(int x, int y) {
    printf("%d x %d = %2d\n", x, y, x * y);
}

int main() {
    int i = 0;
    for (i = 1; i <= 5; i++) {
        show(i, 10 - i);
    }
    return 0;
}

    2.程式設計判斷某個給定數字是否素數;
/*
 * 程式設計判斷一個數是否素數
 */
#include <stdio.h>
int is_su(int num) {
    int num1 = 0;
    for (num1 = 2; num1 < num; num1++) {
        if (!(num % num1)) {
            return 0;    // 0表示不是素數
        }
    }
    return 1;
}

int main() {
    int i = 0;
    printf("請輸入一個數字");
    scanf("%d", &i);
    scanf("%*[^\n]");
    scanf("%*c");

    if (is_su(i)) {
        printf("是素數\n");
    } else {
        printf("不是素數\n");
    }

    return 0;
}

    3.編寫函式生成一張彩票並列印在螢幕上;
    可以出現重複數字,彩票中的數字個數由主函式指定;
/*
 * 編寫函式生成一張彩票並列印在螢幕上;
 * 可以出現重複數字,彩票中的數字個數由主函式指定
 */
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void lottory(int num) {
    int arr[num], i = 0;
    for (i = 0; i < num; i++) {
        //生成隨機數
        arr[i] = rand() % 36 + 1;
    }
    for (i = 0; i < num; i++) {
        //迴圈列印
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int num = 0;
    srand(time(0));
    printf("請輸入彩票的位數: ");
    scanf("%d", &num);
    scanf("%*[^\n]");
    scanf("%*c");

    lottory(num);
    return 0;
}