1. 程式人生 > >C Primer Plus (第五版)中文版——第 9 章 函式

C Primer Plus (第五版)中文版——第 9 章 函式

9.1  函式描述

  • 函式(function)是用於完成特定任務的程式程式碼的自包含單元。一個簡單函式:
/* lesser.c -- finds the lesser of two evils */
#include <stdio.h>
int imin(int n,int m);  /* prototype the function */

int main(void)
{
    int evil1, evil2;

    printf("Enter a pair of integers (q to quit):\n");
    while (scanf("%d %d", &evil1, &evil2) == 2)
    {
        printf("The lesser of %d and %d is %d.\n",
            evil1, evil2, imin(evil1,evil2));    /* use the function */
        printf("Enter a pair of integers (q to quit):\n");
    }
    printf("Bye.\n");
  
    return 0;
}

int imin(int n,int m)
{
    int min;

    if (n < m)
        min = n;
    else
        min = m;
  
    return min;
}

程式分析:imin 識別符號在不同位置出現了三次:

  • 函式原型(function prototype)告知編譯器 imin() 的函式型別。
  • 函式呼叫(function call)導致 imin() 函式的執行。
  • 函式定義(function definition)確切指定 imin() 函式的具體功能。

一、原型宣告

  • 使用函式前需要用 ANSI 原型宣告該函式。函式原型宣告返回值型別、引數個數及各引數的型別。
int imin(int n,int m);   /* prototype the function */
/* 使用逗號分隔的型別列表指明引數的個數和型別 */

int imin(int, int);      /* prototype the function */
/* 可以根據個人喜好省略變數名 */

二、函式呼叫

  • 函式呼叫導致該函式的執行:
imin(evil1,evil2);   /* use the function */
  • evil1 和 evil2 被稱為實際引數。實際引數可以是常量、變數或表示式。

三、函式定義

  • 函式定義以 ANSI C 函式頭開始,且ANSI C 要求在每個變數前宣告其型別:
int imin(int n,int m)
  • 變數 n 和 m 被稱為形式參量。形式參量是區域性變數,與其他函式中的變數(即使同名)相互獨立、互不影響。

四、使用 return 從函式中返回一個值

  • 在一個具有返回值的函式中,關鍵字 return 指明瞭其後的表示式即是該函式的返回值。
  • return 語句的另一作用是終止執行函式,並把控制返回給呼叫函式的下一語句,即使 return 語句不是函式的最後一個語句。
  • 許多 C 程式設計師更傾向於只在函式結尾使用一次 return 語句。

9.3  遞迴

C 允許一個函式呼叫其本身。這種呼叫過程被稱作遞迴(recursion)。

  • 優點:在某些程式設計問題上,遞迴提供了最簡單的解決方法。
  • 缺點:一些遞迴演算法會很快耗盡計算機的記憶體資源;遞迴的程式難於閱讀和維護。

9.4  多原始碼檔案程式的編譯

  • 在 Windows 系統下的編譯器是面向工程的。工程(project)描述了一個特定的程式所使用的資源。這些資源包括原始碼檔案。使用這種編譯器執行單檔案程式時,必須建立工程。而對於多檔案程式,需要將原始碼檔案加入到一個工程之中,且工程必須包括所有的原始碼檔案(.c 檔案),但標頭檔案(.h 檔案)不能包含在工程之中。因為工程只管理所使用的原始碼檔案,而使用哪些標頭檔案需要由原始碼檔案中的 #include 指令確定。
  • 把函式原型和常量定義放在一個頭檔案中是一個和好的變成習慣。

9.5  地址運算子:&

  • 一元地址運算子 & 可以取得變數的儲存地址。變數的地址可以看作是該變數在記憶體中的位置。
/* 假設 pooh 是一個變數名,那麼 &pooh 就是該變數的地址. */
/* 假定 pooh 賦值為24,pooh 的儲存地址是0B76,那麼語句: */
pooh = 24;
printf("%d %p", pooh, &pooh);
/* 將輸出如下數值(%p 是輸出地址的說明符):            */
24 0B76

9.7  指標簡介

  • 指標是一個其數值為地址的變數(更一般地說是一個數據物件)。
  • 普通的變數把它的數值作為基本數值量,而通過使用地址運算子&將它的地址作為間接數值量。
  • 對指標來說,它把地址作為基本數值量,而通過使用間接運算子*將地址中儲存的數值作為間接數值量。
/* 若某個指標變數名為ptr */
ptr = & pooh;    /* 把pooh的地址賦給ptr,注意&pooh是一個常量,而ptr是一個變數 */
  • 間接運算子:*
/* 若某個指標變數名為ptr */
ptr = & pooh;    /* 把pooh的地址賦給ptr,注意&pooh是一個常量,而ptr是一個變數 */
val = * ptr;     /* 使用間接運算子*來獲取pooh中存放的數值 */
  • 指標宣告
int * pi;    /* 型別識別符號表明了被指向變數的型別,星號(*)表明變數pi為一指標 */
  • 使用指標在函式間通訊:使用函式交換 x 和 y 的值。
/* swap3.c -- using pointers to make swapping work */
#include <stdio.h>
void interchange(int * u, int * v);

int main(void)
{
    int x = 5, y = 10;

    printf("Originally x = %d and y = %d.\n", x, y);
    interchange(&x, &y);  /* send addresses to function  */
    printf("Now x = %d and y = %d.\n", x, y);

    return 0;
}

void interchange(int * u, int * v)    /* u的值為&x,*u代表x的值 */
{
    int temp;

    temp = *u;       /* temp gets value that u points to */
    *u = *v;
    *v = temp;
}