LoginSignup
roku-trlt
@roku-trlt (kuro kuro)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

文字列がNULLと文字列が空の違いを教えてください

Q&A

以下2つの違いを教えて欲しいです。
私は文字列がNULLとは、つまり文字列が空という意味だと勘違いしていました。その違いが知りたいです。

①文字列strがNULL

str == NULL

②文字列strが空

str[0] == '\0';
0

4Answer

文字列がNULLというのは表現として曖昧なためここでは明確に区別します.

「ポインタstrがNULL」というのはポインタがどこも指していない状態を言います.
対して「文字列が空」というのは,Cの場合は配列の先頭に\0が入っている状態です.(ご存知でしょうがこの\0は伝送路上でNULLを表すものとしてASCIIに定められています.)
配列が存在するということは,後者はメモリ領域がいくらか確保されています.もっと分かりやすく言うとscanfできるかどうかが違います.strがどこかしらのアドレスを指していれば,scanfはそのアドレスからデータを書き込みますが,どこも指していなければデータを書き込むことができません.

scanfの%sはバッファオーバーランを起こすので,特に長さを制限せずにデータを読み込むのは危険です.

1Like
#include <stdio.h>
#include <string.h>

void hoge(const char* str)
{
    if (str == NULL) {
        printf("文字列がNULL\n");
    } else if (strlen(str) == 0) {    
        printf("文字列が空\n");
    } else {
        printf("文字列が\"%s\"\n", str);    
    }
}

int main(void)
{
    hoge("");
    hoge(NULL);
    hoge("HOGE HOGE");
}
文字列が空
文字列がNULL
文字列が"HOGE HOGE"

0Like

Comments

  1. なぜ違いを教えてという質問にスニペットだけ貼っていくのか

察するに、変数strchar*つまりcharのポインタ型です。char[]char型の配列でも意味は同じ。
①は、変数strにnullをセットしているので、何の文字列をも示していないということになります。当然ながら「空の文字列」を示していることにもなりません。もし文字列として参照すると、null pointer exceptionで落ちます。
一方、②は「空の文字列」を示していることと同値です。C言語の文字列は、最後の文字の直後に\0をセットすることで、文字列の終端を示します。配列の添え字の0は、文字列の1文字目を表していて、そこが\0ですから「空の文字列」となります。

質問の「文字列がNULLと文字列が空の違い」は以上ですが、「文字列がNULL」という表現は曖昧性を含んでいて誤解を生じやすいと思います。①と②のどちらを指しているのか、一見判断できませんから。

なぜなら、C言語のNULLは、確か(void*)0か単なる0で、str[0] = NULLと書いてもエラーにならいと思います。下記*①を見ると「文字列がNULL」と表現したくなりますね。(記憶が曖昧)C言語もK&RとANSIで違ったかも。

str[0] = '\0';
str[0] = 0;
str[0] = NULL;
*str = '\0';
*str = NULL;    /* * ② */
char str[] = "";
/*上記はどれも「空の文字列」の意味。しかし、下記は意味が異なる。*/
str = NULL;
char *str =  NULL;    /* * ① */
/* 特に*に注意。そっくりだけど、①と②でまったく意味が違う */
0Like

Comments

  1. ChatGPT君に聞いたところ、一例だと断り付きで教えてくれました。
     K&R `#define NULL 0`
     ANSI `#define NULL ((void*)0)`

    ということで、最近のCコンパイラなら、②に分類される`str[0] = NULL`や`*str = NULL`は、型が違うとワーニングかエラーが出ると思います。

Your answer might help someone💌