NULLが宣言されていないのはなぜですか?


87

このコードをコンパイルしようとすると、この構造体コンストラクターに問題があります。

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

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

私が来ると、このエラーが発生します:

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

最後の問題は構造体でしたが、main.cppにあるときは正常に機能しました。今回はヘッダーファイルにあり、この問題が発生しています。このコードをコンパイルするためにCode :: Blocksを使用しています

回答:


139

NULLCまたはC ++言語の組み込み定数ではありません。実際、C ++では多かれ少なかれ時代遅れであり、0代わりにプレーンリテラルを使用するだけで、コンパイラはコンテキストに応じて正しいことを行います。

新しいC ++(C ++ 11以降)では、を使用しますnullptr(コメントで指摘されているように、ありがとうございます)。

それ以外の場合は、

#include <stddef.h>

NULL定義を取得します。


7
NULLはstdlib.hではなくstddef.hの一部です。技術的には、stdlib.hの一部として取得できるとは限りませんが、取得しなかった場合はかなり驚くことになると思います。
CBベイリー

8
NULLは、次のCヘッダーで定義されています:stddef.h、stdlib.h、stdio.h、locale.h、string.h、およびtime.h(およびC99をカウントする場合はwchar.h)。
Michael Burr

8
<cstddef>よりクリーンなオプションです。
Fred Foo

29
「NULL」を意味する場合は「0」を使用しないでください。違いがあります:セマンティクス。コンパイラーがそれを回避できるとしても、何かが何であるかを知り、正しい単語を使用することの重要性を過小評価しないでください!
imallett 2013

13
@ 6502それについて話していません。0とNULLは(ほぼ)常に同じ値であるため、「\ 0」または0を使用すると誤って機能します。問題はセマンティクスです。NULLを使用すると、値が質問であり、単なる整数ではなくポインタであることが示されるため、より表現力があります。
imallett 2013

34

NULLを使用してください。とにかくそれは単に0として定義されており、整数0と意味的に区別するのに非常に便利です。

0(したがってNULL)の使用には問題があります。例えば:

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

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

C ++の次のバージョン(C ++ 0x)にはnullptr、これを修正することが含まれています。

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

5
これは((void *)0)、ほとんどのC標準ライブラリの実装によって定義されています。
Triang3l 2013

1
これは、このトピックに関して私が今まで読んだ中で最も短い答えです(そして技術的に正確です):NULL対0対nullptr。ありがとうございました!
jose.angel.jimenez 2014

2
@SiPlusが((void *)0)あるため、C ++で間違っているvoid*他のポインタ型にはC.のはglibcにある道を強制可能ではないが、例えば、ない#define NULL 0とき__cplusplusに定義されています。
rpjohnst 2015

16

NULLはコアC ++言語のネイティブ部分ではありませんが、標準ライブラリの一部です。その定義を含む標準ヘッダーファイルの1つをインクルードする必要があります。#include <cstddef>または#include <stddef.h>十分なはずです。

またはNULLを含めると、の定義が利用可能であることが保証されます。保証はされていませんが、代わりに他の多くの標準ヘッダーを含めると、その定義が含まれる可能性が非常に高くなります。cstddefstddef.h


12

このファイルに「stdlib.h」または「cstdlib」を含めていますか?NULLはstdlib.h / cstdlibで定義されています

#include <stdlib.h>

または

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

2
NULLはstdlib.hではなくstddef.hの一部です
awiebe 2016年

@awiebeそれは、5分前まで私が考えていたものでした。C99によると、かなりの数の異なるヘッダーファイルで定義する必要があります。セクション7.17ではstddef.hからを必要とし、7.20ではstdlib.hでそれを必要とし、おそらく他にもかなりの数があります。
AJM-復活-モニカ

4

使用しないでくださいNULL。C++では、0代わりに装飾なしを使用できます。

previous = 0;
next = 0;

また、C ++ 11の場合と同様に、通常はどちらも使用しないでください。NULL または 0nullptrタイプが提供さstd::nullptr_tれるため、タスクにより適しています。


33
NULLは、整数定数ではなくnullポインター定数を使用することを意図している有用なドキュメントだと思う傾向がありますが、0の使用には反対しません。現時点では、実用的なメリットは得られないことを認めます。ただし、次のC ++バージョンを採用する場合は、新しいnullptr定数を使用するように変更する場所を見つけるのに適しています。
CBベイリー

1
もちろん、私はあなたの両方に同意します。ちなみに、1つのドキュメントがポインタを使用するのは良いことですが、実際に整数を前に出すのも良いドキュメントです。printf( "%p \ n"、NULL);を検討してください。// OH、UB。または、2つのオーバーロードがある場合は、void f(int); void f(void *); あなたはf(NULL);と思うかもしれません。呼び出しをざっと見てみると、void *バージョンを呼び出します。f(0); 実際にintバージョンを呼び出すという事実は文書化されますが、ポインタを渡すつもりであるという事実は文書化されません:( nullptrが修正するのは良いことです:)
Johannes Schaub --litb 2009年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.