【C】 43_函數的意義

C語言中的函數

  • 函數的由來

程序 = 數據 + 算法
==>
C程序 = 數據 + 函數 (定義算法)算法

函數的意義

  • 模塊化程序設計

clipboard.png

  • C語言中的模塊化

clipboard.png

面向過程的程序設計

  • 面向過程是一種以過程爲中心的編程思想
  • 首先將複雜的問題分解爲一個個容易解決的問題
  • 分解後的問題能夠按照步驟一步步完成
  • 函數是面向過程在 C 語言中的體現
  • 解決問題的每一個步驟能夠用函數來實現

聲明和定義

  • 聲明的意義在於告訴編譯器程序單元的存在
  • 定義則明確指示程序單元的存在
  • C 語言中經過 extern 進行程序單元的聲明
  • 一些程序單元在聲明時能夠省略 extern

嚴格意義上的聲明和定義並不一樣編程

實例分析: 聲明和意義不一樣

實驗 1app

test.c
#include <stdio.h>
#include <malloc.h>

extern int g_var;    // 變量聲明,不分配內存空間

extern struct Test;

int main()
{
    extern void f(int i, int j);
    extern int g(int x);
    
    struct Test* p = NULL;
    
    printf("p = %p\n", p);
    
    printf("g_var = %d\n", g_var);
    
    f(1, 2);
    
    printf("g(3) = %d\n", g(3));
    
    free(p);
    
    return 0;
}
global.c
#include <stdio.h>

int g_var = 10;    // 變量定義,分配內存空間

struct Test
{
    int x;
    int y;
};

void f(int i, int j)
{
    printf("i + j = %d\n", i + j);
}

int g(int x)
{
    return (int)(2 * x + g_var);
}
輸出:
p = (nil)
g_var = 10
i + j = 3
g(3) = 16

實驗 2模塊化

test.c
#include <stdio.h>
#include <malloc.h>

extern int g_var;

extern struct Test;

int main()
{
    extern void f(int i, int j);
    extern int g(int x);
    
    struct Test* p = (struct test*)malloc(sizeof(struct Test));  // 注意這裏!
    
    printf("p = %p\n", p);
    
    printf("g_var = %d\n", g_var);
    
    f(1, 2);
    
    printf("g(3) = %d\n", g(3));
    
    free(p);
    
    return 0;
}
global.c
#include <stdio.h>

int g_var = 10;

struct Test
{
    int x;
    int y;
};

void f(int i, int j)
{
    printf("i + j = %d\n", i + j);
}

int g(int x)
{
    return (int)(2 * x + g_var);
}
編譯輸出:
test.c:13: error: invalid application of ‘sizeof’ to incomplete type ‘struct Test’ 
test.c:13: warning: initialization from incompatible pointer type

發生了什麼?函數

在連接階段以前,各個文件之間的編譯是互相獨立的。
test.c 中,對 struct Test 進行聲明,僅告訴編譯器其定義於其它文件,但在本文件中,沒法獲取它的詳細信息,sizeof()不知道返回怎樣的值,所以報錯。

實驗 3spa

test.c
#include <stdio.h>
#include <malloc.h>

extern int g_var;  // 注意聲明的類型!

extern struct Test;

int main()
{
    extern void f(int i, int j);
    extern int g(int x);
    
    struct Test* p = NULL;
    
    printf("p = %p\n", p);
    
    printf("g_var = %d\n", g_var);
    
    f(1, 2);
    
    printf("g(3) = %d\n", g(3));
    
    free(p);
    
    return 0;
}
global.c
#include <stdio.h>

float g_var = 10;    // 注意定義的類型!

struct Test
{
    int x;
    int y;
};

void f(int i, int j)
{
    printf("i + j = %d\n", i + j);
}

int g(int x)
{
    return (int)(2 * x + g_var);
}
輸出:
p = (nil)
g_var = 1092616192
i + j = 3
g(3) = 16

發生了什麼?設計

在global.c定義爲 float ,test.c 聲明爲 int ,編譯器沒有發出警告!;
global.c 中,g_var 內存空間中 4 字節二進制數據將按照 float 類型進行解釋;
test.c   中,g_var 內存空間中 4 字節二進制數據將按照 int   類型進行解釋;
在 c 語言中, float 與 int 的存儲方式不一樣,致使輸出不一樣。

小結

  • 函數是面向過程思想在 C 語言中的體現
  • 面向過程是由上至下分解問題的設計方法
  • 程序中的定義和聲明徹底不一樣
  • C 語言中經過 extern 對程序單元進行聲明

以上內容參考狄泰軟件學院系列課程,請你們保護原創!code

相關文章
相關標籤/搜索