Object-C基礎(4)—— 函數

來源:互聯網
上載者:User

標籤:

C是一門結構化的程式設計語言,Objective-C是C的超集。

為什麼要定義函數?

        為了方便複用某段代碼,可以將這段代碼定義成一個函數,以後每次調用該函數,就相當於讓程式去執行這段代碼。

定義函數(function)的文法

     返回值類型 函數名(形參列表)

     {

     }

     返回值類型:可以是任何有效類型(基本類型、構造類型、參考型別)。

                所謂返回值類型,決定了該函數執行成功之後,所返回的結果的類型。

                因此如果沒有返回值類型,應該將返回值型別宣告為void。

                如果不寫返回值類型,表明返回值類型為int。

                如果聲明了返回值類型(包括不寫),程式應該在函數體使用return語句來返回函數的返回值。

      函數名:標識符即可。

               實際上,函數名應該一個或多個有意義的單詞連綴而成。

      形參列表: 形參類型 形參名, 形參類型 形參名, ...

               每個形參都必須由 形參類型和形參名所組成。

調用函數

        注意點:

        1. 聲明函數時指定了幾個形參,調用函數時就需要傳入幾個參數、而且參數的類型要一致。

        2. 函數的返回值,既可用變數去裝;也可立即拿來用掉(將函數返回值放入運算式中)。

函式宣告

     C語言是從上到下的,預設要求:函數必須先定義、再使用。

      對於如下兩種情況:

     - 函數定義在函數調用處的後面。

     - 函數定義在另一個源檔案中。

      此時就需要使用函式宣告 —— 函式宣告就是告訴編譯器:這個函數是存在的。

      函式宣告:就是重要函數的返回值類型、函數名、形參類型即可,不要函數執行體。

                         注意:函式宣告時既可有形參名,也可沒有形參名。

       import語句,就是匯入大量的函式宣告。

      由於函式宣告必須在所有函數調用的前面,因此程式就需要將#import語句放在程式在最上面。

函數的傳參機制

        Object-C的傳參機制是“值傳遞”,程式傳入函數的只是參數本身的副本(複製品),

        因此函數所參數所作的修改,對參數本身是沒有任何影響的。

       注意:對於傳遞指標的情形,實際上傳遞的依然是指標的複製品(副本)。

遞迴函式

       如果一個函數,調用了自身,該函數就會形成遞迴函式。

       遞迴,可實現一個隱式的迴圈。

       與迴圈類似的是,遞迴也必須有結束的時候。

       遞迴:一定要有結束的時,要向已知的方向遞迴。

使用數組本身(數組的本質就是指標)作為參數

      注意:

            1. 當在函數中聲明數群組類型的參數時,既可指定數組的長度,也可不指定數組的長度,但通常都不會指定。

            2. 由於數組本身是一個指標,因此傳入函數的並不是數組本身,只是一個指標的副本。

                 因此函數無法通過sizeof來擷取被傳入的數組的長度。

            3. 由於數組本身是指標,因此函數對數組元素所做的修改會影響數組本身的元素的。

內建函式與外部函數

     C語言是結構化程式設計語言,因此函數是C的一等公民:

            一個C程式通常是由於很多個函數組成,程式員開發的函數,可能還需要依賴系統內建的函數。

            由此可見:C語言程式,可能由成千上萬的函數組成,但最多隻能有一個main函數

            —— 它作為程式的入口,其他函數都是直接或間接地被main函數調用,所有函數的地位是平等。

     每個函數都可調用別的函數,也可被別的函數調用。

     static修飾符的作用之一:把外部東西(函數、全域變數),變成內部東西(函數、全域變數)。

           - static函數,就是內建函式——只能在當前源檔案中被調用。

          - 沒static修飾或extern修飾的函數,可以任何地方被調用(只要先做函式宣告即可)。

     對於內建函式,程式只有通過直接把原始碼import進來才可以調用內建函式。

     而外部函數,程式即使拿不到定義函數的原始碼,只要有定義函數的原始碼產生的庫,程式也可通過函式宣告之後來調用外部函數。

 

局部變數與全域變數

        C的變數分為:

        局部(local)變數:在函數裡、方法裡定義的變數,都是局部變數。

                 局部變數儲存在各自的棧區中,函數、方法執行結束時,棧區被銷毀。

                 特徵:只在定義該變數的函數、方法內有效,函數、方法執行完,局部變數立即消失。             

        全域(global)變數:在檔案範圍內定義的變數,都是全域變數。

                 全域變數儲存在整個程式的記憶體(靜態儲存區)中。程式不結束,靜態儲存區不會消失。

                 特徵:只要程式不退出,全域變數將一直有效。

        細分局部變數,又可分為:

      - 形參:從函數被調用開始,形參開始生效,函數結束時,參數失效。

      - 方法裡局部變數:從定義該變數開始生效,函數結束時,該變數失效。

      - 代碼塊的局部變數:從定義該變數開始生效,代碼塊結束時,該變數失效。

        包括在if條件體、迴圈體、for迴圈的初始化語句中定義的變數,都屬於代碼塊的局部變數,離開了定義該變數的花括弧地區,那麼該變數就失效了。

        細分全域變數

      - static全域變數,就是內部[全域]變數——只能在當前源檔案中被調用。

      - 沒static修飾的全域變數,可以任何地方被調用(只要先做變數聲明即可)。

       變數聲明:如果程式要使用其他來源程式中定義的全域變數時,就必須做變數聲明。文法是:

        extern 類型變數名;

       局部變數的儲存機制:

        定義局部變數時,有如下幾個修飾符:

       auto - 有auto和沒auto效果是一樣的。也就是說,你定義的所有的局部變數,預設就相當於有個auto。

                 auto修飾的局部變數,會被儲存到函數或方法的棧區中。

       static - 把局部變數放到靜態儲存區中。

                對於static的局部變數而言,只要程式不退出,靜態局部變數將一直有效。

                由於static局部變數會一直有效,因此程式只有第一次調用函數時,才會對static局部變數賦初始值。

       register - 控制把局部變數放入寄存器中。

                 但OS並不保證register變數一定會進入寄存器,所以實際上這個修飾用的並不多。

        關於定義變數的原則:

        1. 程式應該優先使用局部變數(全域變數是非常糟糕的設計、會造成牽一髮而動全身的效果)。

        2. 如果局部變數需要能在函數、方法結束時,依然可以儲存上次啟動並執行資料,或者該變數只希望第一次調用時被初始化,

               該局部變數應該用static修飾。

        3. 實在沒辦法,才考慮使用全域變數。

        典型的,當一個程式單元需要把資料共用給另外一個程式單元時,正確做法是參數傳遞,而不是全域變數。

        static修飾符有2個作用:

         - 修飾全域函數、全域變數,使之變成內建函式、內部全域變數。

              - 修飾局部變數,使之成為靜態局部變數——靜態局部變數會被儲存到程式的靜態儲存區。

        extern修飾符也有2個作用:

                - 聲明全域變數。

                - 修飾外部函數。————但實際上,不用extern效果也是一樣的。


預先處理

       預先處理:程式在編譯階段就會處理調用東西,這些預先處理指令不會保留到運行階段。

       對於來源程式中包含的預先處理,編譯器會在編譯階段處理完成,到運行時就不存在預先處理指令。

       預先處理的特徵:

            - 通常在程式的開頭。

             - 必須以#開始。

       #define 或 #undef定義宏變數和取消宏

       #define定義的又被稱為:“宏(macro)變數”。

       #define的作用是:編譯器在處理常式之前,先執行尋找、替換。

       通過#define定義宏變數有兩個好處:

         - 可以方便程式以後修改。

         - 可以提高程式的可讀性。

       #undef:取消宏定義

       #define還可以定義帶參數的宏

       對於帶參數的宏定義而言,有兩點要注意:

         - 定義宏的參數時,並不是定義函數的參數,因此宏的參數無需指定參數類型。

         - 使用宏的參數時,一定要參數放在圓括弧中。

       使用#ifdef   #ifndef   #else   #endif執行條件編譯。

          它的用法基本上和前面介紹的分支是一樣的。

          它們的主要作用是判斷指定的宏是否存在,根據指定宏是否存在來執行相應的分支。

       使用#if #elif #else#endif執行條件編譯。

        預先處理的if分支比普通的if分支的效率要高的多。

         能用預先處理的if分支,應該盡量使用預先處理的if分支。

         記住:只要你的if條件中包含了變數、函數調用等運算式,就只能使用普通的if分支。

         #include和#import

         #include和#import的功能是類似的,但#import的功能更強大一些。

         #import就可以自動避免重複include導致的錯誤。

Object-C基礎(4)—— 函數

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.