NULL neden bildirilmemiş?


87

Bu kodu derlemeye çalıştığımda bu yapı oluşturucusuyla ilgili bir sorun yaşıyorum:

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

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

geldiğimde bu hata oluşuyor:

\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 ===|

Son sorun yapıtı, ancak main.cpp'mdeyken iyi çalıştı, bu sefer bir başlık dosyasında ve bana bu sorunu veriyor. Bu kodu derlemek için Code :: Blocks kullanıyorum

Yanıtlar:


139

NULLC veya C ++ dillerinde yerleşik bir sabit değildir. Aslında, C ++ 'da az ya da çok modası geçmiş, 0bunun yerine düz bir değişmez kullanın, derleyici bağlama bağlı olarak doğru şeyi yapacaktır.

Daha yeni C ++ 'da (C ++ 11 ve üstü), nullptr (bir yorumda belirtildiği gibi, teşekkürler).

Aksi takdirde ekleyin

#include <stddef.h>

NULLtanımı almak için .


7
NULL stddef.h'nin bir parçasıdır, stdlib.h'nin bir parçasıdır. Teknik olarak stdlib.h'nin bir parçası olarak almanız garanti değil, ancak kabul etmeseniz oldukça şaşırtıcı olurdu.
CB Bailey

8
NULL, aşağıdaki C başlıklarında tanımlanmıştır: stddef.h, stdlib.h, stdio.h, locale.h, string.h ve time.h (ve C99'u sayarsanız wchar.h).
Michael Burr

8
<cstddef>daha temiz bir seçenektir.
Fred Foo

30
"NULL" demek istediğinizde "0" KULLANMAYIN! Bir fark var : anlambilim. Derleyici bundan kurtulmanıza izin verse bile, bir şeyin ne olduğunu bilmenin ve doğru kelimeyi kullanmanın önemini asla küçümsemeyin!
imallett

13
@ 6502 Bundan bahsetmiyorum; 0 ve NULL aynı değere sahiptir (hemen hemen), bu nedenle '\ 0' veya 0 kullanmak yanlışlıkla işe yarayacaktır. Sorun anlambilimdir. NULL kullanımı daha anlamlıdır, çünkü değerin soru olduğunu söyler, sadece bir tamsayı değil, bir işaretçi olduğunu söyler.
imallett

35

NULL kullanın. Zaten 0 olarak tanımlanmıştır ve onu 0 tamsayısından anlamsal olarak ayırmak çok yararlıdır.

0 (ve dolayısıyla NULL) kullanımıyla ilgili sorunlar var. Örneğin:

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

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

Sonraki C ++ sürümü (C ++ 0x) şunları içerir: nullptr bunu düzeltmeyi .

f(nullptr); // Calls f(void*).

5
((void *)0)Çoğu C standart kütüphane uygulaması tarafından tanımlanır .
Triang3l

1
Bu konuyla ilgili okuduğum en iyi kısa cevap (ve teknik olarak kesin): NULL, 0 ve nullptr. Teşekkür ederim!
jose.angel.jimenez

2
@SiPlus ((void *)0)nedeniyle, C ++ yanlıştır void*diğer işaretçi tiplerine de, örneğin, C glibc'de olduğu şekilde Coercible değildir, yok #define NULL 0olduğunda __cplusplustanımlanır.
rpjohnst

16

NULLçekirdek C ++ dilinin yerel bir parçası değildir, ancak standart kitaplığın bir parçasıdır. Tanımını içeren standart başlık dosyalarından birini eklemeniz gerekir. #include <cstddef>veya#include <stddef.h> yeterli olmalıdır.

Veya NULLeklerseniz tanımının mevcut olması garantilidir . Garanti edilmez, ancak bunun yerine diğer standart başlıkların birçoğunu eklerseniz tanımının dahil edilmesi çok olasıdır.cstddefstddef.h


12

Bu dosyaya "stdlib.h" veya "cstdlib" ekliyor musunuz? NULL, stdlib.h / cstdlib'de tanımlanmıştır.

#include <stdlib.h>

veya

#include <cstdlib>  // This is preferrable for c++

2
NULL stddef.h'nin bir parçasıdır, stdlib.h değil
awiebe

@awiebe Beş dakika öncesine kadar düşündüğüm buydu - C99'a göre birkaç farklı başlık dosyasının onu tanımlaması gerekiyor. Bölüm 7.17 stddef.h'yi gerektirir, 7.20 stdlib.h içinde gerektirir ve muhtemelen birkaç tane daha vardır.
AJM-Reinstate-Monica

4

Kullanmayın NULL, C ++ 0bunun yerine süslenmemiş olanı kullanmanıza izin verir :

previous = 0;
next = 0;

Ve, C ++ 11 itibariyle, genellikle kullanarak olmamalı NULL ya 0 da sağlar çünkü nullptrÇeşidi std::nullptr_tdaha iyi görev için uygundur.


33
Ben 0 kullanmaya itiraz etmeme rağmen, NULL'un bir tamsayı sabiti yerine bir boş gösterici sabiti kullanmayı düşündüğünüz yararlı bir dokümantasyon olduğunu düşünüyorum. Şu anda herhangi bir pratik fayda sağlamadığınızı kabul ediyorum , ancak bir sonraki C ++ sürümünü benimserseniz, yeni nullptr sabitini kullanmak için yerlerin değiştirilmesi için iyi bir başlangıç ​​sağlar.
CB Bailey

1
Elbette ikinize de katılıyorum. Bu arada, bir belgenin bir işaretçi kullanması hem iyidir, hem de bir kişinin gerçekten bir tam sayı koyduğu belgeler iyidir. printf ("% p \ n", NULL); // OH, UB. Veya iki aşırı yüklemeniz varsa, void f (int); void f (void *); f (NULL) olduğunu düşünebilirsiniz; görüşmeye hızlı bir şekilde göz atarken void * sürümünü çağırır. f (0); aslında int sürümünü çağıracağını belgeleyecek, ancak bir işaretçi geçirmeyi düşündüğünüzü belgelemeyecek :( İyi ki nullptr bunu düzeltir :)
Johannes Schaub - litb
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.