在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。
先看一下控制台版本的程序运行;
在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。
如需检查一个空指针,您可以使用 if 语句,如下:
if(ptr) /* 如果 ptr 非空,则完成 */
if(!ptr) /* 如果 ptr 为空,则完成 */
因此,如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。
用 vs2013 可以看到,NULL 的定义就是:
define NULL 0
看如下程序,输出 NULL=0;
看Win32版本的程序;
#include
#include "resource.h"
using namespace std;
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HINSTANCE hInst;
TCHAR szClassName[] = TEXT("nullptrDemo");
int WINAPI
WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HWND hwnd;
MSG messages;
WNDCLASSEX wincl;
hInst = hThisInstance;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = MAKEINTRESOURCE (IDC_NULLPTRDEMO);
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
if (!RegisterClassEx (&wincl))
return 0;
hwnd = CreateWindowEx (
0,
szClassName,
TEXT("C++ NULL指针 Demo"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
200,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
ShowWindow (hwnd, nFunsterStil);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
LRESULT CALLBACK
WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
RECT rt;
char szBuffer[100];
int *ptr = NULL;
switch (message)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_nullptr:
hdc=GetDC(hwnd);
wsprintf(szBuffer, "ptr 的值是%d",ptr);
TextOut(hdc,10,10,szBuffer,lstrlen(szBuffer));
wsprintf(szBuffer, "NULL=%d",NULL);
TextOut(hdc,10,40,szBuffer,lstrlen(szBuffer));
break;
case IDM_ABOUT:
MessageBox (hwnd, TEXT ("nullptrDemo v1.0\nCopyright (C) 2020\n by bo"),
TEXT ("nullptrDemo"), MB_OK | MB_ICONINFORMATION);
break;
case IDM_EXIT:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
break;
case WM_CREATE:
break;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rt);
EndPaint(hwnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
运行结果如上图;
菜单如上;
工程;
1
资源和头文件;
#include "resource.h"
#include
/
//
// Menu
//
IDC_NULLPTRDEMO MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "C++ Null指针 Demo", IDM_nullptr
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
END
#define IDM_EXIT 10001
#define IDM_ABOUT 10002
#define IDC_NULLPTRDEMO 10101
#define IDD_ABOUTBOX 10102
#define IDM_nullptr 40001