Mengapa NULL tidak diumumkan?

87

Saya punya masalah dengan kontraktor struct ini ketika saya mencoba untuk mengkompilasi kode ini:

typedef struct Node
{
    Node( int data ) //
    {
        this->data = data;
        previous = NULL; // Compiler indicates here
        next = NULL;
    }

    int data;
    Node* previous;
    Node* next;
} NODE;

ketika saya datang kesalahan ini terjadi:

\linkedlist\linkedlist.h||In constructor `Node::Node(int)':|
\linkedlist\linkedlist.h|9|error: `NULL' was not declared in this scope|
    ||=== Build finished: 1 errors, 0 warnings ===|

Masalah terakhir adalah struct, tetapi berfungsi dengan baik ketika berada di main.cpp saya, kali ini ada di file header dan memberi saya masalah ini. Saya menggunakan Code :: Blocks untuk mengkompilasi kode ini

beristirahat
sumber

Jawaban:

139

NULLbukanlah konstanta bawaan dalam bahasa C atau C ++. Faktanya, di C ++ ini lebih atau kurang usang, cukup gunakan literal biasa 0saja, kompilator akan melakukan hal yang benar tergantung pada konteksnya.

Di C ++ yang lebih baru (C ++ 11 dan yang lebih tinggi), gunakan nullptr(seperti yang ditunjukkan dalam komentar, terima kasih).

Jika tidak, tambahkan

#include <stddef.h>

untuk mendapatkan NULLdefinisinya.

beristirahat
sumber
7
NULL adalah bagian dari stddef.h, bukan stdlib.h. Secara teknis, Anda tidak dijamin mendapatkannya sebagai bagian dari stdlib.h meskipun saya akui akan sangat mengejutkan jika Anda tidak mendapatkannya.
CB Bailey
8
NULL didefinisikan dalam header C berikut: stddef.h, stdlib.h, stdio.h, locale.h, string.h, dan time.h (dan wchar.h jika Anda menghitung C99).
Michael Burr
8
<cstddef>adalah opsi yang lebih bersih.
Fred Foo
30
JANGAN gunakan "0" jika yang Anda maksud adalah "NULL"! Ada perbedaan : semantik. Jangan pernah meremehkan pentingnya mengetahui apa itu sesuatu dan menggunakan kata yang tepat, bahkan jika kompiler akan membiarkan Anda lolos begitu saja!
imallett
13
@ 6502 Tidak membicarakan tentang itu; 0 dan NULL memang memiliki nilai yang sama (hampir) selalu, jadi penggunaan '\ 0' atau 0 akan bekerja secara tidak sengaja. Masalahnya adalah semantik. Menggunakan NULL lebih ekspresif, karena dikatakan bahwa nilai is question adalah sebuah pointer, bukan hanya sebuah integer.
imallett
35

Gunakan NULL. Itu hanya # didefinisikan sebagai 0 dan sangat berguna untuk membedakannya secara semantik dari bilangan bulat 0.

Ada masalah dengan menggunakan 0 (dan karenanya NULL). Sebagai contoh:

void f(int);
void f(void*);

f(0); // Ambiguous. Calls f(int).

Versi C ++ (C ++ 0x) berikutnya termasuk nullptruntuk memperbaikinya.

f(nullptr); // Calls f(void*).
Eric
sumber
5
Ini didefinisikan sebagai ((void *)0)oleh kebanyakan implementasi pustaka standar C.
Triang3l
1
Ini adalah jawaban singkat terbaik (dan secara teknis tepat) yang pernah saya baca mengenai topik ini: NULL vs. 0 vs. nullptr. Terima kasih!
jose.angel.jimenez
2
@SiPlus ((void *)0)salah di C ++, karena void*tidak dapat dipaksakan untuk jenis penunjuk lain seperti di C. glibc, misalnya, #define NULL 0saat __cplusplusditentukan.
rpjohnst
16

NULLbukan bagian asli dari bahasa C ++ inti, tetapi merupakan bagian dari pustaka standar. Anda perlu menyertakan salah satu file header standar yang menyertakan definisinya. #include <cstddef>atau #include <stddef.h>harus cukup.

Definisi NULLdijamin akan tersedia jika Anda menyertakan cstddefatau stddef.h. Ini tidak dijamin, tetapi Anda kemungkinan besar akan mendapatkan definisinya jika Anda menyertakan banyak header standar lainnya.

CB Bailey
sumber
12

Apakah Anda menyertakan "stdlib.h" atau "cstdlib" dalam file ini? NULL didefinisikan di stdlib.h / cstdlib

#include <stdlib.h>

atau

#include <cstdlib>  // This is preferrable for c++
Andy White
sumber
2
NULL adalah bagian dari stddef.h, bukan stdlib.h
awiebe
@awiebe Itulah yang saya pikirkan sampai lima menit yang lalu - menurut C99 cukup banyak file header yang berbeda harus mendefinisikannya. Bagian 7.17 membutuhkan stddef.h ke, 7.20 membutuhkannya di stdlib.h, dan mungkin ada beberapa yang lain.
AJM-Reinstate-Monica
4

Jangan gunakan NULL, C ++ memungkinkan Anda untuk menggunakan tanpa hiasan 0:

previous = 0;
next = 0;

Dan, seperti pada C ++ 11, Anda biasanya tidak boleh menggunakan salah satu NULL atau 0 karena ini memberi Anda nullptrtipe std::nullptr_t, yang lebih cocok untuk tugas tersebut.

paxdiablo
sumber
33
Saya cenderung berpikir bahwa NULL adalah dokumentasi yang berguna bahwa Anda bermaksud menggunakan konstanta penunjuk nol daripada konstanta integer, meskipun saya tidak keberatan menggunakan 0. Saya akan mengakui bahwa Anda tidak mendapatkan manfaat praktis apa pun saat ini , tetapi jika / ketika Anda mengadopsi versi C ++ berikutnya, ini memberikan awal yang baik untuk tempat-tempat yang akan diubah untuk menggunakan konstanta nullptr baru.
CB Bailey
1
Saya setuju dengan Anda berdua, tentu saja. Kebetulan, itu baik bahwa satu dokumen yang menggunakan pointer, tetapi juga bagus satu dokumen yang benar-benar mengedepankan integer. pertimbangkan printf ("% p \ n", NULL); // OH, UB. Atau jika Anda memiliki dua kelebihan beban, void f (int); batal f (batal *); Anda mungkin berpikir bahwa f (NULL); memanggil versi void * saat melihat sekilas panggilan tersebut. f (0); akan mendokumentasikan fakta bahwa itu benar-benar akan memanggil versi int, tetapi tidak akan mendokumentasikan fakta bahwa Anda bermaksud untuk memberikan pointer :( Bagus, nullptr memperbaikinya :)
Johannes Schaub - litb