An'ın ne enum
olduğunu ve ne zaman kullanılacağını temelde anladığımı sanmıyorum .
Örneğin:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Burada gerçekten ne ilan ediliyor?
An'ın ne enum
olduğunu ve ne zaman kullanılacağını temelde anladığımı sanmıyorum .
Örneğin:
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Burada gerçekten ne ilan ediliyor?
Yanıtlar:
İsimsiz bir numaralandırılmış tipi bildirildi: Üç şey burada beyan ediliyor ShapeType
isimsiz sayımı için bir typedef ilan ediliyor ve üç isim kCircle
, kRectangle
ve kOblateSpheroid
ayrılmaz sabitleri olarak ilan edilmektedir.
Bunu parçalayalım. En basit durumda, bir numaralandırma şu şekilde ilan edilebilir:
enum tagname { ... };
Bu, etiketle bir numaralandırma bildirir tagname
. C ve Objective-C (ama içinde değil C ++), bu ilişkili başvurular gerekir ile gelmelidir enum
anahtar kelime. Örneğin:
enum tagname x; // declare x of type 'enum tagname'
tagname x; // ERROR in C/Objective-C, OK in C++
enum
Anahtar kelimeyi her yerde kullanmak zorunda kalmamak için bir typedef oluşturulabilir:
enum tagname { ... };
typedef enum tagname tagname; // declare 'tagname' as a typedef for 'enum tagname'
Bu tek bir satıra sadeleştirilebilir:
typedef enum tagname { ... } tagname; // declare both 'enum tagname' and 'tagname'
Ve biz kullanmak gerekiyor yoksa son olarak, enum tagname
birlikte enum
anahtar kelime, biz yapabilir enum
anonim ve tek typedef adı ile beyan:
typedef enum { ... } tagname;
Şimdi, bu durumda, ShapeType
anonim bir numaralandırmanın tip tanımlı bir adı olduğunu beyan ediyoruz . ShapeType
gerçekten sadece ayrılmaz bir türüdür ve sadece (bir birini bildiriminde listelenen değerlerden birini tutmak değişkenleri bildirmek için kullanılması gerektiğini kCircle
, kRectangle
ve kOblateSpheroid
). ShapeType
Bununla birlikte, bir değişkeni başka bir değer atayarak atayabilirsiniz , bu nedenle numaralandırma değerlerini okurken dikkatli olmanız gerekir.
Son olarak, kCircle
, kRectangle
, ve kOblateSpheroid
genel ad ayrılmaz sabitleri olarak ilan edilir. Belirli bir değer belirtilmediğinden, 0 ile başlayan ardışık tamsayılara atanırlar, yani kCircle
0, kRectangle
1 ve kOblateSpheroid
2'dir.
Apple, Xcode 4.4'ten beri böyle numaraların tanımlanmasını önerir :
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Ayrıca kullanışlı bir makro sağlarlar NS_ENUM
:
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
Bu tanımlar daha güçlü tip kontrolü ve daha iyi kod tamamlama sağlar. Ben resmi belgelerine bulamadı NS_ENUM
ama WWDC 2012 oturumdan "Modern Objective-C" video izleyebilirsiniz burada .
GÜNCELLEME Burada
resmi belgelere bağlantı .
NS_ENUM
makrosunun NSHipster tarafından yapılan açıklamasına bakın : NSHipster.com/ns_enum-ns_options
Olası değerler içeren bir kullanıcı tanımlı tür kCircle
, kRectangle
ya da kOblateSpheroid
. Numaralandırma içindeki değerler (kCircle, vb.) Numaralandırmanın dışında görülebilir. Bunu akılda tutmak önemlidir ( int i = kCircle;
örneğin geçerlidir).
64 bitlik değişiklik için güncelleme: Apple belgelerine göre yaklaşık 64 bitlik değişiklikler,
Numaralandırmalar da Yazılır: LLVM derleyicisinde numaralandırılmış türler numaralandırmanın boyutunu tanımlayabilir. Bu, bazı numaralandırılmış türlerin de beklediğinizden daha büyük bir boyuta sahip olabileceği anlamına gelir. Çözüm, diğer tüm durumlarda olduğu gibi, bir veri türünün boyutu hakkında hiçbir varsayımda bulunmamaktır. Bunun yerine, doğru veri türüne sahip bir değişkene numaralandırılmış değerleri atayın
Bu yüzden 64-bit için destekliyorsanız, aşağıdaki sözdiziminde tür ile enum oluşturmalısınız .
typedef NS_ENUM(NSUInteger, ShapeType) {
kCircle,
kRectangle,
kOblateSpheroid
};
veya
typedef enum ShapeType : NSUInteger {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Aksi takdirde, Implicit conversion loses integer precision: NSUInteger (aka 'unsigned long') to ShapeType
Hızlı programlama için güncelleme:
Hızlıca bir sözdizimi değişikliği var.
enum ControlButtonID: NSUInteger {
case kCircle , kRectangle, kOblateSpheroid
}
Numaralandırma (numaralandırmanın kısaltması) bir dizi değeri (numaralandırıcılar) numaralandırmak için kullanılır. Değer, bir sembolle (kelime) temsil edilen soyut bir şeydir. Örneğin, temel bir numaralandırma
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl };
Bu numaralandırma anonim olarak adlandırılır, çünkü bunu adlandırmak için bir sembolünüz yoktur. Ama yine de tamamen doğru. Sadece böyle kullan
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
Tamam. Hayat güzel ve her şey yolunda gidiyor. Ancak bir gün myGrandFatherPantSize'ı depolamak için yeni bir değişken tanımlamak için bu numaralandırmayı yeniden kullanmanız gerekir, sonra şunu yazın:
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandFatherPantSize;
Ama sonra derleyici hatası "numaralandırıcı yeniden tanımlama" var. Aslında sorun, derleyicinin ilk numaralandırdığınızdan ve ikinci olarak da aynı şeyi tanımladığından emin olmamasıdır.
Daha sonra aynı numaralandırıcı setini (burada xs ... xxxxl) birkaç yerde yeniden kullanmak istiyorsanız, benzersiz bir adla etiketlemelisiniz. Bu seti ikinci kez kullandığınızda etiketi kullanmanız yeterlidir. Ancak bu etiketin numaralandırma sözcüğü yerine yalnızca numaralandırma kümesinin yerini aldığını unutmayın. Sonra enum'u her zamanki gibi kullanmaya dikkat edin. Bunun gibi:
// Here the first use of my enum
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl } myGrandMotherDressSize;
// here the second use of my enum. It works now!
enum sizes myGrandFatherPantSize;
bir parametre tanımında da kullanabilirsiniz:
// Observe that here, I still use the enum
- (void) buyANewDressToMyGrandMother:(enum sizes)theSize;
Her yerde enum'u yeniden yazmanın uygun olmadığını ve kodun biraz garip görünmesini sağlayabilirsiniz. Haklısın. Gerçek bir tür daha iyi olurdu.
Bu zirveye büyük ilerlememizin son adımı. Sadece bir typedef ekleyerek enumumuzu gerçek bir türe dönüştürelim. Ah son şey, typedef'e sınıfınızda izin verilmiyor. Ardından türünüzü hemen yukarıda tanımlayın. Şöyle yapın:
// enum definition
enum sizes { xs,s,m,l,xl,xxl,xxxl,xxxxl };
typedef enum sizes size_type
@interface myClass {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
Etiketin isteğe bağlı olduğunu unutmayın. O zamandan beri, bu durumda, numaralandırıcıları değil, sadece yeni bir tür tanımlamak için etiketliyoruz. O zaman artık buna gerçekten ihtiyacımız yok.
// enum definition
typedef enum { xs,s,m,l,xl,xxl,xxxl,xxxxl } size_type;
@interface myClass : NSObject {
...
size_type myGrandMotherDressSize, myGrandFatherPantSize;
...
}
@end
XCode ile Objective-C geliştiriyorsanız NS_ENUM ön ekine sahip bazı güzel makrolar keşfetmenize izin verir. Bu, iyi numaralandırmaları kolayca tanımlamanıza yardımcı olacaktır ve dahası, statik analizörün derlemeden önce sizin için bazı ilginç kontroller yapmasına yardımcı olacaktır.
İyi Enum!
typedef
varolan bir değişken türünün adını yeniden tanımlamak için kullanışlıdır. Bir veri tipini çağırmak için kısa ve anlamlı bir yol sağlar. Örneğin:
typedef unsigned long int TWOWORDS;
burada, unsigned long int türü TWOWORDS türünde olarak yeniden tanımlanır. Böylece artık imzasız uzun int türünde değişkenler yazarak,
TWOWORDS var1, var2;
onun yerine
unsigned long int var1, var2;
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
o zaman şöyle kullanabilirsiniz: -
ShapeType shape;
ve
enum {
kCircle,
kRectangle,
kOblateSpheroid
}
ShapeType;
şimdi şöyle kullanabilirsiniz: -
enum ShapeType shape;
enum, yapı içinde yapılamayan enum öğelerine değer atamak için kullanılır. Bu nedenle, tam değişkene erişmek yerine her zaman enum'daki değişkenlere atadığımız değerle yapabiliriz. Varsayılan olarak 0 atamasıyla başlar, ancak herhangi bir değer atayabiliriz ve enum'daki bir sonraki değişkene önceki değere +1 değeri atanır.
Aşağıdaki biçimde kullanabilirsiniz, 0'dan başlayan Raw varsayılan değeri,
Kendi başlangıç değerinizi atayabilirsiniz.
typedef enum : NSUInteger {
kCircle, // for your value; kCircle = 5, ...
kRectangle,
kOblateSpheroid
} ShapeType;
ShapeType circleShape = kCircle;
NSLog(@"%lu", (unsigned long) circleShape); // prints: 0
Typedef, programcının bir Objective-C türünü diğeri olarak tanımlamasını sağlar. Örneğin,
typedef int Sayaç; Sayaç türünü int türüne eşdeğer olarak tanımlar. Bu, kod okunabilirliğini büyük ölçüde artırır.
Typedef, C ve C ++ 'da bir Anahtar Kelimedir. Temel veri türleri (char, int, float, double, struct & enum) için yeni adlar oluşturmak için kullanılır .
typedef enum {
kCircle,
kRectangle,
kOblateSpheroid
} ShapeType;
Burada, numaralandırılmış ShapeType veri türünü oluşturur ve aşağıda verildiği gibi enum Type ShapeType için yeni adlar yazabiliriz
ShapeType shape1;
ShapeType shape2;
ShapeType shape3;
enum birçok "hata" türünü azaltabilir ve kodu daha yönetilebilir hale getirebilir
#define STATE_GOOD 0
#define STATE_BAD 1
#define STATE_OTHER 2
int STATE = STATE_OTHER
Tanımın herhangi bir kısıtlaması yoktur. Bu sadece bir ikame. Devletin tüm koşullarını sınırlayamaz. STATE 5'e atandığında, eşleşen bir durum olmadığından program yanlış olacaktır. Ancak derleyici STATE = 5'i uyarmayacak
Yani böyle kullanmak daha iyidir
typedef enum SampleState {
SampleStateGood = 0,
SampleStateBad,
SampleStateOther
} SampleState;
SampleState state = SampleStateGood;