当前位置: 首页 > news >正文

C语言9 指针

目录

指针的声明与初始化

指针运算

指针的加法和减法

指针的比较

指针与数组

通过指针访问数组元素

指针与多维数组

声明指向多维数组的指针

访问多维数组元素

指针数组和数组指针

指针数组

数组指针

字符指针

字符串的定义和字符指针

直接使用字符指针初始化字符串

void指针

void指针的声明与使用

const修饰指针

修饰指针指向的内容

修饰指针本身

同时修饰指针和指针指向的内容

多级指针

二级指针

多级指针的使用

指向函数的指针

指针函数

指针传递

指针与动态内存分配

函数指针

回调函数


指针是一个变量,它的值是另一个变量的地址。它通过存储内存地址来间接访问变量。

指针的声明与初始化

指针的声明格式为:

类型 *指针名;

例如:

int *ptr; // 声明一个指向int类型的指针

指针的初始化可以通过取地址运算符&来完成:

int var = 10;
int *ptr = &var; // ptr现在指向变量var的地址

此时,ptr存储的是var的地址,而不是var的值。要访问var的值,可以使用解引用运算符*

printf("%d\n", *ptr); // 输出10

指针运算

指针运算包括指针的加法和减法,这些运算在数组遍历和指针偏移中非常有用。

指针的加法和减法

指针加法和减法的本质是以指针所指向数据类型的大小为单位进行的。例如,对于int类型指针,每次加1实际上是加上sizeof(int)个字节。

int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr指向数组的第一个元素ptr++; // ptr现在指向数组的第二个元素
printf("%d\n", *ptr); // 输出20ptr--; // ptr现在指向数组的第一个元素
printf("%d\n", *ptr); // 输出10
指针的比较

指针还可以进行比较运算,常用于判断指针是否达到数组的末尾。

int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr;while (ptr < arr + 5) {printf("%d ", *ptr);ptr++;
}

指针与数组

数组名在很多情况下可以看作是一个指向数组第一个元素的指针。例如:

int arr[] = {10, 20, 30, 40, 50};
int *ptr = arr; // 等同于int *ptr = &arr[0];

这意味着可以使用指针来遍历数组:

for (int i = 0; i < 5; i++) {printf("%d ", *(ptr + i)); // 输出数组的每个元素
}
通过指针访问数组元素

可以使用指针加偏移量的方式访问数组元素:

printf("%d\n", *(arr + 2)); // 输出30,与arr[2]等价

同样,可以使用下标运算符[]来访问指针所指向的数组元素:

printf("%d\n", ptr[2]); // 输出30,与arr[2]等价

指针与多维数组

多维数组的指针处理稍微复杂一些。以二维数组为例:

int arr[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};
声明指向多维数组的指针

指向二维数组的指针的声明方式如下:

int (*ptr)[4] = arr; // ptr是一个指向包含4个int的数组的指针
访问多维数组元素

可以使用指针偏移来访问多维数组的元素:

printf("%d\n", *(*(ptr + 1) + 2)); // 输出7,相当于arr[1][2]

这表示:

  1. ptr + 1移动到第二行,即指向arr[1]
  2. *(ptr + 1)解引用得到第二行的数组,即arr[1]
  3. *(ptr + 1) + 2移动到第二行的第三个元素,即arr[1][2]
  4. 最终,*(*(ptr + 1) + 2)解引用得到该元素的值,即7。

指针数组和数组指针

指针数组和数组指针是两个容易混淆的概念。

指针数组

指针数组是一个数组,其元素是指针。例如:

int *arr[3];
int a = 1, b = 2, c = 3;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

例如,可以创建一个字符指针数组来存储多个字符串:

char *names[] = {"Alice", "Bob", "Charlie"};for (int i = 0; i < 3; i++) {printf("%s\n", names[i]);
}
数组指针

数组指针是一个指向数组的指针。例如:

int *arr[3];
int a = 1, b = 2, c = 3;
arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

字符指针

字符指针用于指向字符类型数据,常用于处理字符串。

字符串的定义和字符指针

在C语言中,字符串是以'\0'结尾的字符数组。字符指针可以指向字符串的第一个字符:

char str[] = "Hello, world!";
char *ptr = str; // ptr指向字符串的第一个字符

通过字符指针可以访问字符串中的各个字符:

while (*ptr != '\0') {printf("%c", *ptr);ptr++;
}
直接使用字符指针初始化字符串

可以直接使用字符指针指向字符串常量:

char *ptr = "Hello, world!";

需要注意的是,字符串常量是存储在只读内存中的,不能通过指针修改其内容:

char *ptr = "Hello, world!";
ptr[0] = 'h'; // 未定义行为,可能导致程序崩溃

void指针

void指针是一种通用指针类型,可以指向任何类型的数据,但不能直接解引用。需要先进行类型转换。

void指针的声明与使用
void *ptr;
int a = 10;
ptr = &a; // void指针指向int类型的变量// 需要进行类型转换后才能解引用
printf("%d\n", *(int *)ptr);

const修饰指针

const可以修饰指针,使指针或指针指向的内容不可修改。

修饰指针指向的内容
int a = 10;
const int *ptr = &a; // ptr指向的内容不可修改
// *ptr = 20; // 错误:尝试修改只读变量
ptr = &b; // 可以修改指针本身

本身

修饰指针本身
int a = 10;
int b = 20;
int *const ptr = &a; // ptr本身不可修改
*ptr = 20; // 可以修改指针指向的内容
// ptr = &b; // 错误:尝试修改const指针
同时修饰指针和指针指向的内容
int a = 10;
const int *const ptr = &a; // ptr本身和ptr指向的内容都不可修改
// *ptr = 20; // 错误:尝试修改只读变量
// ptr = &b; // 错误:尝试修改const指针

多级指针

多级指针是指指向指针的指针。它们可以用于间接访问变量,常用于处理复杂数据结构。

二级指针

二级指针是指向指针的指针:

int a = 10;
int *ptr = &a;
int **pptr = &ptr; // 二级指针指向一级指针printf("%d\n", **pptr); // 输出10,通过二级指针间接访问变量a
多级指针的使用

多级指针在处理动态内存分配和多维数组时非常有用:

int rows = 3, cols = 4;
int **matrix = malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++) {matrix[i] = malloc(cols * sizeof(int));
}// 使用matrix
for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {matrix[i][j] = i * cols + j;}
}// 释放matrix
for (int i = 0; i < rows; i++) {free(matrix[i]);
}
free(matrix);
指向函数的指针

指针不仅可以指向变量,还可以指向函数。函数指针用于实现回调函数和动态函数调用。

int add(int a, int b) {return a + b;
}int (*func_ptr)(int, int) = add; // 声明并初始化函数指针printf("%d\n", func_ptr(2, 3)); // 输出5,通过函数指针调用函数

指针函数

指针函数是指返回指针的函数。它在需要返回动态分配的内存块或者其他指针类型数据时非常有用。

示例
int* createArray(int size) {int *arr = malloc(size * sizeof(int));for (int i = 0; i < size; i++) {arr[i] = i;}return arr;
}int main() {int *array = createArray(5);for (int i = 0; i < 5; i++) {printf("%d ", array[i]);}free(array); // 记得释放内存return 0;
}

指针传递

在函数调用时传递指针,可以实现对原数据的修改。这是C语言实现传引用的方式。

示例
void increment(int *num) {(*num)++;
}int main() {int a = 5;increment(&a);printf("%d\n", a); // 输出6return 0;
}

指针与动态内存分配

C语言中使用malloccallocrealloc进行动态内存分配,使用free释放内存。

示例
int main() {int *arr = malloc(5 * sizeof(int));if (arr == NULL) {printf("Memory allocation failed");return 1;}for (int i = 0; i < 5; i++) {arr[i] = i * i;}for (int i = 0; i < 5; i++) {printf("%d ", arr[i]);}free(arr); // 释放内存return 0;
}

函数指针

函数指针是指向函数的指针,可以用于实现回调函数和动态函数调用。

示例
int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int main() {int (*operation)(int, int);operation = add;printf("Add: %d\n", operation(5, 3)); // 输出8operation = subtract;printf("Subtract: %d\n", operation(5, 3)); // 输出2return 0;
}

回调函数

回调函数是一种通过函数指针调用的函数,常用于事件驱动编程和异步编程。

示例
void processArray(int *arr, int size, void (*process)(int *))

 

相关文章:

C语言9 指针

目录 指针的声明与初始化 指针运算 指针的加法和减法 指针的比较 指针与数组 通过指针访问数组元素 指针与多维数组 声明指向多维数组的指针 访问多维数组元素 指针数组和数组指针 指针数组 数组指针 字符指针 字符串的定义和字符指针 直接使用字符指针初始化字…...

Floyd判圈算法——寻找重复数(C++)

287. 寻找重复数 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 &#xff0c;返…...

面试题目分享

学习目标&#xff1a; 从面试了解自己的不足。 学习内容&#xff1a; 1.你会什么语言&#xff1f; 我该如何回答&#xff0c;我会java&#xff0c;c&#xff0c;c等&#xff0c;在工作中我会用到合适的语言。 牛逼吹的大话 尊敬的面试官&#xff0c;我精通Java和Python&…...

Solana开发之Anchor框架

文章目录 Solana开发之Anchor框架一、什么是Anchor二、安装和使用1. 安装rust2. 安装Solana下载预构建的二进制文件 3. 使用 Anchor 版本管理器 &#xff08;avm&#xff09; 进行安装&#xff08;推荐&#xff09; 四、Anchor 核心原理Anchor 程序由三部分组成程序的 ID 从哪里…...

界面组件Kendo UI for React 2024 Q2亮点 - 生成式AI集成、设计系统增强

随着最新的2024年第二季度发布&#xff0c;Kendo UI for React为应用程序开发设定了标准&#xff0c;包括生成式AI集成、增强的设计系统功能和可访问的数据可视化。新的2024年第二季度版本为应用程序界面提供了人工智能(AI)提示&#xff0c;从设计到代码的生产力增强、可访问性…...

python输出/sys/class/power_supply/BAT0/电池各项内容

读取 /sys/class/power_supply/BAT0/ 目录下的所有相关文件,并输出其内容: import os# 定义电池信息文件的路径 battery_path = "/sys/class/power_supply/BAT0/"# 读取文件内容的函数 def read_battery_info(file_name):try:with open(os.path.join(battery_path…...

HDFS体系架构文件写入/下载流程

HDFS体系架构 HDFS&#xff08;Hadoop Distributed File System&#xff0c;Hadoop分布式文件系统&#xff09;是Hadoop项目中的一个核心组件&#xff0c;旨在以高容错、高吞吐量来处理大规模数据集。它的体系架构由以下几个主要部分组成&#xff1a;Client&#xff0c;NameNo…...

大模型之战进入新赛季,开始卷应用

最近一段时间&#xff0c;国产大模型Kimi彻底火了&#xff0c;而这波爆火&#xff0c;某种意义上也展示了一个问题&#xff0c;即大模型的落地场景可能比技术比拼&#xff0c;更重要。 国产大模型Kimi突然爆火&#xff0c;与Kimi相关的产业链甚至被冠上“Kimi概念股”之名&…...

MySQL8.4.0 LTS安装教程 【小白轻松上手2024年最新长期支持版本MySQL手把手保姆级Windows超详细图文安装教程】

MySQL8.4.0 LTS安装教程 【小白轻松上手2024年最新长期支持版本MySQL手把手保姆级Windows超详细图文安装教程】 MySQL8.4.0前言&#xff08;版本说明&#xff09;官网下载MySQL1.访问MySQL官网2. 打开MySQL官网下载页面3. 选择下载类型Select Version【MySQL版本号】Select Ope…...

Linux 例题及详解

1.&#xff08;yum&#xff09;以下描述正确的是 A.在Centos中可以使用yum install 命令安装软件包 B.在Centos中可以使用yum uninstall 命令卸载软件包 C.在Centos中可以使用yum list 查看所有可安装软件包 D.在Centos中可以使用yum show查看所有可安装软件包 选项A、C是正确…...

爆款文案管理系统设计

设计一个爆款文案管理系统&#xff0c;目标是帮助营销团队高效地创建、管理并分析吸引人的文案&#xff0c;以提升产品或服务的市场吸引力和销售转化率。以下是一些关键功能和设计考量点&#xff1a; 1. 用户友好界面 简洁直观的界面&#xff1a;确保系统界面清晰&#xff0c…...

FPGA-Verilog-Vivado-软件使用

这里写目录标题 1 软件配置2 FPGA-7000使用2.1 运行启动方式 1 软件配置 编辑器绑定为Vscode&#xff0c;粘贴VS code运行文件的目录&#xff0c;后缀参数保持不变&#xff1a; 如&#xff1a; D:/Users/xdwu/AppData/Local/Programs/Microsoft VS Code/Code.exe [file name]…...

Ambari Hive 创建函数无权限

作者&#xff1a;櫰木 1、创建udf函数 参考文档&#xff1a;https://blog.csdn.net/helloxiaozhe/article/details/102498567 如果已经编写好&#xff0c;请使用自己的。如果没有请参考以上链接进行udf函数编写。 2、创建函数遇到的问题 由于集群开启了kerberos&#xff0…...

ARM GEC6818 LCD绘图 实心圆 三角形 五角星 任意区域矩形以及旗帜

要在ARM上实现LCD绘图&#xff0c;可以按照以下步骤进行&#xff1a; 硬件初始化&#xff1a;初始化LCD控制器和相关引脚&#xff0c;配置时钟、分辨率和颜色深度等。 内存映射&#xff1a;将LCD显示区域映射到ARM的内存地址空间中&#xff0c;可以通过ARM的内存映射机制来实现…...

Sentinel-1 Level 1数据处理的详细算法定义(三)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程&#xff0c;以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下&…...

一款永久免费的内网穿透工具——巴比达

近期&#xff0c;一款名为巴比达的内网穿透工具凭借其永久免费的特性&#xff0c;以及卓越的性能与安全性&#xff0c;引起了我的关注。本文将深入探讨巴比达如何通过其独创的技术方案&#xff0c;达到企业级数据通信要求。 WanGooe Tunnel协议 首先&#xff0c;巴比达的核心竞…...

翻译|解开LLMs的神秘面纱:他们怎么能做没有受过训练的事情?

大语言模型&#xff08;LLMs&#xff09;通过将深度学习技术与强大的计算资源结合起来&#xff0c;正在彻底改变我们与软件互动的方式。 虽然这项技术令人兴奋&#xff0c;但许多人也担忧LLMs可能生成虚假的、过时的或有问题的信息&#xff0c;他们有时甚至会产生令人信服的幻…...

代码随想录-DAY⑦-字符串——leetcode 344 | 541 | 151

344 思路 没啥好说的&#xff0c; 双指针头尾交换&#xff0c; 相遇结束。 时间复杂度&#xff1a;O(n) 空间复杂度&#xff1a;O(1) 代码 class Solution { public:void reverseString(vector<char>& s) {int left0, rights.size()-1;while(left<right){swa…...

JavaScript(7)——数组

JavaScript中数组的用法与Java差不多&#xff0c;但还是有一些区别 声明数组 语法: let 数组名 [数据1,数据2,数据...] let arr new Array(数据1,数据2,...数据n) 添加数据 数组.push()方法将一个或多个元素添加到数组末尾&#xff0c;并返回该数组新长度 <script>…...

Spark RDD优化

Spark RDD优化 一、分区优化二、持久化优化三、依赖优化四、共享变量优化五、提交模式与运行模式优化六、其他优化 一、分区优化 分区数调整&#xff1a;RDD的分区数可以通过repartition和coalesce方法进行调整。合理的分区数可以提高并行度&#xff0c;但过多的分区会增加管…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...