- 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语言 - 返回语句
- 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语言中指针的解引用
**解引用运算符** 用于访问和操作由指针指向的变量中存储的值。**解引用**或**间接运算符**(***) 充当一元运算符,它需要一个指针变量作为其操作数。
语法
以下是解引用指针的语法:
*pointer_variable;
借助上述语法(解引用指针),您可以获取和更新任何由指针指向的变量的值。
如何解引用指针?
要解引用指针,您需要按照以下步骤操作:
- 创建一个变量并声明一个指针变量。
- 通过赋值变量的地址来初始化指针。
- 现在,您可以解引用指针来获取或更新变量的值。
示例
在此示例中,我们演示了这三个步骤来解引用指针:
#include <stdio.h> int main() { // Create a variable and pointer variable int x = 10; int *ptr; // Initialize the pointer by assigning // the address of the variable ptr = &x; // Dereference the pointer printf("Value of x = %d\n", *ptr); return 0; }
输出
运行代码并检查其输出:
Value of x = 10
什么是解引用?
术语“解引用”是指访问指针引用的内存地址中存储的值。解引用运算符(也称为**间接运算符**)获取目标变量的值。
示例
在上例中,如果我们打印“*b”,您将获得“a”的值,即 10。类似地,打印“*y”将显示 10.5。
#include <stdio.h> int main (){ int a = 10; int *b = &a; float x = 10.5; float *y = &x; printf ("Address of 'a': %d Value of 'a': %d\n", b, *b); printf ("Address of 'x': %d Value of 'x': %f\n", y, *y); return 0; }
输出
运行代码并检查其输出:
Address of 'a': 6422028 Value of 'a': 10 Address of 'x': 6422024 Value of 'x': 10.500000
通过解引用指针操作值
解引用运算符还有助于间接操作指针引用的变量的值。
示例
在此示例中,我们使用解引用指针更改“a”和“x”的值:
#include <stdio.h> int main (){ int a = 10; int *b = &a; float x = 10.5; float *y = &x; *b = 100; *y = 100.50; printf ("Address of 'a': %d Value of 'a': %d\n", b, *b); printf ("Address of 'x': %d Value of 'x': %f\n", y, *y); return 0; }
输出
运行代码并检查其输出:
Address of 'a': 6422028 Value of 'a': 100 Address of 'x': 6422024 Value of 'x': 100.500000
解引用双指针
就像您将普通变量的地址存储在其指针中一样,您也可以拥有一个存储另一个指针地址的指针。拥有另一个指针地址的指针称为双指针或指向指针的指针。
让我们声明一个指向整数类型的指针,并将整数变量的地址存储在其中。
int a = 10; int *b = &a;
解引用运算符通过指针获取值:
printf("a: %d \n Pointer to 'a' is 'b': %d \n Value at 'b': %d", a, b, *b);
整数变量的值、其地址以及解引用指针获得的值将被打印为:
a: 10 Pointer to 'a' is 'b': 6422036 Value at 'b': 10
现在让我们声明一个可以存储“b”地址的指针,“b”本身是指向整数类型的指针,写成“int *”。让我们假设编译器也为其分配地址 3000。因此,“c”是指向指向int的指针,应声明为“int **”。
int **c = &b; printf("b: %d \n Pointer to 'b' is 'c': %d \n Value at 'b': %d\n", b, c, *c);
您可以获得b的值(它是a的地址)、c的值(它是b的地址)以及从c解引用的值(它是a的地址)。
b: 6422036 Pointer to 'b' is 'c': 6422024 Value at 'b': 6422036
由于这里“c”是双指针,声明中的第一个星号指向“b”,第二个星号依次指向“a”。我们可以使用双重引用指针从“c”获得“a”的值。
printf("Value of 'a' from 'c': %d", **c);
这应该显示a的值为10。
示例
尝试运行以下完整代码:
#include <stdio.h> int main (){ int a = 10; int *b = &a; printf("a: %d \n Address: %d \n Value at 'a': %d\n\n", a, b, *b); int **c = &b; printf("b: %d \n Pointer to 'b' is 'c': %d \n Value at 'b': %d\n", b, c, *c); printf("Value of 'a' from 'c': %d", **c); return 0; }
输出
运行此代码时,将产生以下输出:
a: 10 Address: 6422036 Value at a: 10 b: 6422036 Pointer to 'b' is 'c': 6422024 Value at 'b': 6422036 Value of 'a' from 'c': 10
解引用结构体指针
关键字“struct”用于创建一个派生数据类型,该类型由一个或多个不同类型元素组成。像普通变量一样,您可以声明一个结构体指针并存储其地址。
struct book{ char title[10]; double price; int pages; }; struct book b1 = {"Learn C", 650.50, 325}; struct book *ptr = &b1;
在C语言中,用箭头符号 (→) 表示的间接运算符用于获取结构体指针引用的结构体变量的元素的值。
示例
“ptr -> title”返回title元素的值,与“b1.title”返回的值相同。“ptr -> price”等同于“b1.price”等。
#include <stdio.h> struct book{ char title[10]; double price; int pages; }; int main (){ struct book b1 = {"Learn C", 650.50, 325}; struct book *ptr = &b1; printf("With -> Operator: \n"); printf("Title: %s \nPrice: %7.2lf \nNumber of Pages: %d\n\n", ptr->title, ptr->price, ptr->pages); printf("With . Operator:\n"); printf("Title: %s \nPrice: %7.2lf \nNumber of Pages: %d\n", b1.title, b1.price, b1.pages); return 0; }
输出
运行此代码时,将产生以下输出:
With -> Operator: Title: Learn C Price: 650.50 Number of Pages: 325 With . Operator: Title: Learn C Price: 650.50 Number of Pages: 325
解引用嵌套结构体指针
尽管C语言使用箭头运算符 (→) 来访问结构体变量的元素,但任何内部结构体的元素都不能用它来访问。
只有外部结构体的元素才能用 → 运算符访问。对于后续的内部结构体元素,我们需要使用点(.)运算符。
示例
以下示例显示如何解引用嵌套结构体指针:
#include <stdio.h> #include <string.h> struct employee{ char name[10]; float salary; struct dob { int d, m, y; } d1; }; int main(){ struct employee e1 = {"Arjun", 45000, {12, 5, 1990}}; struct employee *ptr = &e1; printf("Name: %s\n", ptr->name); printf("Salary: %f\n", ptr->salary); printf("Date of Birth: %d-%d-%d\n", ptr->d1.d, ptr->d1.m, ptr->d1.y); return 0; }
输出
运行此代码时,将产生以下输出:
Name: Arjun Salary: 45000.000000 Date of Birth: 12-5-1990