Saya punya sedikit kode tentang sizeof
operator dengan operator ternary:
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool a = true;
printf("%zu\n", sizeof(bool)); // Ok
printf("%zu\n", sizeof(a)); // Ok
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
return 0;
}
Output ( GCC ):
1
1
4 // Why 4?
Tapi di sini,
printf("%zu\n", sizeof(a ? true : false)); // Why 4?
boolean
jenis pengembalian operator ternary dan bool
jenis sizeof adalah 1
byte dalam C.
Lalu mengapa sizeof(a ? true : false)
memberikan output empat byte?
sizeof(true)
dansizeof(false)
juga 4: ide.geeksforgeeks.org/O5jvuN_Bool
memiliki ukuran 1, tetapi tidaktrue
danfalse
. Tapi standarnya tidak ada yang bisa dikatakan tentang itu sejauh yang saya tahu.char a;
sizeof(a) == 1
dansizeof('a') == sizeof(int)
(dalam C). Ini bukan tentang implementasinya, ini tentang bahasa.sizeof(true)
? mungkin itu akan membuat tipis sedikit lebih jelas (khususnya, akan menjadi jelas bahwa operator ternary adalah herring merah).true
adalah#define
d menjadi 1 olehstdbool.h
jadi ya, ini adalah definisi literal.Jawaban:
Itu karena kamu punya
#include <stdbool.h>
. Header itu mendefinisikan makrotrue
danfalse
menjadi1
dan0
, jadi pernyataan Anda terlihat seperti ini:sizeof(int)
adalah 4 di platform Anda.sumber
sizeof(a ? (uint8_t)1 : (uint8_t)0);
akan juga memberikan hasil 4. Promosi bilangan bulat dari?:
operan adalah bagian penting di sini, bukan ukurantrue
danfalse
.int
tanpa promosi. Alasan Anda tidak dapat "memperbaiki" itu adalah promosi default.true
danfalse
yang tidak macro; mereka adalah kata kunci. Mereka tidak didefinisikan sebagai1
dan0
, tetapi menjadi nilai benar dan salah daribool
tipe.sizeof(true)
adalah 1. demo .OK, masih ada lagi!
Dalam C, hasil operasi ternary ini adalah tipe
int
. [catatan di bawah (1,2)]Karenanya hasilnya sama dengan ekspresi
sizeof(int)
, di platform Anda.Catatan 1: Mengutip
C11
, bab §7.18,Boolean type and values <stdbool.h>
Catatan 2: Untuk operator bersyarat, bab §6.5.15, ( penekanan pada tambang )
dan
karenanya, hasilnya akan bertipe integer dan karena rentang nilai, konstanta-konstanta tersebut adalah tipe
int
.Yang mengatakan, saran umum,
int main()
harus lebih baikint main (void)
untuk benar-benar sesuai standar.sumber
<stdbool.h>
mendefinisikan MACROS sebagai tipeint
.. apakah itu salah?Operator ternary adalah herring merah.
mencetak 4 (atau apa pun yang
sizeof(int)
ada di platform Anda).Diasumsikan
bool
sebagai sinonim untukchar
atau tipe serupa dari ukuran 1, danint
lebih besar darichar
.Alasan mengapa
sizeof(true) != sizeof(bool)
dansizeof(true) == sizeof(int)
hanya karenatrue
adalah tidak ekspresi tipebool
. Itu ekspresi tipeint
. Itu#define
d seperti1
dalamstdbool.h
.Tidak ada nilai tipeSunting: paragraf ini tidak benar, argumen untukbool
C sama sekali. Setiap nilai tersebut segera dipromosikanint
, bahkan ketika digunakan sebagai argumensizeof
.sizeof
tidak dipromosikanint
. Ini tidak memengaruhi kesimpulan apa pun.sumber
(bool)1
nilai jenisbool
?printf("%u\n", sizeof((char) 1));
mencetak1
pada platform saya sedangkanprintf("%u\n", sizeof(1));
cetak4
. Bukankah ini berarti pernyataan Anda "Setiap nilai seperti itu segera dipromosikan ke int, bahkan ketika digunakan sebagai argumen untuk sizeof" adalah salah?true
dll tidak terlalu penting dalam hal?:
karena mendapat bilangan bulat dipromosikan keint
bagaimanapun. Yaitu, jawabannya harus menjawab mengapa?:
ikan haring merah.Mengenai jenis boolean di C
Tipe boolean diperkenalkan cukup terlambat dalam bahasa C, pada tahun 1999. Sebelum itu, C tidak memiliki tipe boolean tetapi sebaliknya digunakan
int
untuk semua ekspresi boolean. Oleh karena itu semua operator logis seperti> == !
dll mengembalikanint
nilai1
atau0
.Itu adalah kebiasaan untuk aplikasi untuk menggunakan jenis buatan seperti
typedef enum { FALSE, TRUE } BOOL;
, yang juga bermuara padaint
jenis -sized.C ++ memiliki tipe boolean yang jauh lebih baik, dan eksplisit
bool
, yang tidak lebih besar dari 1 byte. Sedangkan tipe atau ekspresi boolean dalam C akan berakhir sebagai 4 byte dalam kasus terburuk. Beberapa cara kompatibilitas dengan C ++ diperkenalkan di C dengan standar C99. C kemudian mendapat tipe boolean_Bool
dan juga headerstdbool.h
.stdbool.h
menyediakan beberapa kompatibilitas dengan C ++. Header ini mendefinisikan makrobool
(ejaan yang sama dengan kata kunci C ++) yang diperluas ke_Bool
, tipe yang merupakan tipe integer kecil, kemungkinan besar 1 byte. Demikian pula, tajuk menyediakan dua makrotrue
danfalse
, ejaan yang sama dengan kata kunci C ++, tetapi dengan kompatibilitas ke belakang untuk program C yang lebih tua . Oleh karena itutrue
danfalse
berkembang ke1
dan0
di C dan tipenyaint
. Makro ini sebenarnya bukan tipe boolean seperti kata kunci C ++ yang sesuai.Demikian pula, untuk tujuan kompatibilitas ke belakang, operator logis di C masih kembali
int
ke hari ini, meskipun C saat ini mendapat tipe boolean. Sementara di C ++, operator logis mengembalikan abool
. Dengan demikian ekspresi sepertisizeof(a == b)
akan memberikan ukuranint
dalam C, tetapi ukuran daribool
dalam C ++.Mengenai operator bersyarat
?:
Operator bersyarat
?:
adalah operator aneh dengan beberapa keanehan. Ini adalah kesalahan umum untuk percaya bahwa itu 100% setara denganif() { } else {}
. Tidak terlalu.Ada titik urutan antara evaluasi operan 1 dan 2 atau 3. The
?:
Operator dijamin hanya mengevaluasi baik 2 atau operan-3, sehingga tidak dapat menjalankan efek samping dari operan yang tidak dievaluasi. Kode sukatrue? func1() : func2()
tidak akan dieksekusifunc2()
. Sejauh ini baik.Namun , ada aturan khusus yang menyatakan bahwa operan ke-2 dan ke-3 harus secara implisit dipromosikan dan diseimbangkan satu sama lain dengan konversi aritmatika yang biasa . ( Aturan promosi tipe implisit dalam C dijelaskan di sini ). Ini berarti bahwa operan ke-2 atau ke-3 akan selalu setidaknya sebesar
int
.Jadi tidak masalah itu
true
danfalse
kebetulan mengetikkanint
C karena ungkapan itu akan selalu memberikan setidaknya ukuran suatuint
masalah.Bahkan jika Anda akan menulis ulang ekspresi itu masih akan mengembalikan ukuran sebuah !
sizeof(a ? (bool)true : (bool)false)
int
Ini karena jenis promosi implisit melalui konversi aritmatika yang biasa.
sumber
sizeof(bool)==1
.Jawaban cepat:
sizeof(a ? true : false)
mengevaluasi ke4
karenatrue
danfalse
didefinisikan<stdbool.h>
sebagai1
dan0
masing - masing, sehingga ekspresi memperluassizeof(a ? 1 : 0)
yang merupakan ekspresi integer dengan tipeint
, yang menempati 4 byte pada platform Anda. Untuk alasan yang sama,sizeof(true)
juga akan mengevaluasi4
pada sistem Anda.Perhatikan bahwa:
sizeof(a ? a : a)
juga dievaluasi4
karena operator ternary melakukan promosi integer pada operan kedua dan ketiga jika ini adalah ekspresi integer. Hal yang sama tentu saja terjadi untuksizeof(a ? true : false)
dansizeof(a ? (bool)true : (bool)false)
, tetapi menampilkan seluruh ekspresi sebagaibool
berperilaku seperti yang diharapkan:sizeof((bool)(a ? true : false)) -> 1
.juga perhatikan bahwa operator perbandingan mengevaluasi nilai boolean
1
atau0
, tetapi memilikiint
tipe:sizeof(a == a) -> 4
.Satu-satunya operator yang menjaga sifat boolean
a
adalah:operator koma: keduanya
sizeof(a, a)
dansizeof(true, a)
mengevaluasi pada1
saat kompilasi.operator penugasan: keduanya
sizeof(a = a)
dansizeof(a = true)
memiliki nilai1
.operator kenaikan:
sizeof(a++) -> 1
Akhirnya, semua hal di atas hanya berlaku untuk C: C ++ memiliki semantik yang berbeda mengenai
bool
tipe, nilai booleantrue
danfalse
, operator perbandingan dan operator ternary: semuasizeof()
ekspresi ini dievaluasi1
dalam C ++.sumber
true
dan keberadaannyafalse
, karena?:
operan akan dipromosikan menjadi bilangan bulatint
. Dengan demikiansizeof(a ? (uint8_t)true : (uint8_t)false)
juga akan menghasilkan 4 sebagai hasilnya.int
Berikut ini cuplikan dari mana yang termasuk dalam sumber
Ada makro
true
danfalse
dinyatakan sebagai 1 dan 0 masing-masing.Namun dalam hal ini jenisnya adalah jenis konstanta literal. Baik 0 dan 1 adalah konstanta integer yang sesuai dengan int, sehingga tipenya adalah int.
dan
sizeof(int)
dalam kasus Anda adalah 4.sumber
Tidak ada tipe data boolean di C, sebaliknya ekspresi logis mengevaluasi nilai integer
1
ketika benar sebaliknya0
.Ekspresi kondisional seperti
if
,for
,while
, atauc ? a : b
mengharapkan integer, jika nomor tersebut adalah non-nol itu dianggaptrue
kecuali untuk beberapa kasus khusus, berikut adalah rekursif sum fungsi di mana terner operator akan mengevaluasitrue
sampain
jangkauan0
.Itu juga dapat digunakan untuk
NULL
memeriksa sebuah pointer, inilah fungsi rekursif yang mencetak konten dari Singly-Linked-List.sumber