




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、Objective-C-2.0程序設(shè)計-第10章-變量和數(shù)據(jù)類型知識Objective-C-2.0程序設(shè)計-第10章-變量和數(shù)據(jù)類型(1)第第10章章 變量和數(shù)據(jù)類型變量和數(shù)據(jù)類型存儲類說明符10.3枚舉數(shù)據(jù)類型10.4作用域回顧10.2類的初始化10.1typedef語句10.5數(shù)據(jù)類型轉(zhuǎn)換10.610.1 類的初始化 前面已經(jīng)出現(xiàn)過這種模式:使用以下常見序列,分配對象的新實例,然后對它初始化:Fraction *myFract = Fraction alloc init; 調(diào)用這兩個方法之后,通常向這個新對象指派一些值,如下所示:myFract setTo: 1 over: 3; 初始化對
2、象之后為其設(shè)置初值的過程通常可以合并到一個方法中。例如,你可以定義一個initWith:方法,它初始化一個分?jǐn)?shù),并將其分子和分母設(shè)置為兩個給定的參數(shù)。 包含很多方法和實例變量的類通常還有幾個初始化方法。例如,F(xiàn)oundation框架中的NSArray類包含了以下6中初始化方法:initWithArray:initWithArray:copyItems:initWithContentsOfFile:initWithContentsOfURL:initWithObjects:initWithObjects:count:10.1 類的初始化 常見的編程習(xí)慣是類中所有初始化方法都以init開頭。在編寫
3、初始化方法時,應(yīng)該遵循以下兩個策略。 如果你的類包含多個初始化方法,其中一個就應(yīng)該是指定的初始化方法,其他所有初始化方法都應(yīng)該使用這個方法。通常,它是最復(fù)雜的初始化方法(一般是參數(shù)最多的初始化方法)。通過創(chuàng)建指定的初始化方法,可以把大部分初始化代碼集中到單個方法中。然后,任何人想要從該類派生子類,就可以重載這個指定的初始化方法,以便保證正確的初始化新的實例。 一定要恰當(dāng)?shù)爻跏蓟魏卫^承來的實例變量。最簡單的方式就是首先調(diào)用父類指定的初始化方法,大多數(shù)情況下是init方法,然后可以初始化自己的實例變量。 基于這個討論,F(xiàn)raction類的初始化方法initWith:可能如下所示:-(Fracti
4、on *) initWith: (int) n: (int) dself = super init;if (self)self setTo: n over: d;return self;10.1 類的初始化 這個方法首先調(diào)用父類的初始化方法,也就是NSObject的init方法。初始化的結(jié)果需要指派回self,因為初始化方法有權(quán)更改或移動內(nèi)存中的對象。 完成Super的初始化之后,使用setTo:over:方法設(shè)置Fraction的分子和分母。和其他初始化方法一樣,希望由你返回初始化的對象,在這里你就是這樣做的。 代碼清單10-1測試了新的初始化方法initWith:。10.1 類的初始化類的
5、初始化方法init模板:-(instancetype)init:self = super init;if (self)/初始化代碼初始化代碼return self;10.1 類的初始化 代碼清單10-1-#import “Fraction.h”int main (int argc, char *argv)NSAutoreleasePool * pool = NSAutoreleasePool alloc init;Fraction *a, *b;a = Fraction alloc initWith: 1: 3;b = Fraction alloc initWith: 3: 7;a print
6、;b print;a release;b release;pool drain;return 0;輸出:1/33/7第第10章章 變量和數(shù)據(jù)類型變量和數(shù)據(jù)類型存儲類說明符10.3枚舉數(shù)據(jù)類型10.4類的初始化10.1typedef語句10.5數(shù)據(jù)類型轉(zhuǎn)換10.6作用域回顧10.210.2 作用域回顧 可以使用幾種方式影響程序中變量的作用域??梢愿淖儗嵗兞恳约岸x在函數(shù)外部或內(nèi)部的普通變量的作用域。在下面的討論中,我們使用術(shù)語模塊(module)來引用包含在一個源文件中任何數(shù)目的方法或者函數(shù)定義。10.2.1 控制實例變量作用域的指令控制實例變量作用域的指令 目前,你知道實例變量的作用域只限于
7、為該類定義的實例方法。因此,任何實例方法都能直接通過變量名來訪問該類的實例變量,而無需特別的操作。 在接口部分聲明實例變量時,可以把以下三個指令放在實例變量之前,以便更精準(zhǔn)的控制它們的作用域,它們是:vprotected這個指令后面的實例變量可被該類及任何子類中定義的方法直接訪問。這是默認(rèn)情況。vprivate這個指令后面的實例變量可被定義在該類的方法直接訪問,但不能被子類中定義的方法訪問。vpublic這個指令后面的實例變量可被該類中定義的方法訪問,也可被其他類或模塊中定義的方法直接訪問vpackage對于64位圖像,可以在實現(xiàn)該類的圖像的任何地方訪問這個實例變量。10.2.1 控制實例變量
8、作用域的指令控制實例變量作用域的指令 如果要定義一個名為Printer的類,它包含兩個私有實例變量pageCount和tonerLevel,并且只有Printer類中的方法才能直接訪問它們,那么可以如下使用接口部分:interface Printer: NSObjectprivateint pageCount;int tonerLevel;protected/ other instance variables.end10.2.2 外部變量外部變量 如果在程序的開始處(所有方法,類定義和函數(shù)定義之外)編寫一下語句:int gMoveNumber = 0;那么這個模塊中的任何位置都可以引用這個變量
9、的值。在這種情況下,我們說gMoveNumber 被定義為全局變量。為了向閱讀程序的人說明變量的作用域,按照慣例,用小寫的g作為全局變量的首字母。 實際上,這樣的定義使得其他文件也可以訪問變量gMoveNumber 的值。確切地說,前面的語句不僅將gMoveNumber 定義為全局變量,而且將其定義為外部全局變量。 外部變量是可被其他任何方法或函數(shù)訪問和更改其值的變量。在需要訪問外部變量的模塊中,變量聲明和普通方式一樣,只是需要在聲明前加上關(guān)鍵字extern。這就告知系統(tǒng),要訪問其他文件中定義的全局變量。下面這個例子說明如何將gMoveNumber 聲明為外部變量:extern int gMo
10、veNumber; 現(xiàn)在,包含前面這個聲明的模塊就可以訪問和改變gMoveNumber的值。同樣,通過在文件中使用類似的extern聲明,其他模塊也可以訪問gMoveNumber的值。10.2.2 外部變量外部變量 使用外部變量時,必須遵循下面這條重要原則:變量必須定義在源文件中的某個位置。這是通過在所有方法和函數(shù)外部聲明,并且前面不加關(guān)鍵字extern,如下所示:int gMoveNumber; 定義外部變量的第二種方式是在所有函數(shù)之外聲明變量,在聲明前面加上關(guān)鍵字extern,同時顯示地位變量指派初始值,如下所示:extern int gMoveNumber = 0; 然而這并不是首選的方
11、法。編譯器將給出警告消息:提示你已將變量聲明為extern,并同時為變量賦值。這是因為使用關(guān)鍵字extern表明這條語句是變量的聲明而不是定義。記住,聲明不會引起分配變量的存儲空間,而定義會引起變量的存儲空間的分配。 處理外部變量時,變量可以在許多地方聲明為extern,但是只能定義一次。 通過觀察一個小程序例子來說明外部變量的用法。假設(shè)我們定義了一個名為Foo的類,并將以下代碼鍵入一個名為的文件中。10.2.2 外部變量外部變量#import “Foo.h”int gGlobalVar = 5;int main (int argc, char *argc)NSAutoreleasePool
12、* pool = NSAutoreleasePool alloc init;Foo *myFoo = Foo alloc init;NSLog (”%i “, gGlobalVar);myFoo setgGlobalVar: 100NSLog (”%i”, gGlobalVar);myFoo release;pool drain;return 0;10.2.2 外部變量外部變量 在前面的程序中,gGlobalVar定義為全局變量,因此任何方法(或函數(shù))只要正確地使用extern聲明,都可以訪問它。假設(shè)Foo方法setgGlobalVar:如下所示:-(void) setgGlobalVar:
13、(int) valextern int gGlobalVar;gGlobalVar = val;該程序在終端生成以下結(jié)果:5100 如果有很多方法需要訪問gGlobalVar的值,只在文件的開始進行一次extern聲明將比較簡單。但是如果只有一個或少數(shù)幾個方法要訪問這個變量,就應(yīng)該在其中每個方法中單獨進行extern聲明。這樣將使程序的組織結(jié)果更加清晰,并且使實際使用變量的不同函數(shù)單獨使用這個變量。注意,如果變量定義在包含訪問該變量的文件中,那么不需要單獨的extern聲明。10.2.3 靜態(tài)變量靜態(tài)變量 前面所示的例子與數(shù)據(jù)封裝原則以及良好的面向?qū)ο缶幊碳夹g(shù)相違背。然而,可能需要下面這種變量
14、:它們的值在經(jīng)過不同的方法調(diào)用時是共享的。雖然在Foo類中將gGlobalVar定義為實例變量似乎也不太合理,但是,更好的方法可能是通過將訪問限制在類中定義的setter和getter方法中,將實例變量“隱藏”在Foo類中。 現(xiàn)在,你知道在方法之外定義的變量不僅是全局變量而且是外部變量。然而,在很多情況下你想要將變量定義為全局變量但不是外部變量。換句話說,希望定義的全局變量只在特定模塊中是全局的。這種變量在下面的情況中很有意義:除了特定類中的方法,再也沒有其他方法需要訪問這個特定變量。要做的這一點,可以在包含這個特定類實現(xiàn)的文件中將該變量定義為static。10.2.3 靜態(tài)變量靜態(tài)變量 如果
15、語句static int gGlobalVar = 0;聲明在任何方法之外,那么在該文件中,所有位于這條語句之后的方法都可以訪問gGlobalVar的值,而其他文件中的方法和函數(shù)則不行。 你會想起類方法不能訪問實例變量。然而,可能希望類的方法可以設(shè)定和訪問一些變量。簡單的例子是類的分配器方法,它要記錄類已經(jīng)分配空間的對象數(shù)目。實現(xiàn)這項任務(wù)的方式是在類的實現(xiàn)代碼文件中設(shè)定靜態(tài)變量。由于這個變量不是實例變量,所以分配器方法可以直接訪問它。類的用戶不用知道這個變量。因為它是定義在實現(xiàn)文件中的靜態(tài)變量,作用域只是文件內(nèi)部。因此,用戶不能直接訪問該變量,也就沒有違背數(shù)據(jù)封裝的概念。如果需要從類之外訪問該
16、變量,則可以編寫一個方法來獲取該變量的值。 代碼清單10-2對Fraction類定義進行了擴充,增加了兩個新方法。allocF類方法分配一個新的Fraction對象,同時記錄分配了多少Fraction,count方法則返回這個數(shù)的值。注意,后者也是類方法,也可以作為實例方法實現(xiàn),然而,與向類的特定實例發(fā)送消息相比,詢問類已經(jīng)分配了多少實例更有意義。10.2.3 靜態(tài)變量靜態(tài)變量 下面是需要在實現(xiàn)文件中加入的代碼。static int gCounter;implementation Fraction+(Fraction *) allocFextern int gCounter;+gCounter
17、;return Fraction alloc;+(int) countextern int gCounter;return gCounter;/ other methods from Fraction class go here.end注意:重載alloc并不是好的編程實踐,因為這個方法處理內(nèi)存的物理分配。你不應(yīng)該涉足10.2.3 靜態(tài)變量靜態(tài)變量 代碼清單10-2測試這個新方法 代碼清單10-2-#import “Fraction.h”int main (int argc, char *argv)NSAutoreleasePool * pool = NSAutoreleasePool all
18、oc init;Fraction *a, *b, *c;NSLog (”Fractions allocated: %i”, Fraction count);a = Fraction allocF initb = Fract on allocF initc = Fraction allocF init;NSLog (”Fractions allocated: %i”, Fraction count);a release;b release;c release;pool drain;return 0;輸出:Fractions allocated: 0Fractions allocated: 3第第
19、10章章 變量和數(shù)據(jù)類型變量和數(shù)據(jù)類型作用域回顧10.2枚舉數(shù)據(jù)類型10.4類的初始化10.1typedef語句10.5數(shù)據(jù)類型轉(zhuǎn)換10.6存儲類說明符10.310.3.1 auto 這個關(guān)鍵字用來聲明一個自動局部變量,與static相反。這是函數(shù)或方法內(nèi)部變量的默認(rèn)聲明方式,并沒有人使用它。下面是一個例子:auto int index; 該語句聲明index為一個自動局部變量,意味著在進入該塊時,自動為它分配存儲空間,并在退出該塊時自動解除分配。因為在塊中是默認(rèn)的,因此語句int index;和語句auto int index;是等效的。 靜態(tài)變量是有默認(rèn)的初始值0,而自動變量沒有默認(rèn)的初始
20、值。除非顯示地給自動變量賦值,否則它們的值是不確定的。10.3.2 const 編譯器允許你給對程序中值不變的變量設(shè)置const特性。這樣,就告訴編譯器,指定的變量在程序運行期間都有恒定的值。在初始化變量后,如果嘗試給const變量指派一個值,或視圖將其增1或減1,編譯器就會給出警告消息。局一個const特性的例子,代碼const double pi = 3.141592654;聲明了一個const變量pi。這就告訴編譯器,程序不會修改該變量。當(dāng)然,因為隨后不能更改const變量的值,因此必須在定義變量時就進行初始化。10.3.3 volatile 這個類型和const正好相反。它明確告訴編譯
21、器,指定類型變量的值會改變。在語言中加入這個關(guān)鍵字是為了防止編譯器優(yōu)化掉看似多余的變量賦值,同時避免重復(fù)地檢查值沒有變化的變量。I/O端口就是一個很好的例子,這涉及到對指針的理解。 加上在程序中,將輸出端口的地址存儲在一個名為outPort的變量中。如果要向這個端口寫兩個字符,可能會寫出下面的代碼:*outPort = O;*outPort = N; 第一行表示在outPort指定的內(nèi)存地址存儲字符O,第二行表示在同一位置存儲字符N。一個智能的編譯器可能發(fā)現(xiàn)對同一地址進行了兩次連續(xù)的賦值。因為outPort在這兩者之間并沒有被修改,所以編譯器將第一個賦值語句從程序中刪除。要防止這種情況發(fā)生,應(yīng)
22、該將outPort聲明為一個volatile變量:volatile char *outPort;第第10章章 變量和數(shù)據(jù)類型變量和數(shù)據(jù)類型作用域回顧10.2存儲類說明符10.3類的初始化10.1typedef語句10.5數(shù)據(jù)類型轉(zhuǎn)換10.6枚舉數(shù)據(jù)類型10.410.4 枚舉數(shù)據(jù)類型枚舉數(shù)據(jù)類型 Objective-C語句使得你可以將一系列值指派給一個變量。枚舉數(shù)據(jù)類型的定義以關(guān)鍵字enum開頭,之后是枚舉數(shù)據(jù)類型的名稱,然后是標(biāo)識符序列,它們定義了可以給該類型指派的所有允許值。例如:enum flag false, true ;定義了一個數(shù)據(jù)類型flag。從理論上說,在程序中這個數(shù)據(jù)類型只能指
23、派true和false兩種值,不能指派其他的值。遺憾的是,即使違背了這個規(guī)則,Objective-C編譯器也不會發(fā)出警告消息。 要聲明一個enum flag類型的變量,仍需要關(guān)鍵字enum,之后是枚舉類型名稱,最后是變量序列。所以語句enum flag endOfData, matchFound;定義了兩個flag類型的變量endOfData和matchFound。能指派給這兩個變量的值只有true和false。10.4 枚舉數(shù)據(jù)類型枚舉數(shù)據(jù)類型 如果希望一個枚舉標(biāo)識符對應(yīng)一個特定的整數(shù)值,那么可以在定義數(shù)據(jù)類型時給該標(biāo)識符指定整數(shù)值。在列表中依次出現(xiàn)的枚舉標(biāo)識符被指派了特定整數(shù)值開始的序列數(shù)
24、。 在定義enum direction up, down, left = 10, right ;中,定義了一個保護up,down,left和right的枚舉數(shù)據(jù)類型direction。因為up在序列中位于首位,所以編譯器給其賦值為0,down為1;由于left明確被賦值為10,所以它的值就是10;right的值有列表中前一個enum的值遞增得到,因此值為11. 枚舉標(biāo)識符可以共享相同的值。如:enum boolean no = 0, false = 0, yes = 1, true = 1 ; 下面定義了類型enum mouth:enum month january = 1, february
25、, march, april, may, june, july,august, september, october, november, december ;Objective-C編譯器實際上將枚舉標(biāo)識符作為整型常量來處理。thismouth的值是整數(shù)2.enum month thisMonth;.thisMonth = february;10.4 枚舉數(shù)據(jù)類型枚舉數(shù)據(jù)類型 代碼清單10-3-int main (int argc, char *argv)NSAutoreleasePool * pool = NSAutoreleasePool alloc init;enum month jan
26、uary = 1, february, march, april, may, june,july, august, september, october, november,december ;enum month amonth;int days;NSLog (”Enter month number: “);scanf (“%i”, &amonth);switch (amonth) case january:case march:case may:case july:case august:case october:case december:days = 31;break;10.4
27、枚舉數(shù)據(jù)類型枚舉數(shù)據(jù)類型case april:case june:case september:case november:days = 30;break;case february:days = 28;break;default:NSLog (”bad month number”);days = 0;break;if ( days != 0 )NSLog (”Number of days is %i”, days);if ( amonth = february )NSLog (”.or 29 if its a leap year”);pool drain;return 0;輸出:Enter
28、month number:5Number of days is 31輸出:Enter month number:2Number of days is 28.or 29 if its a leap year10.4 枚舉數(shù)據(jù)類型枚舉數(shù)據(jù)類型 可以明確的給枚舉類型的變量指派一個整數(shù)值,這應(yīng)該使用類型轉(zhuǎn)換運算符 。因此,如果monthValue的值是6,那么表達式lastMonth = (enum month) (monthValue - 1);是允許的。 使用包含枚舉數(shù)據(jù)類型的程序時,盡量不要依賴枚舉值被當(dāng)做整數(shù)這個事實。相反,應(yīng)該盡量把它們當(dāng)做獨立的數(shù)據(jù)類型。 在定義枚舉數(shù)據(jù)類型時,也允許有所變
29、化:可以省略數(shù)據(jù)類型的名稱,定義該類型時,以將變量聲明為特定枚舉數(shù)據(jù)類型中的一個。舉出一個同時展示這兩種選擇的例子,語句:enum east, west, south, north direction;定義了一個(未命名的)枚舉數(shù)據(jù)類型,它包含的值為east,west,south和north,同時還聲明了該類型的變量direction。第第10章章 變量和數(shù)據(jù)類型變量和數(shù)據(jù)類型作用域回顧10.2存儲類說明符10.3類的初始化10.1枚舉數(shù)據(jù)類型10.4數(shù)據(jù)類型轉(zhuǎn)換10.6typedef語句10.510.5 typedef語句語句 Objective-C提供了一種能力,編程者可以為數(shù)據(jù)類型另外指
30、派一個名稱。這是通過所謂的typedef語句實現(xiàn)的。語句typedef int Counter;定義名稱Counter等價于Objective-C數(shù)據(jù)類型int。隨后的變量就可以聲明為Counter類型,如在一下語句中:Counter j, n;Objective-C編譯器實際上是將變量j和n的聲明當(dāng)做前面顯示的普通整型變量。 在這種情況下使用typedef語句的主要好處是增加了變量定義的可讀性。從j和n的定義中就可以清晰地看出這些變量在程序中的目的。 下面的typedef將一個名為NumberObject的類型定義為Number對象:typedef Number *NumberObject;
31、隨后將一些變量聲明為NumberObject類型,如在語句NumberObject myValue1, myValue2, myResult;中,它們的使用方式和以常規(guī)方式在程序中聲明一樣,如下所示:Number *myValue1, *myValue2, *myResult;10.5 typedef語句語句 Objective-C提供了一種能力,編程者可以為數(shù)據(jù)類型另外指派一個名稱。這是通過所謂的typedef語句實現(xiàn)的。語句typedef int Counter;定義名稱Counter等價于Objective-C數(shù)據(jù)類型int。隨后的變量就可以聲明為Counter類型,如在一下語句中:Counter j, n;Objective-C編譯器實際上是將變量j和n的聲明當(dāng)做前面顯示的普通整型變量。 在這種情況下使用typedef語句的主要好處是增加了變量定義的可讀性。從j和n的定義中就可以清晰地看出這些變量在程序中的目的。 下面的typedef將一個名為NumberObject的類型定義為Number對象:typedef Number *NumberObject;隨后將一些變量聲明為NumberObject類型,如在語句NumberObject myValue1, myValue2, myResult;中,它們的使用方式和以常規(guī)方式在程序中
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 合同范例在下
- 廈門學(xué)校食堂承包合同范例
- 臨時土地合同范本
- 吉他老師合同范本
- 2025年麻風(fēng)二聯(lián)苗合作協(xié)議書
- 債權(quán)協(xié)議合同范本
- 綠化設(shè)計苗木合同范本
- 代辦貸款定金合同范例
- 勞動合同范本講解
- 發(fā)票業(yè)務(wù)合同范本
- 公司員工獎懲制度流程
- 星巴克案例分析-星巴克成功之道
- 把未來點亮歌詞打印版
- 危險化學(xué)品建設(shè)項目竣工驗收報告
- 國家中醫(yī)藥管理局第3批24個專業(yè)104個病種中醫(yī)診療方案
- 婦產(chǎn)科學(xué)(第9版)第三章 女性生殖系統(tǒng)生理
- LY/T 2241-2014森林生態(tài)系統(tǒng)生物多樣性監(jiān)測與評估規(guī)范
- GB/T 9086-2007用于色度和光度測量的標(biāo)準(zhǔn)白板
- 2023年山東力明科技職業(yè)學(xué)院高職單招(數(shù)學(xué))試題庫含答案解析
- GB/T 24338.4-2018軌道交通電磁兼容第3-2部分:機車車輛設(shè)備
- GB/T 19326-2003鋼制承插焊、螺紋和對焊支管座
評論
0/150
提交評論