Apakah aman untuk memeriksa pointer ke tidak NULL
dengan hanya menulis if(pointer)
atau harus saya gunakan if(pointer != NULL)
?
c++
pointers
if-statement
null
null-pointer
danijar
sumber
sumber
0
ataunullptr
. (NULL
adalah C'ism, dan membutuhkan termasuk file header.)NULL
dalam C ++ mulai dari ini karenaNULL
ini adalah implementasi yang bergantung makro yang mungkin memberi Anda perilaku ambigu.Jawaban:
Kamu bisa; pointer nol secara implisit dikonversi menjadi boolean false sementara pointer non-null dikonversi menjadi true. Dari standar C ++ 11, bagian tentang Konversi Boolean:
sumber
Ya kamu bisa.
Ini adalah bagian dari konversi standar C ++, yang termasuk dalam klausa konversi Boolean :
§ 4.12 Konversi Boolean
sumber
Ya kamu bisa. Bahkan, saya lebih suka menggunakan
if(pointer)
karena lebih mudah untuk membaca dan menulis begitu Anda terbiasa.Perhatikan juga bahwa C ++ 11 yang diperkenalkan
nullptr
lebih disukaiNULL
.sumber
if(som_integer)
vsif(some_integer != 0)
karena bilangan bulat juga bukan boolean, bukan? Saya lebih suka menghindari0
atauNULL
dalam pernyataan if.if (pointer)
diri saya sendiri, tetapiif (ptr != nullptr)
tampaknya sangat sah bagi saya. Di sisi lain, jika saya melihat seseorang di tim saya yang menulisif (some_integer)
saya akan membuat mereka mengubahnyaif (some_integer != 0)
. Namun, saya tidak akan berpura-pura itu bukan preferensi yang relatif sewenang-wenang di pihak saya - saya hanya memilih untuk tidak memperlakukan pointer dan bilangan bulat yang sama.if(isReady)
if(filePtr)
if(serviceNo)
? Membuat nama variabel yang buruk dengan sengaja tidak banyak berarti dalam kasus ini. Pokoknya saya sudah mengerti maksud Anda dan memahaminya, tapi saya bisa bersikeras menggunakan gaya pengkodean saya sendiri, oke?Pertanyaan dijawab, tetapi saya ingin menambahkan poin saya.
Saya akan selalu lebih suka
if(pointer)
daripadaif(pointer != NULL)
danif(!pointer)
bukannyaif(pointer == NULL)
:Kurang kesempatan untuk menulis kode kereta, kira jika aku salah eja Operator cek kesetaraan
==
dengan=
if(pointer == NULL)
dapat salah ejaif(pointer = NULL)
Jadi saya akan menghindarinya, terbaik hanyaif(pointer)
.(Saya juga menyarankan beberapa kondisi Yoda dalam satu jawaban , tapi itu masalah lain)
Demikian pula untuk
while (node != NULL && node->data == key)
, saya hanya akan menuliswhile (node && node->data == key)
yang lebih jelas bagi saya (menunjukkan bahwa menggunakan korsleting).sumber
(boolean expression)? true : false
sama sekali tidak ada gunanya. Ekspresi mengevaluasi ketrue
atau kefalse
; apa yang Anda katakan adalah "jika itu benar, beri aku benar, jika itu salah, beri aku salah". Singkatnya: Ini sepenuhnya sama dengan ekspresi boolean itu sendiri. Perhatikan bahwanode == NULL
ini adalah ekspresi boolean. BTW, dua implementasi Anda menghasilkan kebalikan dari satu sama lain. Entah Anda ingin!=
yang pertama, atau hanya satu!
yang kedua.=
bukan==
membuat variabel Andaconst
kapan pun memungkinkan. Misalnya, Anda bisa mendefinisikan fungsi Anda sebagaiisEmnpy(node* const head) { ... }
, dan kemudian compiler akan menolak untuk mengkompilasi jika Anda secara tidak sengaja menulisnode = NULL
bukannode == NULL
. Tentu saja itu hanya berfungsi untuk variabel yang Anda benar-benar tidak perlu ubah.T* get() const
alih - alihoperator T*() const
menghindari konversi implisit. Namun mereka memilikioperator bool() const
.Memeriksa secara eksplisit untuk NULL dapat memberikan petunjuk kepada kompiler tentang apa yang Anda coba lakukan, ergo mengarah ke yang kurang rawan kesalahan.
sumber
Ya kamu bisa. Kemampuan untuk membandingkan nilai dengan nol secara implisit telah diwarisi dari C, dan ada di semua versi C ++. Anda juga dapat menggunakan
if (!pointer)
untuk memeriksa pointer untuk NULL.sumber
Kasus penggunaan yang relevan untuk null pointer adalah
Gips dinamis. Melemparkan pointer kelas dasar ke kelas turunan tertentu (sesuatu yang harus Anda coba hindari lagi, tetapi kadang-kadang mungkin perlu) selalu berhasil, tetapi menghasilkan pointer nol jika kelas turunan tidak cocok. Salah satu cara untuk memeriksanya adalah
(atau, lebih disukai,
auto derived_ptr = ...
). Sekarang, ini buruk, karena meninggalkan pointer yang diturunkan (kemungkinan tidak valid, yaitu null) di luarif
ruang lingkup blok pengaman . Ini tidak perlu, karena C ++ memungkinkan Anda untuk memperkenalkan variabel boolean-convertable di dalamif
-condition :yang tidak hanya lebih pendek dan lingkup-aman, itu juga jauh lebih jelas dalam tujuannya: ketika Anda memeriksa nol dalam kondisi-if terpisah, pembaca bertanya-tanya "ok, jadi
derived_ptr
tidak boleh nol di sini ... yah, mengapa itu nol? " Sedangkan versi satu baris kata yang sangat jelas "jika Anda dapat dengan aman dilemparkanbase_ptr
keDerived*
, kemudian menggunakannya untuk ...".Hal yang sama juga berfungsi untuk operasi kemungkinan-gagal lainnya yang mengembalikan pointer, meskipun IMO Anda biasanya harus menghindari ini: lebih baik menggunakan sesuatu seperti
boost::optional
sebagai "wadah" untuk hasil operasi yang mungkin gagal, daripada pointer.Jadi, jika use case utama untuk null pointer harus selalu ditulis dalam variasi gaya implisit-cast, saya akan mengatakan itu baik untuk alasan konsistensi untuk selalu menggunakan gaya ini, yaitu saya akan mengadvokasi untuk
if(ptr)
lebihif(ptr!=nullptr)
.Saya khawatir saya harus mengakhiri dengan iklan:
if(auto bla = ...)
sintaks sebenarnya hanya pendekatan yang sedikit rumit untuk solusi nyata untuk masalah seperti: pencocokan pola . Mengapa Anda pertama kali memaksakan beberapa tindakan (seperti melemparkan pointer) dan kemudian mempertimbangkan bahwa mungkin ada kegagalan ... Maksud saya, ini konyol, bukan? Ini seperti, Anda memiliki beberapa bahan makanan dan ingin membuat sup. Anda memberikannya kepada asisten Anda dengan tugas untuk mengekstrak jus, jika itu adalah sayuran lunak. Anda tidak pertama-tama melihatnya. Ketika Anda memiliki kentang, Anda masih memberikannya kepada asisten Anda tetapi mereka menamparnya kembali di wajah Anda dengan catatan kegagalan. Ah, pemrograman imperatif!Jauh lebih baik: segera pertimbangkan semua kasus yang mungkin Anda temui. Kemudian bertindak sesuai. Haskell:
Haskell juga memiliki alat khusus untuk ketika benar-benar ada kemungkinan kegagalan yang serius (dan juga untuk banyak hal lainnya): monads. Tapi ini bukan tempat untuk menjelaskannya.
⟨/iklan⟩
sumber
if(ptr)
daripadaif(ptr != nullptr)
, yang ada cukup banyak untuk dikatakan.ya tentu saja! pada kenyataannya, menulis jika (pointer) adalah cara penulisan yang lebih nyaman daripada jika (pointer! = NULL) karena: 1. mudah untuk debug 2. mudah dimengerti 3. jika tidak sengaja, nilai NULL didefinisikan, maka kode juga tidak akan crash
sumber
Iya. Padahal seharusnya begitu. Jika Anda bertanya-tanya apakah itu menciptakan kesalahan segmentasi , itu tidak.
sumber
Karena orang lain sudah menjawab dengan baik, mereka berdua dapat dipertukarkan.
Meskipun demikian, perlu disebutkan bahwa mungkin ada kasus di mana Anda mungkin ingin menggunakan pernyataan eksplisit, yaitu
pointer != NULL
.Lihat juga https://stackoverflow.com/a/60891279/2463963
sumber
Ya, Anda selalu dapat melakukan ini karena kondisi 'JIKA' hanya mengevaluasi ketika kondisi di dalamnya benar. C tidak memiliki tipe pengembalian boolean dan dengan demikian mengembalikan nilai bukan nol ketika kondisi benar sementara mengembalikan 0 setiap kali kondisi di 'JIKA' ternyata salah. Nilai bukan nol yang dikembalikan secara default adalah 1. Dengan demikian, kedua cara penulisan kode sudah benar sementara saya akan selalu lebih suka yang kedua.
sumber
Saya pikir sebagai aturan praktis, jika ekspresi if Anda dapat ditulis ulang sebagai
sedemikian rupa sehingga TIDAK menyebabkan PERINGATAN, maka ITULAH harus menjadi gaya yang disukai untuk ekspresi if . (Saya tahu saya mendapat peringatan ketika saya menetapkan C lama
BOOL
(#define BOOL int
) ke C ++bool
, apalagi pointer.)sumber
"Apakah itu aman ..?" adalah pertanyaan tentang standar bahasa dan kode yang dihasilkan.
"Apakah ini latihan yang bagus?" adalah pertanyaan tentang seberapa baik pernyataan itu dipahami oleh setiap pembaca manusia yang sewenang-wenang dari pernyataan itu. Jika Anda mengajukan pertanyaan ini, itu menunjukkan bahwa versi "aman" kurang jelas bagi pembaca dan penulis di masa depan.
sumber