Karakter varsayılan olarak imzalı veya imzasız mı?


158

"C'nin Tam Referansı" kitabında charvarsayılan olarak imzasızdır.

Ancak bunu GCC ve Visual Studio ile doğrulamaya çalışıyorum. Varsayılan olarak imzalanmış olarak alıyor .

Hangisi doğru?


5
Güvendiğim bir C referans kitabı Harbison & Steele'nin "C: A Referans Kılavuzu" dur ( careferencemanual.com ). Tabii ki standart son kelimedir, ancak çok okunabilir değildir ve sadece standart dışındaki standart ve yaygın (yani POSIX) kullanımlar hakkında en ufak bir bilgi verir. Harbison & Steele oldukça okunabilir, ayrıntılı ve çoğu referanstan daha doğrudur. Bununla birlikte, aynı zamanda bir öğretici değildir, bu yüzden öğrenmenin ilk aşamalarındaysanız, muhtemelen atlamak için harika bir şey değildir.
Michael Burr

15
Bence okuduğunuz kitap C: The Complete Reference , Herbert Schildt. Bu kitabın bir incelemesinden ( accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm ): Bu kitabı tavsiye etmeyeceğim (çok fazla görüşüme çok fazla ağırlık veriyorsunuz) ama Diğer çalışmalarının bazılarında meşru bir şekilde atılan karşıtlığı hak ettiğini düşünmüyorum. Michael'ın dediği gibi, çok daha iyi bir referans Harbison & Steele'dir .
Alok Singhal

Benim iki sent burada: Çünkü charimzasız olabilir, bir başparmak kural olarak intkullanarak bir değeri okumak için kullanın getchar(), hangi dönebilir EOF. EOFgenellikle bir -1veya içinde başka bir negatif değer olarak tanımlanır unsigned. İşte deklarasyon: extern int getchar();BTW, bu öneri aynı zamanda "C: Bir Başvuru Kılavuzu" kitabından da gelmektedir.
Maxim Chetrusca

6
Güvendiğim bir C referansı ISO / IEC 9899: 2011 :-)
Jeff

3
@MaxChetrusca iyi bir tavsiye ama kötü bir gerekçe: imzalanan chardavada bile int, iade değerini saklamak için kullanmanız gerekir.
Antti Haapala

Yanıtlar:


204

Kitap yanlış. Standart, düz charimzalı veya imzasız olup olmadığını belirtmez .

Aslında, standart üç farklı tiplerini tanımlar: char, signed charve unsigned char. Eğer varsa #include <limits.h>ve daha sonra bakmak CHAR_MINdüz eğer öğrenebilirsiniz charolduğu signedveya unsigned(eğer CHAR_MIN0'dan küçüktür veya 0'a eşit), ama o zaman bile, üç tip farklıdır standart söz konusu kadarıyla kadar.

charBu şekilde özel olduğunu unutmayın . Bir değişkeni, int% 100 eşdeğer olduğu şeklinde bildirirseniz signed int. Bu, tüm derleyiciler ve mimariler için her zaman doğrudur.


1
@Alok: aynısı diğer veri türleri için de geçerli değil, örneğin her zaman intdemek signed int, değil mi? Bunun dışında char, başka hangi veri tiplerinde aynı karışıklık var C?
Lazer

8
@ eSKay: evet, charimzalanabilen veya imzalanamayan tek tiptir. inteşdeğerdir signed intörneğin.
Alok Singhal

28
Bunun histerik, er, tarihsel bir nedeni var - C'nin hayatının başlarında "standart" en az iki kez flip-flop edildi ve bazı popüler erken derleyiciler bir şekilde ve diğerleri de sona erdi.
Hot Licks

9
@AlokSinghal: Bit tipinde bir alanın intimzalı veya imzasız olup olmadığı da uygulanır .
Keith Thompson

@ KeithThompson düzeltme için teşekkürler. Çok fazla kullanmadığım için bit alan tipleri hakkında bazı detayları unutmaya meyilliyim.
Alok Singhal

67

Alok'un belirttiği gibi , standart bunu uygulamaya bırakır.

Gcc için varsayılan imzalanmıştır, ancak bunu ile değiştirebilirsiniz -funsigned-char. not: Android NDK'da gcc için varsayılan işaretsizdir . Ayrıca açıkça ile imzalı karakterleri isteyebilirsiniz -fsigned-char.

MSVC'de, varsayılan olarak imzalanmıştır, ancak ile değiştirebilirsiniz /J.


2
Kitapları genellikle MSVC kullanıcılarına yönelik olduğu için Schildt'in açıklamasının MSVC'nin davranışıyla eşleşmemesi ilginçtir. Acaba MS bir noktada varsayılan değişti mi?
Michael Burr

1
Derleyiciye değil, platforma bağımlı olduğunu düşündüm. Ben char o zaman sistemlerin yazdırılabilir karakterler olarak kullanılan ne uygun üçüncü tip "karakter veri türü" olarak kaldı düşündüm.
Spidey

10
GCC dokümanları , makineye bağlı olduğunu söylüyor: " Her makine türü, karakterin olması gereken bir varsayılan var. Varsayılan olarak imzasız karakter veya varsayılan olarak imzalı karakter gibi. "
Deduplicator

1
Android için varsayılan imzasız char olduğunu notunuz için bir kaynak sağlayabilir misiniz?
phlipsy

1
@Spidey C standardı derleyiciler, platformlar ve CPU mimarileri arasında gerçek bir ayrım yapmaz. Sadece "uygulama" altında hepsini bir araya getiriyor.
plugwash

35

C99 N1256 taslak 6.2.5 / 15 "Türler" türün imzalılığı hakkında şunları söyler char:

Uygulama char'ı imzalı char veya unsigned char ile aynı aralığa, temsile ve davranışa sahip olacak şekilde tanımlamalıdır.

ve dipnotta:

CHAR_MIN, içinde tanımlanan <limits.h>değerlerden birine sahip olacak 0veya SCHAR_MINbu iki seçeneği ayırt etmek için kullanılabilir. Yapılan seçime bakılmaksızın char, diğer ikisinden ayrı bir tiptir ve her ikisiyle de uyumlu değildir.


7

ANSI C için fiili standart kitap olan Dennis Ritchie'nin C Programlama Dili kitabına göre, imzalı veya imzasız düz karakterler makineye bağımlıdır, ancak yazdırılabilir karakterler her zaman pozitiftir.


9
Yazdırılabilir karakterlerin her zaman pozitif olması şart değildir . C standardı, temel yürütme karakter kümesinin tüm üyelerinin negatif olmayan değerlere sahip olduğunu garanti eder.
Keith Thompson

7

C standardına göre, düz karakterin imzası "uygulama tanımlı" dır.

Genel olarak uygulayıcılar, mimarileri için hangisinin daha verimli uygulanacağını seçtiler. X86 sistemlerinde karakter genellikle imzalanır. Kol sistemlerinde genellikle imzasızdır (Apple iOS bir istisnadır).



2
@plugwash Tim Post anahtarlarını kaybettiği için cevabınız muhtemelen reddedildi . Ciddi bir şekilde, cevabınızın doğru olduğundan emin olduğunuz sürece (bu durumda) tek bir düşüş hakkında endişelenmemelisiniz. Mesajlarımın geçerli bir sebep olmadan reddedilmesi birkaç kez başıma geldi. Endişelenme, bazen insanlar tuhaf şeyler yapar.
Donald Duck

1
İmzalı karakter x86'da neden daha verimli? Herhangi bir kaynak var mı?
martinkunev

2

Bjarne Stroustrup'un "C ++ Programlama Dili" ne göre char"uygulama tanımlı" dır. Bu olabilir signed charveya unsigned charuygulamaya bağlı olabilir . charKullanarak imzalı olup olmadığını kontrol edebilirsiniz std::numeric_limits<char>::is_signed.


9
Bu bir C sorusu. C ++ farklı bir dildir ve C ++ referanslarının C ile hiçbir ilgisi yoktur
MM

1

Şimdi, standardın bunu uygulamaya bıraktığını biliyoruz.

Ancak bir türün nasıl kontrol edileceği signedveya unsignedgibi char?

Bunu yapmak için bir makro yazdım:

#define IS_UNSIGNED(t) ((t)~1 > 0)

ve ile test gcc, clangve cl. Ama diğer durumlar için her zaman güvenli olduğundan emin değilim.


Her zamanki CHAR_MIN <0 (veya wchar_t için WCHAR_MIN <0) ile ilgili sorun nedir?
Öö Tiib
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.