1.运行环境
操作系统:windows10
使用的IDE:visual studio comunity 2019
编译器标准:ISO C++17 标准 (std:c++17)
2.空指针
C++03中,空指针使用“0”来表示。0既是一个常量整数,也是一个常量空指针。即会出现:0具有二义性;
在C语言中,空指针使用(void *)0来表示;
在c++中用“NULL”来表示空指针(VS内部实现方式是#define NULL 0)
如下图1:
C++标准化委员会希望“空指针”是一个确定的东西。
即在C++11中引入保留字“nullptr”作为空指针。
如下图2:
注意:
为了避免二义性的问题,建议使用保留字“nullptr”作为空指针;
在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 nullptr是一个良好的编程习惯,以避免产生野指针。
3.示例
-3.1 判断空指针
一般来说,操作系统的程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。
利用这个特性判定空指针:指针的地址为 0 ,表明该指针不指向任何东西,即空指针。
如下示例,打印空指针的值,判断是否为空指针:
#include <iostream>
int main()
{
//指针创建的时候,记得初始化,避免产生野指针。
int* ptr1 = NULL;
int* ptr2 = nullptr;
std::cout << "ptr1 的值是 " << ptr1 <<std::endl;
std::cout << "ptr2 的值是 " << ptr2 << std::endl;
if (!ptr2) /* 如果 ptr 为空,则为真 */
{
std::cout <<"打印逻辑判断:" << (ptr1 == 0) << std::endl;
std::cout << "打印逻辑判断:" << (ptr2 == 0) << std::endl;
std::cout << "打印逻辑判断:" << (ptr1 == ptr2) << std::endl;
}
return 0;
}
运行如下图3:
-3.2 访问非空指针的地址
如果将指针 p 指向一个初始化好的变量 a 的内存地址,
我们可以正常通过 p 和 *p 访问指针 p 存储的地址值和它指向的内存地址存储的值。
如果我们将 nullptr 赋值给指针 p,打印指针变量p存储的地址值发现为 0,
而尝试访问指针变量 p 指向的内存地址(0)存储的值会直接报错!
如下示例,访问空指针直接报错:
#include <iostream>
using namespace std;
int main(int argc, char const* argv[])
{
int a = 537;
int* p = &a;
std::cout << p << ',' << *p << endl;
p = nullptr; //建议不要使用NULL
std::cout << p << ',' << *p << std::endl;
return 0;
}
运行如下图4:
4.关于野指针
野指针不是空指针,是一个指向垃圾内存的指针。
形成原因:.指针变量没有被初始化。
任何指针变量被刚创建时不会被自动初始化为nullptr指针,它的缺省值是随机的。
因此,指针变量在创建的同时应当被初始化,要么将指针设置为nullptr ,要么让它指向合法的内存。例如:
//将指针设置为nullptr
int* p1 = nullptr ;
//或者指向合法的内存
int a = 537;
int* p2 = &a;