- C编程教程
- C语言 - 首页
- C语言基础
- C语言 - 概述
- C语言 - 特性
- C语言 - 历史
- C语言 - 环境搭建
- C语言 - 程序结构
- C语言 - Hello World
- C语言 - 编译过程
- C语言 - 注释
- C语言 - 词法单元
- C语言 - 关键字
- C语言 - 标识符
- C语言 - 用户输入
- C语言 - 基本语法
- C语言 - 数据类型
- C语言 - 变量
- C语言 - 整数提升
- C语言 - 类型转换
- C语言 - 类型强制转换
- C语言 - 布尔值
- C语言中的常量和字面量
- C语言 - 常量
- C语言 - 字面量
- C语言 - 转义序列
- C语言 - 格式说明符
- C语言中的运算符
- C语言 - 运算符
- C语言 - 算术运算符
- C语言 - 关系运算符
- C语言 - 逻辑运算符
- C语言 - 位运算符
- C语言 - 赋值运算符
- C语言 - 一元运算符
- C语言 - 自增和自减运算符
- C语言 - 三元运算符
- C语言 - sizeof 运算符
- C语言 - 运算符优先级
- C语言 - 其他运算符
- C语言中的决策语句
- C语言 - 决策语句
- C语言 - if 语句
- C语言 - if...else 语句
- C语言 - 嵌套 if 语句
- C语言 - switch 语句
- C语言 - 嵌套 switch 语句
- C语言中的循环
- C语言 - 循环
- C语言 - while 循环
- C语言 - for 循环
- C语言 - do...while 循环
- C语言 - 嵌套循环
- C语言 - 死循环
- C语言 - break 语句
- C语言 - continue 语句
- C语言 - goto 语句
- C语言中的函数
- C语言 - 函数
- C语言 - 主函数
- C语言 - 按值调用函数
- C语言 - 按引用调用函数
- C语言 - 嵌套函数
- C语言 - 可变参数函数
- C语言 - 用户自定义函数
- C语言 - 回调函数
- C语言 - return 语句
- C语言 - 递归
- C语言中的作用域规则
- C语言 - 作用域规则
- C语言 - 静态变量
- C语言 - 全局变量
- C语言中的数组
- C语言 - 数组
- C语言 - 数组的特性
- C语言 - 多维数组
- C语言 - 将数组传递给函数
- C语言 - 从函数返回数组
- C语言 - 变长数组
- C语言中的指针
- C语言 - 指针
- C语言 - 指针和数组
- C语言 - 指针的应用
- C语言 - 指针运算
- C语言 - 指针数组
- C语言 - 指向指针的指针
- C语言 - 将指针传递给函数
- C语言 - 从函数返回指针
- C语言 - 函数指针
- C语言 - 指向数组的指针
- C语言 - 指向结构体的指针
- C语言 - 指针链
- C语言 - 指针与数组的区别
- C语言 - 字符指针和函数
- C语言 - 空指针
- C语言 - void 指针
- C语言 - 悬空指针
- C语言 - 解引用指针
- C语言 - 近指针、远指针和巨指针
- C语言 - 指针数组的初始化
- C语言 - 指针与多维数组的区别
- C语言中的字符串
- C语言 - 字符串
- C语言 - 字符串数组
- C语言 - 特殊字符
- C语言中的结构体和联合体
- C语言 - 结构体
- C语言 - 结构体和函数
- C语言 - 结构体数组
- C语言 - 自引用结构体
- C语言 - 查找表
- C语言 - 点 (.) 运算符
- C语言 - 枚举 (enum)
- C语言 - 结构体填充和打包
- C语言 - 嵌套结构体
- C语言 - 匿名结构体和联合体
- C语言 - 联合体
- C语言 - 位域
- C语言 - typedef
- C语言中的文件处理
- C语言 - 输入 & 输出
- C语言 - 文件 I/O (文件处理)
- C语言预处理器
- C语言 - 预处理器
- C语言 - 编译指示
- C语言 - 预处理器运算符
- C语言 - 宏
- C语言 - 头文件
- C语言中的内存管理
- C语言 - 内存管理
- C语言 - 内存地址
- C语言 - 存储类
- 其他主题
- C语言 - 错误处理
- C语言 - 可变参数
- C语言 - 命令执行
- C语言 - 数学函数
- C语言 - static 关键字
- C语言 - 随机数生成
- C语言 - 命令行参数
- C编程资源
- C语言 - 问答
- C语言 - 快速指南
- C语言 - 速查表
- C语言 - 有用资源
- C语言 - 讨论
C语言中的指针链
什么是C语言中的指针链?
C语言中的指针链是一系列相互指向的指针。指针变量可以存储另一个变量的地址,这个变量可以是任何类型,包括另一个指针,在这种情况下,它被称为指向指针的指针。
指针链是指存在多个级别的指针。理论上,链的级别没有限制,如下图所示:
指针链的声明
这可以用以下代码表示:
int a = 10; int *x = &a; int **y = &x; int ***z = &y;
在上面的例子中,“x”是指向“int”类型的指针,如符号“int *”所示。要在“y”中存储“x”的地址,“y”应该是指向指向int的指针,即“int **”。
类似地,“z”是“指向指向指向int的指针”的指针,因此其声明中星号出现了三次,即“int ***”。
解引用是如何工作的?
我们知道“*x”返回存储在“x”中的地址处的值,即“a”的值。
根据相同的逻辑,“*y”应该返回它的值(参考上图),它是1000,这反过来又是“a”的地址。因此,“y”的双重解引用(即“**y”)应该给出“a”的值。
此外,“z”的三重解引用(即“***z”)应该给出“a”的值。
示例
下面的例子展示了“双重解引用”和“三重解引用”是如何工作的:
#include <stdio.h> int main(){ int a = 10; int *x = &a; int **y = &x; int ***z = &y; printf("a: %d\n", a); printf("a: %d\n", *x); // dereferencing x; printf("a: %d\n", **y); // double dereferencing y; printf("a: %d\n", ***z); // triple dereferencing z; return 0; }
输出
请注意,所有三种解引用情况都打印了“a”的值:
a: 10 a: 10 a: 10 a: 10
浮点型指针链
我们可以遵循相同的逻辑来创建一个浮点型指针链,并应用多级解引用来获取浮点型变量的值。
示例
下面的例子展示了如何使用浮点型指针链:
#include <stdio.h> int main(){ float a = 10.25; float *x = &a; float **y = &x; float ***z = &y; printf("a: %f\n", a); printf("a: %f\n", *x); printf("a: %f\n", **y); printf("a: %f\n", ***z); return 0; }
输出
运行代码并检查其输出:
a: 10.250000 a: 10.250000 a: 10.250000 a: 10.250000
通过解引用更新原始变量
我们还可以通过解引用来更新原始变量的值。请看下面的语句:
*x = 11.25;
它会相应地更改“a”的值。类似地,它可以使用后续级别的指针进行更新。
示例
下面的程序展示了如何使用不同级别的解引用来更新原始变量:
#include <stdio.h> int main(){ float a = 10.25;; float *x = &a; float **y = &x; float ***z = &y; printf("a: %f\n", a); // update with first pointer *x = 11.25; printf("a: %f\n", *x); // update with second pointer **y = 12.25; printf("a: %f\n", **y); // update with third pointer ***z = 13.25; printf("a: %f\n", ***z); return 0; }
输出
运行代码并检查其输出:
a:10.250000 a:11.250000 a:12.250000 a:13.250000
字符型指针链
字符串表示为“char”类型的数组或指向“char”类型的指针:
char *a = "Hello";
因此,我们可以创建一个字符型指针链。
注意:唯一的区别是,这里的原始变量本身就是一个指针,因此与前面的例子相比,上层指针多了一个星号。
示例
下面的例子展示了字符型指针链是如何工作的:
#include <stdio.h> int main(){ char *a = "Hello"; char **x = &a; char ***y = &x; char ****z = &y; printf("a: %s\n", a); printf("a: %s\n", *x); printf("a: %s\n", **y); printf("a: %s\n", ***z); return 0; }
输出
运行这段代码时,会产生以下输出:
a: Hello a: Hello a: Hello a: Hello