Dosya kapsamında değişken olarak değiştirilmiş dizi


87

".M" dosyamın en üst düzeyinde buna benzer şekilde Objective-C uygulama dosyamda kullanılacak sabit bir statik dizi oluşturmak istiyorum:

static const int NUM_TYPES = 4;
static int types[NUM_TYPES] = { 
  1,
  2, 
  3, 
  4 };

NUM_TYPESDosyada daha sonra kullanmayı planladığım için onu bir değişkene koymak istedim.

Ancak bunu yaptığımda hata alıyorum

"Dosya kapsamında değişken olarak değiştirilmiş" türler "

Bunun dizi boyutunun değişken olmasıyla bir ilgisi olabileceğini anlıyorum (gibi bir tamsayı koyduğumda bu mesajı alamıyorum static int types[4]).

Bunu düzeltmek istiyorum, ama belki de tamamen yanlış yapıyorum ... Burada 2 hedefim var:

  1. Dosya boyunca erişilebilen bir diziye sahip olmak
  2. NUM_TYPESDosyamdaki farklı yerlere dağılmış aynı değişmez bilginin olmaması için bir değişkeni kapsüllemek için

Herhangi bir öneri?

[DÜZENLE] Bunu C Faq'da buldum: http://c-faq.com/ansi/constasconst.html


2
Bunun yerine bir tanım olarak yaparsanız ne olur? #define kNUM_TYPES 4?
Jorge Israel Peña

Bu işe yarıyor ... nedense ön işlemciyi kullanmaktan uzak durmaya çalışıyordum çünkü bunu bir yerde okuduğumu hatırladığımı düşündüm, ancak biraz daha araştırma yaptım ve bu durumda kullanmamak için iyi bir neden bulamadım. Önişlemcide (gibi @"An NSString literal") nesneler oluşturursam daha az arzu edilir olduğunu düşünüyorum . Kod parçanızla ilgili tek sorun, noktalı virgülün gerekmemesidir.
Sam

Ah evet, uyarılar için teşekkürler ve yardımcı olabildiğime sevindim.
Jorge Israel Peña

Yanıtlar:


63

Bu uyarının nedeni , c'deki const'ın sabit anlamına gelmemesidir. "Salt okunur" anlamına gelir. Bu nedenle, değer bir bellek adresinde saklanır ve potansiyel olarak makine kodu ile değiştirilebilir.


3
Tanımlanmış bir nesneyi değiştirmek const( constbir işaretçiden uzağa atma ve bir değer saklama gibi) tanımsız bir davranıştır; bu nedenle, böyle bir nesnenin değeri bir derleme zamanı veya çalışma zamanı sabitidir (depolama süresine bağlı olarak). Değer, sabit bir ifadede kullanılamaz çünkü C standardı olabileceğini söylemiyor. ( constHedef nesne tanımlanmadan constveya dinamik olarak tahsis edilmeden tanımlanmışsa, bir değerin constatılmasına ve depolanmasına izin verilir ; dize değişmezleri yazılmaz, ancak yazılamaz.)
jilles

3
@jilles "potansiyel olarak makine koduyla değiştirilebilir", bu cevabın yazarının "C koduyla potansiyel olarak değiştirilebileceği" anlamına gelmez. Dahası, bunun çok iyi bir nedeni daha var: externFarklı TU'larda mevcut TU derlenirken değeri bilinmeyen sabitler olabilir .

15
Bu yanıtı iyileştirmenin bir yolu, bu sorunun nasıl çözüleceğini göstermektir.
George Stocker

33

Diğer yanıtlara göre ön işlemciyi yine de kullanacaksanız, derleyicinin otomatik olarak değerini belirlemesini sağlayabilirsiniz NUM_TYPES:

#define NUM_TYPES (sizeof types / sizeof types[0])
static int types[] = { 
  1,
  2, 
  3, 
  4 };

Vay canına, bu gerçekten harika ... Bunun mümkün olduğunu bilmiyordum. Bu hesaplamanın maliyetinin ihmal edilebilir olduğunu varsayıyorum. Bir derleyicinin bunu statik bir değere optimize edebileceğini de varsayabilir miyim?
Sam

2
Evet, bunun sizeofgibi nesneler üzerindeki sonucu bir derleme zamanı sabitidir.
caf


11

Numaralandırmayı kullanmak da mümkündür.

typedef enum {
    typeNo1 = 1,
    typeNo2,
    typeNo3,
    typeNo4,
    NumOfTypes = typeNo4
}  TypeOfSomething;

4

Diğer cevaplarda zaten açıklandığı gibi, constC'de yalnızca bir değişkenin salt okunur olduğu anlamına gelir. Hala bir çalışma zamanı değeridir. Ancak, bir enumC de gerçek sabit olarak kullanabilirsiniz :

enum { NUM_TYPES = 4 };
static int types[NUM_TYPES] = { 
  1, 2, 3, 4
};

3

Imho, bu birçok c derleyicide bir kusurdur. Çalıştığım derleyicilerin bir adreste "statik sabit" değişkeni saklamadıklarını, koddaki kullanımı çok sabit ile değiştirdiklerini biliyorum. Bir önişlemciler #define yönergesi kullandığınızda ve statik bir const değişkeni kullandığınızda, üretilen kod için aynı sağlama toplamını alacağınız için bu doğrulanabilir.

Her iki durumda da, mümkün olduğunda #defines yerine statik sabit değişkenleri kullanmanız gerekir, çünkü statik sabit tür açısından güvenlidir.


Bir static constdeğişkenin adresini alabildiğiniz için kulağa oldukça kötü geliyor . Tanımladığınız davranış geçerli bir optimizasyon olabilir, ancak kesinlikle her zaman işe yarayabilecek bir şey değildir.
gevşeyin

Aslında iyi. C derleyicisinin, const global değişkenlerinin bireysel kullanımlarını mümkün olan her yerde sabit değerle değiştirmesi uygundur. Bir değişkene yapılan tüm referanslar sabitlere dönüştürülürse, derleyici onu tamamen kaldırabilir. Adresi herhangi bir yerde kullanırsanız, kaldırılmaz. Bunların hiçbiri, dil standardına göre, değişken sabit olsun ya da olmasın, boyut olarak değişken olan global dizilere C'nin izin vermemesini değiştirmez.
Evan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.