文字列がNULLと文字列が空の違いを教えてください
Q&A
以下2つの違いを教えて欲しいです。
私は文字列がNULLとは、つまり文字列が空という意味だと勘違いしていました。その違いが知りたいです。
①文字列strがNULL
str == NULL
②文字列strが空
str[0] == '\0';
Q&A
以下2つの違いを教えて欲しいです。
私は文字列がNULLとは、つまり文字列が空という意味だと勘違いしていました。その違いが知りたいです。
①文字列strがNULL
str == NULL
②文字列strが空
str[0] == '\0';
文字列がNULLというのは表現として曖昧なためここでは明確に区別します.
「ポインタstr
がNULL」というのはポインタがどこも指していない状態を言います.
対して「文字列が空」というのは,Cの場合は配列の先頭に\0
が入っている状態です.(ご存知でしょうがこの\0
は伝送路上でNULLを表すものとしてASCIIに定められています.)
配列が存在するということは,後者はメモリ領域がいくらか確保されています.もっと分かりやすく言うとscanfできるかどうかが違います.str
がどこかしらのアドレスを指していれば,scanfはそのアドレスからデータを書き込みますが,どこも指していなければデータを書き込むことができません.
scanfの%sはバッファオーバーランを起こすので,特に長さを制限せずにデータを読み込むのは危険です.
#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"
察するに、変数strはchar*
つまり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; /* * ① */
/* 特に*に注意。そっくりだけど、①と②でまったく意味が違う */