Satu buku referensi C yang saya percayai adalah "C: A Reference Manual" milik Harbison & Steele ( careferencemanual.com ). Tentu saja standar adalah kata terakhir, tetapi itu tidak terlalu mudah dibaca dan hanya memberikan sedikit informasi tentang penggunaan pra-standar dan umum (mis., POSIX) yang berada di luar standar. Harbison & Steele cukup mudah dibaca, terperinci dan mungkin lebih benar daripada kebanyakan referensi. Namun, ini juga bukan tutorial, jadi jika Anda berada di tahap awal pembelajaran, mungkin bukan hal yang baik untuk dilakukan.
Michael Burr
15
Saya pikir buku yang Anda baca adalah C: The Complete Reference , oleh Herbert Schildt. Dari ulasan buku ini ( accu.informika.ru/accu/bookreviews/public/reviews/c/c002173.htm ): Saya tidak akan merekomendasikan buku ini (terlalu banyak dari Anda memberikan terlalu banyak pendapat pada pendapat saya) tetapi Saya tidak berpikir itu layak atas kelemahan yang sama yang telah dilemparkan secara sah pada beberapa karyanya yang lain. Seperti kata Michael, referensi yang jauh lebih baik adalah Harbison & Steele .
Alok Singhal
Dua sen saya di sini: Karena chardapat ditandatangani, sebagai aturan praktis gunakan a intuntuk membaca nilai menggunakan getchar(), yang mungkin kembali EOF. EOFbiasanya didefinisikan sebagai -1atau nilai negatif lainnya, yang menyimpan dalam unsignedbukan apa yang Anda inginkan. Inilah deklarasi: extern int getchar();BTW, rekomendasi ini juga berasal dari buku "C: A Reference Manual".
Maxim Chetrusca
6
Satu referensi C yang saya percayai adalah ISO / IEC 9899: 2011 :-)
Jeff
3
@MaxChetrusca saran yang baik tetapi alasan yang buruk: bahkan pada charkasus yang ditandatangani , Anda harus menggunakan intuntuk menyimpan nilai pengembalian.
Antti Haapala
Jawaban:
204
Buku itu salah. Standar tidak menentukan apakah dataran charditandatangani atau tidak ditandatangani.
Bahkan, standar mendefinisikan tiga jenis yang berbeda: char, signed char, dan unsigned char. Jika Anda #include <limits.h>dan kemudian melihat CHAR_MIN, Anda dapat mengetahui apakah dataran charadalah signedatau unsigned(jika CHAR_MINkurang dari 0 atau sama dengan 0), tetapi bahkan kemudian, ketiga jenis berbeda sejauh standar yang bersangkutan.
Perhatikan bahwa charini istimewa dengan cara ini. Jika Anda mendeklarasikan variabel karena int100% setara dengan mendeklarasikannya sebagai signed int. Ini selalu berlaku untuk semua kompiler dan arsitektur.
@Lok: yang sama tidak benar untuk beberapa tipe data lainnya, misalnya intberarti signed intselalu, kan? Selain itu char, tipe data apa yang memiliki kebingungan yang sama C?
Lazer
8
@ eSKay: ya, charadalah satu-satunya jenis yang bisa ditandatangani atau tidak ditandatangani. intsetara dengan signed intmisalnya.
Alok Singhal
28
Ada alasan histeris, er, historis untuk ini - di awal kehidupan C "standar" terbalik dua kali, dan beberapa kompiler awal populer berakhir dengan satu cara dan lain-lain yang lain.
Hot Licks
9
@ AlokSinghal: Ini juga implementatin-defined apakah jenis bidang bit intditandatangani atau tidak.
Keith Thompson
@KeithThompson terima kasih atas koreksinya. Saya cenderung lupa beberapa detail tentang tipe bidang bit karena saya tidak banyak menggunakannya.
Alok Singhal
67
Seperti yang Alok tunjukkan , standar membiarkan implementasi.
Untuk gcc, standarnya sudah ditandatangani, tetapi Anda dapat memodifikasinya dengan -funsigned-char. Catatan: untuk gcc di Android NDK, defaultnya tidak ditandai . Anda juga dapat secara eksplisit meminta karakter yang ditandatangani dengan-fsigned-char .
Pada MSVC, defaultnya sudah ditandatangani tetapi Anda bisa memodifikasinya dengan /J.
Menarik bahwa deskripsi Schildt tidak cocok dengan perilaku MSVC karena bukunya biasanya ditujukan untuk pengguna MSVC. Saya ingin tahu apakah MS mengubah default di beberapa titik?
Michael Burr
1
Saya pikir itu tidak tergantung pada kompiler, tetapi pada platform. Saya pikir char dibiarkan sebagai tipe ketiga dari "datatype karakter" agar sesuai dengan apa yang digunakan sistem saat itu sebagai karakter yang dapat dicetak.
Spidey
10
Dokumen GCC mengatakan itu bergantung pada mesin: " Setiap jenis mesin memiliki default untuk karakter apa yang seharusnya. Ini seperti char yang tidak ditandai secara default atau seperti char yang ditandatangani secara default. "
Deduplicator
1
Bisakah Anda memberikan sumber untuk catatan Anda bahwa di Android defaultnya adalah tanda unsigned?
phlipsy
1
@Spidey standar C tidak membuat perbedaan nyata antara kompiler, platform dan arsitektur CPU. Itu hanya benjolan mereka semua di bawah "implementasi".
plugwash
35
C99 N1256 konsep 6.2.5 / 15 "Jenis" memiliki ini untuk mengatakan tentang jenis char:
Implementasi harus mendefinisikan char untuk memiliki jangkauan, representasi, dan perilaku yang sama seperti char yang ditandatangani atau char yang tidak ditandatangani.
dan dalam catatan kaki:
CHAR_MIN, didefinisikan dalam <limits.h>, akan memiliki salah satu nilai 0atau SCHAR_MIN, dan ini dapat digunakan untuk membedakan dua opsi. Terlepas dari pilihan yang dibuat, charadalah jenis yang terpisah dari dua lainnya dan tidak kompatibel dengan keduanya.
Menurut buku Bahasa Pemrograman C oleh Dennis Ritchie yang merupakan buku standar de-facto untuk ANSI C, karakter sederhana yang ditandatangani atau tidak ditandatangani bergantung pada mesin, tetapi karakter yang dapat dicetak selalu positif.
Ini tidak selalu berarti bahwa karakter yang dapat dicetak selalu positif. Standar C menjamin bahwa semua anggota set karakter eksekusi dasar memiliki nilai non-negatif.
Keith Thompson
7
Menurut standar C, penandatanganan char biasa adalah "implementasi didefinisikan".
Secara umum implementor memilih mana yang lebih efisien untuk diimplementasikan pada arsitektur mereka. Pada sistem x86, char biasanya ditandatangani. Pada sistem lengan umumnya tidak ditandatangani (Apple iOS adalah pengecualian).
@plugwash Jawaban Anda mungkin diturunkan karena Tim Post kehilangan kuncinya . Serius, Anda tidak perlu khawatir tentang satu downvote selama Anda yakin jawaban Anda benar (yang dalam hal ini). Itu terjadi pada saya beberapa kali agar postingan saya downvoted tanpa alasan yang sah. Jangan khawatir tentang itu, kadang-kadang orang hanya melakukan hal-hal aneh.
Donald Duck
1
Mengapa char yang ditandatangani lebih efisien di x86? Ada sumber?
martinkunev
2
Menurut "Bahasa Pemrograman C ++" oleh Bjarne Stroustrup, charadalah "implementasi yang ditentukan". Itu bisa signed charatau unsigned chartergantung pada implementasi. Anda dapat memeriksa apakah charditandatangani atau tidak dengan menggunakan std::numeric_limits<char>::is_signed.
char
dapat ditandatangani, sebagai aturan praktis gunakan aint
untuk membaca nilai menggunakangetchar()
, yang mungkin kembaliEOF
.EOF
biasanya didefinisikan sebagai-1
atau nilai negatif lainnya, yang menyimpan dalamunsigned
bukan apa yang Anda inginkan. Inilah deklarasi:extern int getchar();
BTW, rekomendasi ini juga berasal dari buku "C: A Reference Manual".char
kasus yang ditandatangani , Anda harus menggunakanint
untuk menyimpan nilai pengembalian.Jawaban:
Buku itu salah. Standar tidak menentukan apakah dataran
char
ditandatangani atau tidak ditandatangani.Bahkan, standar mendefinisikan tiga jenis yang berbeda:
char
,signed char
, danunsigned char
. Jika Anda#include <limits.h>
dan kemudian melihatCHAR_MIN
, Anda dapat mengetahui apakah dataranchar
adalahsigned
atauunsigned
(jikaCHAR_MIN
kurang dari 0 atau sama dengan 0), tetapi bahkan kemudian, ketiga jenis berbeda sejauh standar yang bersangkutan.Perhatikan bahwa
char
ini istimewa dengan cara ini. Jika Anda mendeklarasikan variabel karenaint
100% setara dengan mendeklarasikannya sebagaisigned int
. Ini selalu berlaku untuk semua kompiler dan arsitektur.sumber
int
berartisigned int
selalu, kan? Selain ituchar
, tipe data apa yang memiliki kebingungan yang samaC
?char
adalah satu-satunya jenis yang bisa ditandatangani atau tidak ditandatangani.int
setara dengansigned int
misalnya.int
ditandatangani atau tidak.Seperti yang Alok tunjukkan , standar membiarkan implementasi.
Untuk gcc, standarnya sudah ditandatangani, tetapi Anda dapat memodifikasinya dengan
-funsigned-char
. Catatan: untuk gcc di Android NDK, defaultnya tidak ditandai . Anda juga dapat secara eksplisit meminta karakter yang ditandatangani dengan-fsigned-char
.Pada MSVC, defaultnya sudah ditandatangani tetapi Anda bisa memodifikasinya dengan
/J
.sumber
C99 N1256 konsep 6.2.5 / 15 "Jenis" memiliki ini untuk mengatakan tentang jenis
char
:dan dalam catatan kaki:
sumber
Menurut buku Bahasa Pemrograman C oleh Dennis Ritchie yang merupakan buku standar de-facto untuk ANSI C, karakter sederhana yang ditandatangani atau tidak ditandatangani bergantung pada mesin, tetapi karakter yang dapat dicetak selalu positif.
sumber
Menurut standar C, penandatanganan char biasa adalah "implementasi didefinisikan".
Secara umum implementor memilih mana yang lebih efisien untuk diimplementasikan pada arsitektur mereka. Pada sistem x86, char biasanya ditandatangani. Pada sistem lengan umumnya tidak ditandatangani (Apple iOS adalah pengecualian).
sumber
Menurut "Bahasa Pemrograman C ++" oleh Bjarne Stroustrup,
char
adalah "implementasi yang ditentukan". Itu bisasigned char
atauunsigned char
tergantung pada implementasi. Anda dapat memeriksa apakahchar
ditandatangani atau tidak dengan menggunakanstd::numeric_limits<char>::is_signed
.sumber
Sekarang, kita tahu standar membiarkan implementasi.
Tetapi bagaimana cara memeriksa suatu tipe
signed
atauunsigned
, sepertichar
?Saya menulis makro untuk melakukan ini:
#define IS_UNSIGNED(t) ((t)~1 > 0)
dan mengujinya dengan
gcc
,clang
, dancl
. Tapi saya tidak yakin itu selalu aman untuk kasus lain.sumber