程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 不可或缺 Windows Native (6),windowsnative

不可或缺 Windows Native (6),windowsnative

編輯:關於C語言

不可或缺 Windows Native (6),windowsnative


[源碼下載]


不可或缺 Windows Native (6) - C 語言: 函數



作者:webabcd


介紹
不可或缺 Windows Native 之 C 語言

  • 函數



示例
cFunction.h

#ifndef _MYHEAD_FUNCTION_
#define _MYHEAD_FUNCTION_ 

#ifdef __cplusplus  
extern "C"
#endif  

// 函數聲明
// 像這種在 .h 中聲明的函數,如果想被外部文件調用的話,則外部文件不用再聲明即可調用
char *demo_cFunction();

long recursion(int n);

void update(int ary[], int aryLength);
// 也可以將上面的函數聲明寫成下面這種形式,像這種只有參數類型,沒有參數名稱的函數聲明稱之為函數原型(function prototype)
// void update(int[], int);

void demo_variable1();

void demo_variable2();

void demo_params();



// 加上 static 關鍵字就是內部函數,僅能在當前文件使用;在不同的文件中如果有同名的內部函數,則他們互不干擾
static void cFunction_demo1();

// 加上 extern 關鍵字就是外部函數,可被其他文件調用
extern void cFunction_demo2();

// 如果既無 static 也無 extern,則默認為 extern
void cFunction_demo3();

#endif


cFunction.c

/*
 * 函數
 *
 *
 * 1、從變量的作用域(scope)角度來分,可以分為全局變量(外部變量)和局部變量
 * 2、從變量的生存期角度來分,可以分為靜態存儲方式和動態存儲方式
 *
 *
 * argument - 實參
 * parameter - 形參
 */

#include "pch.h"
#include "cFunction.h"
#include "cHelper.h"


// 全局變量(亦稱外部變量),作用域(scope)是整個源程序
int global01 = 100;


// 像這種定義在 .c 中的函數(無論在 .c 文件中有無函數聲明),如果想被外部文件調用的話,則外部文件在調用之前需要先聲明
void function0()
{
    ;
}

char *demo_cFunction()
{
    // 函數定義在之前,則不用聲明也可以調用(同一文件);函數定義在之後,則必須先聲明才可以調用
    function0();



    // 以下為無參數無返回值的函數聲明(declare),其同 void demo_cFunction1();
    void function1(void);

    // 以下為有參數有返回值的函數聲明
    int function2(int a, int b);
    
    // 也可以將上面的函數聲明寫成下面這種形式,像這種只有參數類型,沒有參數名稱的函數聲明稱之為函數原型(function prototype)
    // int demo_cFunction2(int, int); 


    // 無參數,無返回值函數演示
    function1();


    // 有參數,有返回值函數演示
    int a = 1, b = 1;  // 這裡的 a 和 b 是實參
    int x = function2(a, b);


    // 函數遞歸
    long y = recursion(100); // 結果:5050


    // 向函數傳遞數組類型的演示
    // 之前說過 ary 是數組的首地址,也就是說傳遞過去的是指針,也就是說實參和形參其實指向的是一個地方,相當於引用類型
    int ary[] = {0, 1, 2, 3, 4 };
    update(ary, 5); // 數組 ary 被更新了


    // 局部變量和全局變量的演示
    demo_variable1();


    // 變量存儲方式的演示
    demo_variable2();


    // 參數不定的函數(可變參數)
    demo_params();


    return "看代碼及注釋吧";
}


// 無參數,無返回值函數演示
void function1()
{
    // 空參數時,寫 void 和不寫 void 的區別(C 語言建議沒有參數時使用 void)

    /*
    void fun(); // 代表可以傳遞任意參數(C++ 則代表不能傳遞任何參數)
    fun(1); // 正常編譯(在本例中這麼做其實是會編譯錯誤的,因為用的是 C++ 編譯器)
    fun(1, 2, 3); // 正常編譯(在本例中這麼做其實是會編譯錯誤的,因為用的是 C++ 編譯器)
    */

    /*
    void fun(void); // 代表不能傳遞任何參數
    fun(1); // 編譯錯誤
    fun(1, 2, 3); // 編譯錯誤
    */
}


// 有參數,有返回值函數演示
int function2(int a, int b) 
{
    // 這裡的 a 和 b 是形參,形參就是實參的副本
    // 形參變量只在被調用期間才分配內存單元,調用結束立即釋放,也就是說形參變量只有在函數內才是有效的,離開該函數就不能再使用了,即形參的作用於在函數內
    return a + b;
}


// 演示函數的遞歸調用
// return: 0 + 1 + 2 + 3 + ... + n
long recursion(int n)
{
    long result = 0 ;
    
    if (n > 0)
    {
        result += n;
        result += recursion(n - 1);
    }

    return result;
}


// 參數為數組類型的演示(之所以需要傳遞 aryLength 數組長度,是因為傳遞過來的 ary 是個指針,無法計算其指向的數組長度。就好像 main 函數似的,需要傳遞參數個數)
void update(int ary[], int aryLength)
{
    // 此處實參和形參其實指向的是一個地方
    for (int i = 0; i < aryLength; i++)
    {
        ary[i] = 0;
    }

}


// 局部變量和全局變量的演示
void demo_variable1()
{
    // 我是局部變量,作用域在函數內
    int i = 1;
    {
        // 我是復合語句內的局部變量,作用域在復合語句內,不能與復合語句外的局部變量重名
        int j = 1;
    }

    // 我是局部變量,如果全局變量有與我同名的,則“屏蔽”全局變量
    int global01 = 200;

    // 上面“屏蔽”了全局變量,那我要怎麼引用全局變量呢?像下面這樣用“::”
    int global01Outside = ::global01;
}


// 變量存儲方式的演示
void demo_variable2()
{
    // 從變量的生存期角度來分,可以分為靜態存儲方式和動態存儲方式
    // 1、靜態存儲方式:是指在程序運行期間分配固定的存儲空間的方式
    // 2、動態存儲方式:是在程序運行期間根據需要進行動態的分配存儲空間的方式


    // 全局變量在程序運行期間都會被分配固定的存儲空間(靜態存儲方式)

    // 局部變量默認就是 auto 的,即動態分配存儲空間。下面這句寫全了就是 auto int i = 0;(動態存儲方式)
    int i = 0;  

    // 如果希望函數中的局部變量的值在函數調用結束後不消失的話,則應該用 static 指定局部變量為“靜態局部變量”(靜態存儲方式)
    static int j = 0;

    // 用 register 指定“寄存器變量”,其會保存在 cpu 中的寄存器中。一個最佳場景是,將其作為循環控制的變量
    // 寄存器變量無地址,所以不能用“&”對其取地址(C++ 可以取其地址,但是編譯器會自動將其變為內存變量)。另外,寄存器不夠用的話會自動變為內存變量
    register int x = 0;
    
    // 用 volatile 保證變量必在內存中,而不會被放入 cpu 寄存器(如果編譯器認為某變量無外部修改,則為了優化會將其放入寄存器)
    volatile int y = 0;


    // 全局變量是在函數的外部定義的,它的作用域為從變量定義處開始,到本程序文件的末尾
    // 如果在定義點之前的函數想引用該全局變量,則應該使用 extern 表明該變量在別的地方已經定義過了,在這裡要使用那個變量
    extern int global02, global03; // 如果沒有這句的話,則編譯會報“未聲明的標識符”的錯誤

    int p02 = global02;
    int p03 = global03;
}

int global02 = 200, global03 = 300;



// 以下演示如何定義及使用參數不定的函數(可變參數)

#include <stdarg.h> // 其定義了 va_start, va_arg, va_end (va 應該是 variable argument(可變參數)的簡寫)

void demo_params()
{
    // 計算 n 個整數的平均值,第一個參數代表後面的參數的個數
    float average(int paramCount, ...);

    float result =  average(4, 1, 2, 3, 4); // 2.5
}

float average(int paramCount, ...)
{
    // 定義一個參數列表
    va_list va_params;

    long sum = 0;

    // 告知不定參數的個數,並准備讀取參數
    va_start(va_params, paramCount);

    for (int i = 0; i < paramCount; i++)
    {
        // 一個一個地按照指定的類型讀取參數的值,每讀取完一個,參數指針就會向後移動繼續讀取下一個
        int value = va_arg(va_params, int);
        sum += value;
    }

    // 停止讀取參數
    va_end(va_params);

    return sum * 1.0f / paramCount;
}



OK
[源碼下載]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved