■null判定って書くのは止めよう!
【null判定】
【ヌル判定】
【ナル判定】
って書くのは止めよう!
【NULLポインタ判定】
【空文字列判定】
【終端文字¥0判定】
と書こう。
■推奨例:空文字列を判定する関数
#include <stdbool.h>
#include <stdio.h>
bool isEmptyString(const char *p){
if(p == NULL) {
printf("NULLポインタ\t");
return true;
}
if(p[0] == '\0'){
printf("空文字列\t");
return true;
}
printf("有効文字列\t");
return false ;
}
int main(void) {
printf("%d\n",isEmptyString(NULL)); //NULLポインタ
printf("%d\n",isEmptyString("")); //空文字列
printf("%d\n",isEmptyString("有効文字列"));
}
NULLポインタと終端文字¥0、
NULLポインタと空文字列””を
しっかり区別しましょう。
■非推奨例1:いきなりstrcmp
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool isEmptyString(const char *p){
if(strcmp(p,"") == 0) {
printf("空文字列\t");
return true;
}
printf("有効文字列\t");
return false ;
}
int main(void) {
printf("%d\n",isEmptyString(NULL)); //NULLポインタ
printf("%d\n",isEmptyString("")); //空文字列
printf("%d\n",isEmptyString("有効文字列"));
}
引数のポインタが空文字列かどうか判定したい時、
strcmp()を使って第二引数にNULLポインタを渡してはいけません。
NULL参照が発生して
プログラムが異常終了してしまう可能性があります。
■非推奨例2:いきなりstrlen
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool isEmptyString(const char *p){
if(strlen(p) == 0) {
printf("空文字列\t");
return true;
}
printf("有効文字列\t");
return false ;
}
int main(void) {
printf("%d\n",isEmptyString(NULL)); //NULLポインタ
printf("%d\n",isEmptyString("")); //空文字列
printf("%d\n",isEmptyString("有効文字列"));
}
NULLポインタのチェックをしてからstrlen(p)を呼び出しましょう。
又、strlen(p) 関数を呼び出すため、
関数呼び出しのオーバーヘッド分プログラムの実行速度が
遅くなります。
■非推奨例3:NULLと’\0’の混乱
#include <stdbool.h>
#include <stdio.h>
bool isEmptyString(const char *p){
if(p == '\0') {
printf("NULLポインタ\t");
return true;
}
if(p[0] == NULL){
printf("空文字列\t");
return true;
}
printf("有効文字列\t");
return false ;
}
int main(void) {
printf("%d\n",isEmptyString(NULL)); //NULLポインタ
printf("%d\n",isEmptyString("")); //空文字列
printf("%d\n",isEmptyString("有効文字列"));
}
上記のコードはNULLポインタと終端文字¥0の区別がついていない
初級者の間違いです。
ポインタpを終端文字\0と比較したり
一文字のp[0] と NULLポインタを比較しています。
■非推奨例4:NULLポインタ判定が遅い
#include <stdbool.h>
#include <stdio.h>
bool isEmptyString(const char *p){
if(p[0] == '\0' && p != NULL){
printf("空文字列\t");
return true;
}
if(p == NULL){
printf("NULLポインタ\t");
return true;
}
printf("有効文字列\t");
return false ;
}
int main(void) {
printf("%d\n",isEmptyString(NULL)); //NULLポインタ
printf("%d\n",isEmptyString("")); //空文字列
printf("%d\n",isEmptyString("有効文字列"));
}
上記のコードは
p != NULLの判定をする前に
p[0] を参照してしまった例で
これでは p がNULLの時NULL参照が発生してしまいます。
先に p != NULL の判定を行う必要があります。

参考:
C-FAQ5.13: “ヌル”とか”NULL”とか”ナル”という単語が無造作に使われるときは以下のどれかを意味する。
http://www.kouno.jp/home/c_faq/c5.html#13