【C/C++】指针相关汇总 Pointer

本文深入解析C语言中的指针概念,包括指针类型、指针指向内容的类型、指针值及指针变量的内存地址。通过实例讲解不同类型的指针,如普通指针、二级指针、指针数组等,并探讨NULL、0与nullptr的区别。

Backto C/C++ Index

基础

指针的基础, 看透这一篇就够了, 神文 让你不再害怕指针——C指针详解(经典,非常详细)

看到一个 pointer, 明确其四个相关信息就 OK 了

  1. 指针的类型
  2. 指针指向内容的类型
  3. 指针的值或者叫指针所指向的内存区或地址
  4. 指针变量自身所在的内存地址

适合画图揣摩, 和 单链表 差不多.
作为练习, 明确下面几个类型

//这是一个普通的整型变量
int p; 

//首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,
// 说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针
int *p; 
 
 //首先从P 开始,先与*结合,说是P 是一个指针,然后再与*结合,说明指针所指向的元素是指针,
 // 然后再与int 结合,说明该指针所指向的元素是整型数据.
 int **p;
 
//首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,
//说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组
int p[3]; 

 //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P 是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组
int *p[3];

//首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),
// 说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.
// 所以P 是一个指向由整型数据组成的数组的指针
int (*p)[3]; 

// 从P 处起,先与()结合,说明P 是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数,
// 然后再与外面的int 结合,说明函数的返回值是一个整型数据
int p(int); 

//从P 处开始,先与指针结合,说明P 是一个指针,
// 然后与()结合,说明指针指向的是一个函数,
// 然后再与()里的int 结合,说明函数有一个int 型的参数,
// 再与最外层的int 结合,说明函数的返回类型是整型,
// 所以P 是一个指向有一个整型参数且返回类型为整型的函数的指针
int (*p)(int); 

//从P 开始,先与()结合,说明P 是一个函数,然后进入()里面,与int 结合,说明函数有一个整型变量参数,
// 然后再与外面的*结合,说明函数返回的是一个指针, 
// 然后到最外面一层,先与[]结合,说明返回的指针指向的是一个数组,
// 然后再与*结合,说明数组里的元素是指针,然后再与int 结合,
// 说明指针指向的内容是整型数据.
// 所以P 是一个参数为一个整数据且返回一个指向由整型指针变量组成的数组的指针变量的函数.
int *(*p(int))[3]; 

空指针 NULL vs 0 vs nullptr

详细解读, 看这里: 史上最明白的 NULL、0、nullptr 区别分析

  • C 中, 使用 NULL. 通常定义 #define NULL (void*(0)), 进行指针的隐式转换
  • C++11 引入了 nullptr, 直接用.
  • C++11 之前, 因为 C++ 强类型, 所以禁止了 C-style 的隐式转换, 而是采用 #define NULL (0) , 但是这样空指针就有了二值性, 同时是 空指针 和 int(0). 很麻烦. 忍受不了的话, 就自己定义一个 nullptr 吧
const
class nullptr_t
{
public:
    template<class T>
    inline operator T*() const
        { return 0; }

    template<class C, class T>
    inline operator T C::*() const
        { return 0; }
 
private:
    void operator&() const;
} nullptr = {};

打印指针变量

因为指针变量中存放的是地址, 所以打印的时候就按无符号整数打印就可以. 对于, 32-bit 系统, 一个指针正好可以转换为 unsigned int, 而 64-bit 系统, 一个指针则要转换为 unsigned long long.

char addr[100];
sprintf(addr, "%du", ptr32);
sprintf(addr, "%llu", ptr64);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值