Saya pikir ini hanya cara lucu untuk mendefinisikan BENAR sebagai 1 dan SALAH sebagai 0
BlackDwarf
160
Perhatikan bahwa ini adalah ide yang buruk tanpa tanda kurung di sekitar ekspresi itu. Maksud saya itu adalah ide yang buruk bagi mereka, tetapi tanpa Anda hanya meminta malam panjang debugging.
TartanLlama
70
Bolehkah saya tahu buku kode yang Anda referensikan?
artm
47
Saya harap buku itu memasukkan ini sebagai contoh kode yang buruk atau sengaja dikaburkan.
Jon Hanna
31
@Aniel: Gagasan lain adalah rand ()% 2 mendefinisikan MAYBE sebagai rand ()% 2, sehingga kadang-kadang == BENAR dan kadang-kadang == SALAH.
Kaiserludi
Jawaban:
380
Mari kita lihat: '/' / '/'berarti yang charliteral /, dibagi dengan charliteral '/'itu sendiri. Hasilnya adalah satu, yang kedengarannya masuk akal TRUE.
Dan '-' - '-'artinya charsecara literal '-', dikurangkan dari dirinya sendiri. Ini nol (FALSE ).
Ada dua masalah dengan ini: pertama, itu tidak dapat dibaca. Menggunakan 1dan 0benar-benar lebih baik. Juga, seperti yang ditunjukkan oleh TartanLlama dan KerrekSB, jika Anda akan menggunakan definisi itu, silakan tambahkan tanda kurung di sekitar mereka sehingga Anda tidak akan memiliki kejutan:
Ini akan mencetak nilai charliteral'-' (45 pada sistem saya).
Dengan tanda kurung:
#define TRUE ('/'/'/')#define FALSE ('-'-'-')
program dengan benar mencetak nol, meskipun tidak masuk akal untuk melipatgandakan nilai kebenaran dengan bilangan bulat, tetapi itu hanyalah contoh dari jenis bug yang tidak terduga yang dapat menggigit Anda jika Anda tidak mengurung makro Anda.
Sialan aku butuh banyak untuk memahaminya: bahkan berpikir itu adalah hal yang aneh seperti mesin terbang ... tidak tahu xD
Luis Masuelli
8
Sebenarnya masuk akal untuk berkembang biak dengan nilai kebenaran. Untuk memeriksa indentasi * should_indent akan menghasilkan 0 atau indentasi berdasarkan apakah should_indent tanpa bercabang. (Saya kira ini adalah contoh yang buruk, ketika bekerja dengan text single branching tidak masalah, (saya telah melihat teknik ini di shader dan di XPATH (keduanya terlalu berbeda dan saya tidak ingat bentuk persisnya))
Alpedar
2
Alpedar - tetapi secara konseptual dan matehmatis tidak masuk akal untuk melakukannya - dalam hal ini akan lebih jelas (dan secara konseptual masuk akal) untuk menggunakan ifalih - alih mengalikan TRUEdengan integer.
Jay
4
Penjelasan yang bagus. Punya lencana emas!
Michael Hampton
2
Negasi logis dapat diimplementasikan notx = TRUE- x;dan berfungsi dengan baik. Kecuali itu TRUE-FALSE-44 (dengan asumsi ASCII)
Hagen von Eitzen
89
Ini hanyalah cara penulisan lainnya
#define TRUE 1#define FALSE 0
Ekspresi '/'/'/'akan membagi nilai char '/'dengan sendirinya, yang akan memberikan 1 sebagai hasilnya.
Ekspresi '-'-'-'akan mengurangi nilai char '-'dari itu sendiri, yang akan menghasilkan 0 sebagai hasilnya.
Tanda kurung di sekitar seluruh defineekspresi tidak ada, yang dapat menyebabkan kesalahan dalam kode menggunakan makro ini. Jawaban Jay mendukungnya.
Contoh skenario "kehidupan nyata" di mana melupakan tanda kurung dapat berbahaya adalah penggunaan gabungan makro ini dengan operator pemain gaya-C. Jika seseorang memutuskan untuk memberikan ekspresi ini ke booldalam C ++ misalnya:
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
(Tautan ke program di sini , ada petunjuk tentang apa yang dilakukan program ini di halaman IOCCC di atas.)
Juga jika saya ingat dengan benar ungkapan-ungkapan ini sebagai makro yang dikaburkan untuk TRUEdan FALSEjuga tercakup dalam buku "Misterius C dan Misteri Lain" oleh Don Libes (1993).
Ini cara lucu untuk menulis makro untuk Truedan False.
Karena banyak penjelasan yang telah diberikan /berarti angka 1 byte (sesuai ASCII) ketika dibagi dengan sendirinya memberi Anda 1yang akan diperlakukan sebagai Truedan juga -lagi nomor byte ketika dikurangi nilai yang sama itu memberi Anda 0yang akan ditafsirkan sebagaifalse
#define TRUE '/'/'/'#define FALSE '-'-'-'
maka kita dapat mengganti /atau -dengan char apa pun yang kita suka, misalnya:
#define TRUE '!'/'!'#define FALSE 'o'-'o'
Akan tetap memiliki makna yang sama dengan ungkapan asli.
Mari kita mulai dengan yang benar. Anda dapat membacanya sebagai '/' / '/', yang berarti "karakter '/' dibagi dengan karakter '/'". Karena setiap karakter, dalam C, adalah nilai numerik (pada satu byte), itu dapat dibaca sebagai "nilai ASCII dari karakter '/' dibagi dengan nilai ASCII dari karakter yang sama", yang berarti 1 (karena, jelas, x / x adalah 1). Karenanya, TRUEadalah 1.
Sebab FALSE, alasannya sama: '-'-'-'berbunyi '-' - '-', yaitu "nilai ASCII dari '-' dikurangi nilai ASCII dari '-'", yang adalah 0. Oleh karena itu, FALSEadalah 0.
Ini adalah cara jahat untuk menyatakan yang sudah jelas.
@Fabien: Tidak tergantung pada ASCII. '/'/'/'adalah 1 untuk setiap set karakter yang valid, apakah '/' == 47(seperti dalam ASCII), atau '/' == 97(seperti dalam EBCDIC), atau nilai lainnya.
Keith Thompson
4
@ Pamel: Implementasi C yang sesuai tidak dapat dipetakan '/'ke 0. Nilai itu dicadangkan untuk karakter nol.
Keith Thompson
2
Anda menjadi pedantic.
Matheus208
3
@ Matheus208 Jika Pawel menjadi orang yang bertele-tele, maka itu ('-'-'-') karena maksudnya didasarkan pada kondisi yang tidak disebutkan; menggambarkan pernyataan Keith sebagai bertele-tele mungkin lebih ('/' / '/') tapi saya akan menyebutnya "klarifikasi" (dan dengan menambahkan smiley "bertele-tele" jelas tampak '/' - '/' bagi saya). Mungkin ('-' / '-') bahwa komentar yang diambil bersama-sama dapat disebut pedantic tetapi, 1) bukankah itu agak wajib dalam bidang ini? 2) mereka membuat saya berpikir; dan 3) Saya sedikit lebih jelas dalam beberapa hal daripada saya. Dan ya, saya kira saya sendiri terlalu jago! (Tapi saya lebih jelas tentang apa yang "pedantic" berarti daripada saya! ;-)
Jawaban:
Mari kita lihat:
'/' / '/'
berarti yangchar
literal/
, dibagi denganchar
literal'/'
itu sendiri. Hasilnya adalah satu, yang kedengarannya masuk akalTRUE
.Dan
'-' - '-'
artinyachar
secara literal'-'
, dikurangkan dari dirinya sendiri. Ini nol (FALSE
).Ada dua masalah dengan ini: pertama, itu tidak dapat dibaca. Menggunakan
1
dan0
benar-benar lebih baik. Juga, seperti yang ditunjukkan oleh TartanLlama dan KerrekSB, jika Anda akan menggunakan definisi itu, silakan tambahkan tanda kurung di sekitar mereka sehingga Anda tidak akan memiliki kejutan:Ini akan mencetak nilai
char
literal'-'
(45 pada sistem saya).Dengan tanda kurung:
program dengan benar mencetak nol, meskipun tidak masuk akal untuk melipatgandakan nilai kebenaran dengan bilangan bulat, tetapi itu hanyalah contoh dari jenis bug yang tidak terduga yang dapat menggigit Anda jika Anda tidak mengurung makro Anda.
sumber
if
alih - alih mengalikanTRUE
dengan integer.notx = TRUE- x;
dan berfungsi dengan baik. Kecuali ituTRUE-FALSE
-44 (dengan asumsi ASCII)Ini hanyalah cara penulisan lainnya
Ekspresi
'/'/'/'
akan membagi nilai char'/'
dengan sendirinya, yang akan memberikan 1 sebagai hasilnya.Ekspresi
'-'-'-'
akan mengurangi nilai char'-'
dari itu sendiri, yang akan menghasilkan 0 sebagai hasilnya.Tanda kurung di sekitar seluruh
define
ekspresi tidak ada, yang dapat menyebabkan kesalahan dalam kode menggunakan makro ini. Jawaban Jay mendukungnya.Contoh skenario "kehidupan nyata" di mana melupakan tanda kurung dapat berbahaya adalah penggunaan gabungan makro ini dengan operator pemain gaya-C. Jika seseorang memutuskan untuk memberikan ekspresi ini ke
bool
dalam C ++ misalnya:Inilah yang kami dapatkan:
Jadi
(bool) TRUE
akan benar-benar mengevaluasifalse
, dan(bool) FALSE
akan mengevaluasitrue
.sumber
Itu sama dengan menulis
Apa ekspresi
'/'/'/'
sebenarnya adalah membagi karakter/
(apa pun nilai numeriknya) dengan sendirinya, sehingga menjadi1
.Demikian pula, ekspresi
'-'-'-'
mengurangi karakter-
dari dirinya sendiri dan mengevaluasi ke0
.Akan lebih baik menulis
untuk menghindari perubahan nilai yang tidak disengaja ketika digunakan dengan operator dengan prioritas lebih tinggi lainnya.
sumber
Jay sudah menjawab mengapa nilai dari ekspresi ini adalah
0
dan1
.Demi sejarah, ungkapan-ungkapan ini
'/'/'/'
dan'-'-'-'
berasal dari salah satu entri dari Kontes Kode C Internasional I yang Dikurangi pada tahun 1984 :(Tautan ke program di sini , ada petunjuk tentang apa yang dilakukan program ini di halaman IOCCC di atas.)
Juga jika saya ingat dengan benar ungkapan-ungkapan ini sebagai makro yang dikaburkan untuk
TRUE
danFALSE
juga tercakup dalam buku "Misterius C dan Misteri Lain" oleh Don Libes (1993).sumber
Ini cara lucu untuk menulis makro untuk
True
danFalse
.Karena banyak penjelasan yang telah diberikan
/
berarti angka 1 byte (sesuai ASCII) ketika dibagi dengan sendirinya memberi Anda1
yang akan diperlakukan sebagaiTrue
dan juga-
lagi nomor byte ketika dikurangi nilai yang sama itu memberi Anda0
yang akan ditafsirkan sebagaifalse
maka kita dapat mengganti
/
atau-
dengan char apa pun yang kita suka, misalnya:Akan tetap memiliki makna yang sama dengan ungkapan asli.
sumber
Mari kita mulai dengan yang benar. Anda dapat membacanya sebagai
'/' / '/'
, yang berarti "karakter '/' dibagi dengan karakter '/'". Karena setiap karakter, dalam C, adalah nilai numerik (pada satu byte), itu dapat dibaca sebagai "nilai ASCII dari karakter '/' dibagi dengan nilai ASCII dari karakter yang sama", yang berarti 1 (karena, jelas, x / x adalah 1). Karenanya,TRUE
adalah 1.Sebab
FALSE
, alasannya sama:'-'-'-'
berbunyi'-' - '-'
, yaitu "nilai ASCII dari '-' dikurangi nilai ASCII dari '-'", yang adalah 0. Oleh karena itu,FALSE
adalah 0.Ini adalah cara jahat untuk menyatakan yang sudah jelas.
sumber
'/'/'/'
adalah 1 untuk setiap set karakter yang valid, apakah'/' == 47
(seperti dalam ASCII), atau'/' == 97
(seperti dalam EBCDIC), atau nilai lainnya.'/'
ke0
. Nilai itu dicadangkan untuk karakter nol.