Saya telah melihat definisi makro berikut dalam buku kode.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Tidak ada penjelasan di sana.
Tolong jelaskan kepada saya bagaimana ini akan berfungsi sebagai TRUE
dan FALSE
.
Saya telah melihat definisi makro berikut dalam buku kode.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Tidak ada penjelasan di sana.
Tolong jelaskan kepada saya bagaimana ini akan berfungsi sebagai TRUE
dan FALSE
.
Jawaban:
Mari kita lihat: '/' / '/'
berarti yang char
literal /
, dibagi dengan char
literal '/'
itu sendiri. Hasilnya adalah satu, yang kedengarannya masuk akal TRUE
.
Dan '-' - '-'
artinya char
secara literal '-'
, dikurangkan dari dirinya sendiri. Ini nol (FALSE
).
Ada dua masalah dengan ini: pertama, itu tidak dapat dibaca. Menggunakan 1
dan 0
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:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Ini akan mencetak nilai char
literal'-'
(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.
if
alih - alih mengalikan TRUE
dengan integer.
notx = TRUE- x;
dan berfungsi dengan baik. Kecuali itu TRUE-FALSE
-44 (dengan asumsi ASCII)
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 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:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
Inilah yang kami dapatkan:
True: 0
False: -44
Jadi (bool) TRUE
akan benar-benar mengevaluasi false
, dan (bool) FALSE
akan mengevaluasi true
.
Itu sama dengan menulis
#define TRUE 1
#define FALSE 0
Apa ekspresi '/'/'/'
sebenarnya adalah membagi karakter /
(apa pun nilai numeriknya) dengan sendirinya, sehingga menjadi 1
.
Demikian pula, ekspresi '-'-'-'
mengurangi karakter -
dari dirinya sendiri dan mengevaluasi ke0
.
Akan lebih baik menulis
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
untuk menghindari perubahan nilai yang tidak disengaja ketika digunakan dengan operator dengan prioritas lebih tinggi lainnya.
Jay sudah menjawab mengapa nilai dari ekspresi ini adalah 0
dan 1
.
Demi sejarah, ungkapan-ungkapan ini '/'/'/'
dan '-'-'-'
berasal dari salah satu entri dari Kontes Kode C Internasional I yang Dikurangi pada tahun 1984 :
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 TRUE
dan FALSE
juga tercakup dalam buku "Misterius C dan Misteri Lain" oleh Don Libes (1993).
Ini cara lucu untuk menulis makro untuk True
dan False
.
Karena banyak penjelasan yang telah diberikan /
berarti angka 1 byte (sesuai ASCII) ketika dibagi dengan sendirinya memberi Anda 1
yang akan diperlakukan sebagai True
dan juga -
lagi nomor byte ketika dikurangi nilai yang sama itu memberi Anda 0
yang 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, 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.
'/'/'/'
adalah 1 untuk setiap set karakter yang valid, apakah '/' == 47
(seperti dalam ASCII), atau '/' == 97
(seperti dalam EBCDIC), atau nilai lainnya.
'/'
ke 0
. Nilai itu dicadangkan untuk karakter nol.