Pemeran dalam pertanyaan Anda berlebihan, haruskah dibalik?
GManNickG
9
Dia tidak bermaksud mereka menjadi pemain, maksudnyabool t = true; int n = 1; if (t == n) {...} ;
egrunin
7
@egrunin: Eh, tapi benar itu bool dan 1 int juga. :)
GManNickG
1
Benar, saya bermaksud menyatakan jenis nilainya.
Petruza
2
(int) trueadalah 1sebagai nilai integer, tetapi sesuatu yang if (pointer)melewati bagian then if pointer != 0. Satu-satunya hal yang dapat Anda anggap benar adalah itu false == 0, dan true != 0(dan trueevaluasi 1ketika dilemparkan ke int)
Luis Colorado
Jawaban:
134
Iya. Pemerannya berlebihan. Dalam ekspresi Anda:
true==1
Promosi integral berlaku dan nilai bool akan dipromosikan menjadi intdan promosi ini harus menghasilkan 1.
Referensi: 4.7 [konv.integral] / 4: Jika tipe sumber adalah bool... truediubah menjadi satu.
@Joshua: trueadalah kata kunci yang ditentukan oleh bahasa. Itu tidak dapat didefinisikan ulang oleh perpustakaan. #defines tidak diperbolehkan untuk mendefinisikan ulang kata kunci.
jalf
21
@jalf: # define memang diizinkan untuk menentukan kata kunci sistem. Tahap pra-pemrosesan dari kompilasi C murni tekstual, dan tidak mengetahui kata kunci atau sintaks C secara umum. Namun demikian, mendefinisikan ulang kata kunci bahasa hampir selalu merupakan ide yang buruk.
Dale Hagglund
2
@jalan. Mereka tidak? Lihat gcc.gnu.org/onlinedocs/cpp/Macros.html , dan setidaknya salah satu entri dalam Kontes Kode C Internasional yang Disamarkan, yang pernah menanyakan "Kapan waktu tungguwhile ?" (Jawaban: ketika dibutuhkan dua parameter, karena entri #defineditu harus printf.)
Ken Bloom
3
C99, §6.10.1 / 1 mengatakan: "Ekspresi yang mengontrol penyertaan bersyarat harus berupa ekspresi konstanta integer kecuali bahwa: tidak boleh mengandung cast; pengenal (termasuk yang secara leksikal identik dengan kata kunci) diinterpretasikan seperti yang dijelaskan di bawah ini;" Meskipun tidak dinyatakan sebagai izin langsung, ini dengan jelas mempertimbangkan kemungkinan makro yang "identik secara leksikal" dengan kata kunci.
Jerry Coffin
2
Oh, dan #defines diizinkan untuk mendefinisikan ulang kata kunci. C ++ 1x menyebabkan terlalu banyak masalah dengan kata kunci barunya sehingga persyaratan tersebut harus dihapus.
Joshua
18
Jawaban Charles Bailey benar. Kata-kata yang tepat dari standar C ++ adalah (§4.7 / 4): "Jika jenis sumbernya bool, nilai false diubah menjadi nol dan nilai true diubah menjadi satu."
Sunting: Saya melihat dia menambahkan referensi juga - Saya akan segera menghapus ini, jika saya tidak terganggu dan lupa ...
Sunting2: Kemudian lagi, mungkin perlu dicatat bahwa sementara nilai Boolean itu sendiri selalu dikonversi ke nol atau satu, sejumlah fungsi (terutama dari pustaka standar C) mengembalikan nilai yang "pada dasarnya Boolean", tetapi direpresentasikan sebagai ints yang biasanya hanya perlu nol untuk menunjukkan salah atau bukan nol untuk menunjukkan benar. Misalnya, fungsi is * <ctype.h>hanya memerlukan nol atau bukan nol, tidak harus nol atau satu.
Jika Anda mentransmisikannya ke bool, nol akan dikonversi menjadi salah, dan bukan nol menjadi benar (seperti yang Anda harapkan).
Menurut standar, Anda harus aman dengan asumsi itu. Jenis C ++ boolmemiliki dua nilai - truedan falsedengan nilai yang sesuai 1 dan 0.
Hal yang harus diperhatikan adalah mencampurkan boolekspresi dan variabel dengan BOOLekspresi dan variabel. Yang terakhir didefinisikan sebagai FALSE = 0dan TRUE != FALSE, yang cukup sering dalam praktiknya berarti bahwa nilai apa pun yang berbeda dari 0 dipertimbangkan TRUE.
Banyak kompiler modern sebenarnya akan mengeluarkan peringatan untuk kode apa pun yang secara implisit mencoba mentransmisikan BOOLke booljika BOOLnilainya berbeda dari 0 atau 1.
Saya telah menemukan kompiler yang berbeda memberikan hasil yang berbeda pada true. Saya juga menemukan bahwa seseorang hampir selalu lebih baik membandingkan bool dengan bool daripada int. Int tersebut cenderung berubah nilai dari waktu ke waktu saat program Anda berkembang dan jika Anda mengasumsikan true sebagai 1, Anda dapat digigit oleh perubahan yang tidak terkait di tempat lain dalam kode Anda.
Ini adalah jawaban yang salah untuk C ++, seperti truekata kunci bahasa dengan perilaku yang ditentukan. Jika Anda merujuk ke makro yang ditentukan secara umum seperti TRUE, itu benar.
David Thornley
1
Mungkin pengalaman saya adalah dengan kompiler C - Saya telah menghabiskan banyak waktu dengan mereka selama bertahun-tahun. Maksud saya tentang secara langsung menggunakan ekspresi mathetical dalam pernyataan if berdiri. Kami memiliki kode yang melihat jika sedikit pergeseran bukan nol dalam jika, maka orang lain mengambil nilai bukan nol yang sama dan mengasumsikan itu adalah 1 dan meledakkan barang. Konversi sederhana menjadi true / 1 akan mencegah hal itu.
Michael Dorgan
Saya juga telah melihat perilaku seperti ini. Harus diakui, terakhir kali saya melihatnya sekitar tahun 1999. Saya menggunakan GCC. Bahasanya C. Tetap saja, saya memang pernah melihat perilaku seperti itu.
bool t = true; int n = 1; if (t == n) {...} ;
(int) true
adalah1
sebagai nilai integer, tetapi sesuatu yangif (pointer)
melewati bagian then ifpointer != 0
. Satu-satunya hal yang dapat Anda anggap benar adalah itufalse == 0
, dantrue != 0
(dantrue
evaluasi1
ketika dilemparkan keint
)Jawaban:
Iya. Pemerannya berlebihan. Dalam ekspresi Anda:
Promosi integral berlaku dan nilai bool akan dipromosikan menjadi
int
dan promosi ini harus menghasilkan 1.Referensi: 4.7 [konv.integral] / 4: Jika tipe sumber adalah
bool
...true
diubah menjadi satu.sumber
true
adalah kata kunci yang ditentukan oleh bahasa. Itu tidak dapat didefinisikan ulang oleh perpustakaan.#define
s tidak diperbolehkan untuk mendefinisikan ulang kata kunci.while
?" (Jawaban: ketika dibutuhkan dua parameter, karena entri#defined
itu harusprintf
.)Jawaban Charles Bailey benar. Kata-kata yang tepat dari standar C ++ adalah (§4.7 / 4): "Jika jenis sumbernya bool, nilai false diubah menjadi nol dan nilai true diubah menjadi satu."
Sunting: Saya melihat dia menambahkan referensi juga - Saya akan segera menghapus ini, jika saya tidak terganggu dan lupa ...
Sunting2: Kemudian lagi, mungkin perlu dicatat bahwa sementara nilai Boolean itu sendiri selalu dikonversi ke nol atau satu, sejumlah fungsi (terutama dari pustaka standar C) mengembalikan nilai yang "pada dasarnya Boolean", tetapi direpresentasikan sebagai
int
s yang biasanya hanya perlu nol untuk menunjukkan salah atau bukan nol untuk menunjukkan benar. Misalnya, fungsi is *<ctype.h>
hanya memerlukan nol atau bukan nol, tidak harus nol atau satu.Jika Anda mentransmisikannya ke
bool
, nol akan dikonversi menjadi salah, dan bukan nol menjadi benar (seperti yang Anda harapkan).sumber
Menurut standar, Anda harus aman dengan asumsi itu. Jenis C ++
bool
memiliki dua nilai -true
danfalse
dengan nilai yang sesuai 1 dan 0.Hal yang harus diperhatikan adalah mencampurkan
bool
ekspresi dan variabel denganBOOL
ekspresi dan variabel. Yang terakhir didefinisikan sebagaiFALSE = 0
danTRUE != FALSE
, yang cukup sering dalam praktiknya berarti bahwa nilai apa pun yang berbeda dari 0 dipertimbangkanTRUE
.Banyak kompiler modern sebenarnya akan mengeluarkan peringatan untuk kode apa pun yang secara implisit mencoba mentransmisikan
BOOL
kebool
jikaBOOL
nilainya berbeda dari 0 atau 1.sumber
Saya telah menemukan kompiler yang berbeda memberikan hasil yang berbeda pada true. Saya juga menemukan bahwa seseorang hampir selalu lebih baik membandingkan bool dengan bool daripada int. Int tersebut cenderung berubah nilai dari waktu ke waktu saat program Anda berkembang dan jika Anda mengasumsikan true sebagai 1, Anda dapat digigit oleh perubahan yang tidak terkait di tempat lain dalam kode Anda.
sumber
true
kata kunci bahasa dengan perilaku yang ditentukan. Jika Anda merujuk ke makro yang ditentukan secara umum sepertiTRUE
, itu benar.