cpp_2_2_指针 Pointer_2_空指针

  1. Overview
  2. Null pointers 空指针
  3. The nullptr keyword nullptr关键字
  4. 空指针的检查

Overview

1.Null pointers 空指针
2.The nullptr keyword nullptr关键字
3.空指针的检查

Null pointers 空指针

0.上次我们谈到, 指针保存一个 object 的地址, 通过 dereference 运算符 * 实现 object 的获取, 但是得额外注意下一下空指针的情况
1.指针除了可以保存内存地址以外, 还可以保存一种特殊的值: a null value. null value (经常简写为null) 是一种特殊的value, null value 就是 no value
2.null pointer: 当一个指针可以指向 null value 的时候, 也是意味着指针不指向任何的 object

int main() {
  int* ptr{}; // ptr就是第一个 null pointer, 没保存任何地址而存在
  int x{5};
  ptr = &x;     
  std::cout << *ptr << '\n';
  return 0;
}

The nullptr keyword nullptr关键字

1.类比一下 ture 和 false 作为 boolean 类型的字面值, nullptr 是代表 nullptr 的字面值
2.我们可以用 nullptr 去显式初始化一个 pointer, 这也是 pointer 的 best practice
3.对一个 null pointer, dereference 一个 null pointer 会导致未定义的行为

A pointer should either hold the address of a valid object, or be set to nullptr. That way we only need to test pointers for null, and can assume any non-null pointer is valid.

4.采用 nullptr 可以在一定程度上避免 dangling pointers, 一个指针要么保存一个有效的 object 的地址, 要么设置为 nullptr, 这样的话我们只需要测试空指针, 默认非空的指针是有效的
5.因此在使用指针的时候, 通常要检查是否空指针, 采用 if (ptr), 这时候会隐式的转化为 boolean 变量

int main() {
  int* ptr{nullptr};      // can use nullptr to initialize a pointer to be a null pointer
  int value{5};
  int* ptr2{&value};      // ptr2 is a valid pointer
  ptr2 = nullptr;         // Can assign nullptr to make the pointer a null pointer
  someFunction(nullptr);  // we can also pass nullptr to a function that has a pointer parameter
  return 0;
}

检查空指针的操作

#include <iostream>
int main() {
  int x{5};
  int* ptr{&x};

  // 空指针检查的时候会隐式转化成 boolean 变量
  if (ptr) {
    std::cout << "ptr is non-null\n";
  } else {
    std::cout << "ptr is null\n";
  }

  int* nullPtr{};
  std::cout << "nullPtr is " << (nullPtr ? "non-null\n" : "null\n"); // 空指针检查的时候会隐式转化成 boolean 变量
  return 0;
}

输出

ptr is non-null
nullPtr is null

空指针的检查

#include <iostream>
int main() {
  int x = 5;
  int* p1;            // 编辑器会提示 p1 没有初始化, 但是可以编译, 这里我们规定一个规则: 代码严格不这么写
  int* p2{};          // 编译器毫无提示
  int* p3 = &x;       // 一个确定的指针
  int* p4 = nullptr;  // 一个指向null value的指针
  int* p5 = NULL;     // 一个指向NULL的指针
  if (p1) {
    std::cout << "*p1:" << *p1 << std::endl;
  }
  if (p2) {
    std::cout << "*p2:" << *p2 << std::endl;
  }
  if (p3) {
    std::cout << "*p3:" << *p3 << std::endl;
  }
  if (p4) {
    std::cout << "*p4:" << *p4 << std::endl;
  }
  if (p5) {
    std::cout << "*p5:" << *p5 << std::endl;
  }
  std::cout << "middle" << std::endl;
  return 0;
}

转载请注明来源, from goldandrabbit.github.io

💰

×

Help us with donation