Bir kodlama kitabında aşağıdaki makro tanımlarını gördüm.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Orada bir açıklama yoktu.
Lütfen bunların nasıl TRUE
ve nasıl çalışacağını açıklayın FALSE
.
Bir kodlama kitabında aşağıdaki makro tanımlarını gördüm.
#define TRUE '/'/'/'
#define FALSE '-'-'-'
Orada bir açıklama yoktu.
Lütfen bunların nasıl TRUE
ve nasıl çalışacağını açıklayın FALSE
.
Yanıtlar:
Bakalım: '/' / '/'
araçlar char
literal /
bölünmesiyle, char
edebi '/'
kendisi. Sonuç makul olanıdır TRUE
.
Ve kendisinden çıkarılan gerçek '-' - '-'
anlamına gelir . Bu sıfır ( ).char
'-'
FALSE
Bununla ilgili iki sorun var: birincisi, okunamıyor. Kullanmak 1
ve 0
kesinlikle daha iyidir. Ayrıca, TartanLlama ve KerrekSB'nin de belirttiği gibi, eğer bu tanımı kullanacaksanız, lütfen etraflarına parantez ekleyin, böylece herhangi bir sürpriziniz olmaz:
#include <stdio.h>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
printf ("%d\n", 2 * FALSE);
return 0;
}
Bu, char
değişmez değerin değerini yazdıracaktır '-'
(sistemimde 45).
Parantez ile:
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
bir doğruluk değerini bir tamsayı ile çarpmak pek mantıklı olmasa da, program doğru olarak sıfır yazdırır, ancak bu, makrolarınızı parantez içinde almazsanız sizi ısıtabilecek beklenmedik hataların bir örneğidir.
if
ile çarpmak yerine kullanmak daha açık (ve kavramsal olarak mantıklı) olacaktır TRUE
.
notx = TRUE- x;
ve iyi çalışır. Bunun dışında TRUE-FALSE
-44 (ASCII varsayarak)
Bu sadece yazmanın başka bir yolu
#define TRUE 1
#define FALSE 0
İfade '/'/'/'
, '/'
sonuç olarak 1 verecek olan karakter değerini kendi başına böler .
İfade '-'-'-'
, '-'
kendisinin karakter değerini özetleyecek ve sonuç olarak 0 verecektir.
Tüm define
ifadelerin etrafındaki köşeli parantezler eksiktir, bu da bu makroları kullanarak kodda hatalara neden olabilir. Jay'in cevabı bunu çok iyi karşılar.
Köşeli parantezlerin unutulmasının zararlı olabileceği "gerçek hayat" senaryosunun bir örneği, bu makroların bir C stili döküm operatörü ile birlikte kullanılmasıdır. Birisi bu ifadeleri bool
C ++ dilinde yayınlamaya karar verirse, örneğin:
#include <iostream>
#define TRUE '/'/'/'
#define FALSE '-'-'-'
int main() {
std::cout << "True: " << (bool) TRUE << std::endl;
std::cout << "False: " << (bool) FALSE << std::endl;
return 0;
}
İşte elde ettiklerimiz:
True: 0
False: -44
Yani (bool) TRUE
aslında hiç değerlendirirsiniz false
ve (bool) FALSE
hiç değerlendirirsiniz true
.
Yazmaya eşdeğerdir
#define TRUE 1
#define FALSE 0
İfadenin '/'/'/'
gerçekte yaptığı, karakteri /
(sayısal değeri ne olursa olsun) tek başına bölmektir, böylece olur 1
.
Benzer şekilde, ifade '-'-'-'
karakteri -
kendisinden çıkarır ve olarak değerlendirir 0
.
Yazmak daha iyi olur
#define TRUE ('/'/'/')
#define FALSE ('-'-'-')
diğer yüksek öncelikli operatörlerle kullanıldığında değerlerin yanlışlıkla değiştirilmesini önlemek için.
Jay zaten bu ifadelerin değerleridir neden cevap 0
ve 1
.
Tarih uğruna, bu ifadeler '/'/'/'
ve 1984'te 1. Uluslararası Gizli C Kodu Yarışması'nın'-'-'-'
girişlerinden birinden gelir :
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);}
( Buradaki programa bağlantı , yukarıdaki IOCCC sayfasında bu programın ne yaptığına dair bir ipucu var.)
Ayrıca, bu ifadeleri gizlenmiş makrolar olarak doğru hatırlıyorsam TRUE
ve FALSE
aynı zamanda Don Libes (1993) tarafından yazılan "Gizli C ve Diğer Gizemler" kitabında da yer aldı.
İçin makro yazmak için bu komik yolu True
ve False
.
Birçok açıklama temin edilmiştir olarak /
(ASCII göre) vasıtaları, bir 1 bayt sayısının tek başına bölünmüş zaman vermek 1
olarak tedavi olacak True
benzer şekilde ve -
bu vermek aynı değere çıkarılır zaman bir bayt sayısı tekrar edilir 0
olarak yorumlanacaktırfalse
#define TRUE '/'/'/'
#define FALSE '-'-'-'
dolayısıyla /
veya -
istediğimiz herhangi bir karakterle değiştirebiliriz , örneğin:
#define TRUE '!'/'!'
#define FALSE 'o'-'o'
Orijinal ifadeyle aynı anlamı koruyacaktır.
Doğru ile başlayalım. Sen olarak okuyabilir '/' / '/'
, hangi vasıta "karakteri '/' karakteri '/' bölü". C'deki her karakter sayısal bir değer (bir bayt üzerinde) olduğundan, "/ 'karakterinin ASCII değerinin aynı karakterin ASCII değerine bölünmesi" olarak okunabilir, yani 1 (açıkçası, x / x 1) 'dir. Dolayısıyla, TRUE
1'dir.
İçin FALSE
, aynı mantık: '-'-'-'
okur '-' - '-'
, yani "- 'ASCII değeri eksi 0 -' - 'ASCII değeri", dolayısıyla 0'dır FALSE
.
Bu bariz olanı belirtmenin kötü bir yoludur.
'/'/'/'
için geçerli herhangi bir karakter kümesi için 1'dir . '/' == 47
'/' == 97
'/'
için 0
. Bu değer null karakter için ayrılmıştır.