2010-08-19 11 views
7
int main(void) 
{ 
    char four[4] = "four"; 
    return 0; 
} 

, G ++char dörtlü [4] = "dört"; Bu ifadenin doğru semantiği nedir? bir C++ programı derlenmiş

xxx.cpp rapor: işlev int ana():

xxx.cpp: 3: hatası: dizisi için başlatıcı dizgisi karakter sayısı çok uzun

Bir C programı derlendiğinde, GCC hata bildirmez.

Görünüşe göre, atama beklediğim gibi 4 baytlık bir değişkeni doğru şekilde kopyalıyor.

Benim soru

, C gözlenen davranış doğru mu yoksa bir yere tanımlanmamış bir davranış dokunuyorum ..... aşağı kaynar ya da tamamen başka bir şeydir?

+1

Burada bu soruya verilen yanıtlara çok benzer bir soru var: http://stackoverflow.com/questions/3216462/initializing-char-arrays-in-a-way-similar-to-initializing-string-literals –

+0

Bunu bulmak için tebrikler. Evet Bu sorunu biraz tartışıyor. – EvilTeach

cevap

22

Kısa yanıt: kodunuz geçerli C, ancak geçerli değil C++.

Uzun aswer:

"four" aslında uzun 5 karakter - senin için orada eklenen bir \0 yoktur. bölüm 6.7.8 Başlatma, paragraf 13, C standart diyor ki: o farklı şekilde davranıyor C. C++ olarak derlenmiş zaman

An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

Yani \0 sadece programda göz ardı edilir. dört harf:

There shall not be more initializers than there are array elements. [ Example:

char cv[4] = "asdf"; // error 

is ill-formed since there is no space for the implied trailing ’\0’ . — end example ]

+1

C de bu geçerlidir, ancak bazı seviyelerde bir uyarı vermelidir. – Joel

+0

@Joel, Bir uyarı olması gerektiğini düşünmüyorum, standart tamamen güvenli ve iyi tanımlanmış olduğunu gösteriyor gibi görünüyor. –

+0

Sizeof ("four") 5 bayt iken, yalnızca 4 bayt değişkene kopyalanır. – EvilTeach

2

dize "dört" aslında beş bayt içerir: Aslında bu özel durum (8.5.2 Karakter diziler, paragraf 2 Bölüm) C++ spec açıkça dışarı denir artı bir dize sonlandırıcı olarak sıfır bayt (\ 0). C veya C++ yazdığımdan beri bir süre geçti, ama C derleyicisinin ne olursa olsun sessizce görmezden geleceğini tahmin ediyorum. Daha iyi

2

Gördüğünüz, C ve C++ arasındaki farktır

char four[] = "four"; 
+0

Hem C hem de C++'da beş dizili bir dizi verir ve harika çalışır. –

+0

@David, yalnızca * beş karakterli bir dizi istiyorsanız *. Ama umursamıyorsanız, bu yol kesinlikle daha fazla korunabilir. –

+0

Doğru, neredeyse hiçbir zaman char dört [4] = "four" istemediğini iddia ediyorum. –

1

olurdu. C, yok sayılan ekstra başlatıcılara sahip olmanızı sağlar. C++ bunu yasaklar - bir dizge (veya dizi) için bir boyut belirtirseniz, ,'un tüm başlatıcıları (bir dize durumunda NUL terminatör dahil) alabilecek kadar geniş veya kod bozuk ("izin verilmez" için standartlar - derleyicinin onu reddetmesini bekler ").

+0

Hayır. Bence ekstra NUL özel bir durum olarak kabul edilir. Eğer bunu char yaparsanız dört [4] = "fiveX"; C. – EvilTeach

+0

@EvilTeach - Bir hata, "5X" durumda bir hata değil, bir uyarı alıyorum. –

+0

@EvilTeach (ve Carl): Bu (büyük ölçüde) standartlarla ilgili bir zorluğa geri dönüyor: yanlış kod için bir "teşhis" gerektiriyorlar (ancak eğer seçtiyse derleyici kodu yine de kabul edebilir), ancak Bir tanılayıcı olanı tanımlamak (ya da değil) derleyici. Ayrıca, belirli bayrakların uyumluluk için gerekli olduğu da normaldir, bu yüzden varsayılan olarak bu kadar çok şey alamayabilirsiniz. –