时间:2026-03-16 15:11
人气:
作者:admin
先看一段代码:
#include <iostream>
using namespace std;
void func(char* p) {
cout << "void func(char* p)" << endl;
cout << p << endl;
}
void func(int p) {
cout << "void func(int p)" << endl;;
cout << p << endl;
}
int main() {
//int
func(10);
//char*
func(NULL); //这里我希望程序调用func(char* p)的函数
system("pause");
return 0;
}
输出结果:
void func(int p)
10
void func(int p)
0
调用了两次func(int p)函数,且按理说NULL指针是不能cout的
也就是说第二次调用func(NULL)也调用了一次func(int p) 并且传入的p是0
原因:
在底层源码中NULL这个宏是这样定义的
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
也就是说如果源码是C++程序NULL就是0,如果是C程序NULL表示(void*)0。那么为什么要这样做呢? 是由于 C++ 中,void * 类型无法隐式转换为其他类型的指针,此时使用 0 代替 ((void *)0),用于解决空指针的问题。这个0(0x0000 0000)表示的就是虚拟地址空间中的0地址,这块地址是只读的。
正如:C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种
char *ptr = 0;
char *ptr = NULL;
并且
int* ptr1 = NULL;
char* ptr2 = NULL;
double* ptr3 = NULL;
void* ptr4 = NULL;
int* ptr5 = ptr4;//报错:"void*"类型的值不能用于初始化"int*"类型的实体
//是由于 C++ 中,void * 类型无法隐式转换为其他类型的指针,此时使用 0 代替 ((void *)0),用于解决空指针的问题。
int* ptr5 = (int*)ptr4; //强转正确不报错
C++11引入nullptr关键字用于标识空指针,是std::nullptr_t类型的(constexpr)变量。它可以转换成任何指针类型和bool布尔类型(主要是为了兼容普通指针可以作为条件判断语句的写法),但是不能被转换为整数。
nullptr是专用于初始化空类型指针,不同类型的指针变量都可以使用 nullptr 来初始化,nullptr 出现的目的是为了替代 NULL
#include <iostream>
using namespace std;
void func(char* p) {
cout << "void func(char* p)" << endl;
//cout << *p << endl;
}
void func(int p) {
cout << "void func(int p)" << endl;;
//cout << p << endl;
}
int main() {
int* ptr1 = nullptr;
char* ptr2 = nullptr;
double* ptr3 = nullptr;
void* ptr4 = nullptr;
int* ptr5 = (int*)ptr4;
//int
func(10);
//char*
func(nullptr);
system("pause");
return 0;
}
输出结果:
void func(int p)
void func(char* p)
通过输出的结果可以看出,nullptr 无法隐式转换为整形,但是可以隐式匹配指针类型。在 C++11 标准下,相比 NULL 和 0,使用 nullptr 初始化空指针可以令我们编写的程序更加健壮,因此当需要使用 NULL 时候,养成直接使用 nullptr的习惯。
上一篇:基于范围的for循环
下一篇:没有了