当前位置: 首页 > 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;但过多的分区会增加管…...

idea:解决Maven报错 Properties in parent definition are prohibited

在父pom文件中定义了 <dhversion>1.0-SNAPSHOT</dhversion> 在子模块中引用 <parent><groupId>com.douhuang</groupId><artifactId>douhuang-springcloud</artifactId><version>${dhversion}</version> </parent&…...

代理IP池:解析与应用

代理IP大家都了解不少了&#xff0c;代理IP池又是什么呢&#xff1f;下面简单介绍一下吧&#xff01; 1. 概述 代理IP池就是由多个代理IP地址组成的集合&#xff0c;用于实现更高效的网络访问和数据获取。这些IP地址通常来自不同的地理位置和网络提供商&#xff0c;经过动态管…...

MQTT是什么,物联网

写文思路&#xff1a; 以下从几个方面介绍MQTT&#xff0c;包括&#xff1a;MQTT是什么&#xff0c;MQTT和webSocket的结合&#xff0c;以及使用场景&#xff0c; 一、MQTT是什么 MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;是一种轻量级的发布/订阅消息…...

分布式训练

一、分布式计算 跟多GPU不同是&#xff1a;数据不是从主存拿的&#xff0c;是在分布式文件系统拿的&#xff0c;有多个工作站&#xff0c;工作站中有多个GPU&#xff0c;通过网络读取数据到GPU中&#xff0c;GPU通过网络接收到来自参数服务器的参数进行运算计算梯度&#xff0c…...

day10:04一文搞懂decode和decoding的区别

在Python 3中&#xff0c;decode()方法和decoding概念同样与字符串的编码和解码紧密相关&#xff0c;但它们的应用场景和上下文有所不同。下面通过案例来解释它们的关系和区别。 1. decode() 方法 decode()方法是字节串&#xff08;bytes&#xff09;类型的一个方法&#xff…...

MechMind结构光相机 采图SDK python调用

测试效果 Mech-Mind结构光相机 Mech Mind(梅卡曼德)的结构光相机,特别是Mech-Eye系列,是工业级的高精度3D相机,广泛应用于工业自动化、机器人导航、质量检测等多个领域。以下是对Mech Mind结构光相机的详细解析: 一、产品概述 Mech Mind的结构光相机,如Mech-Eye PRO,…...

“学习Pandas中时间序列的基本操作“

目录 # 开篇 1. 创建和操作时间序列对象 2. 时间序列数据的读取和存储 3. 时间序列数据的索引和切片 4. 时间序列数据的操作和转换 5. 时间序列数据的可视化 6. 处理时间序列中的缺失值 7. 时间序列数据的聚合和分组 8. 时间序列的时间区间和偏移量操作 示例代码&…...

常用知识碎片 分页组件的使用(arco-design组件库)

目录 分页组件使用 API 组件代码示例 使用思路&#xff1a; 前端示例代码 html script 后端示例代码 Controller Impl xml 总结 分页组件使用 使用Arco Design之前需要配置好搭建前端环境可以看我另外一篇文章&#xff1a; 手把手教你 创建Vue项目并引入Arco Desi…...

WPF 制作一个文字漂浮提示框

WPF好像没有自带的文字提示漂浮&#xff0c;我们可以定制一个。 效果如下&#xff1a; xaml xaml如下&#xff1a; <Window x:Class"GroupServer.MsgTip"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://sc…...

Node.js_fs模块

文件删除 文件重命名和移动&#xff08;本质都是修改路径&#xff09; 文件夹操作 创建文件夹(mkdir) 读取文件夹(readdir) &#xff08;打印出来是该文件夹下名称的数组形式&#xff09; 读取当前的文件夹(readdir) 删除文件夹 &#xff08;rmdir&#xff09; 查看资源状态…...

乡村文化建设网站栏目设置/企业网站建设公司

本文章是❤️力扣 (LeetCode)❤️的内容&#xff0c;该专栏还有多篇优质内容在等待你观看&#xff0c;现在点击右上角点击这个————&#x1f680;订阅专栏&#x1f680; &#x1f506;坚持刷算法 &#x1f48e;每天进步一点点 &#x1f680;冲冲冲冲冲冲冲冲冲冲 &#x1f4…...

喀什网站建设公司/一键生成原创文案

Processing入门简介 http://blog.csdn.net/mysunnytime/article/details/16104723 Processing官方教程 https://processing.org/tutorials/gettingstarted/ Processing程序中重写了两个函数&#xff1a;setup()和draw()。 setup()是在程序开始时调用的函数&#xff0c;只执…...

网站建设方案封面/湘潭网页设计

Asciidoc中的“”号可以在文中任意位置存在&#xff0c;而成对的""号会对其中间的文字起到着色的效果&#xff0c;比如以下的正文&#xff1a; - 熟悉C语言&#xff0c;熟悉STL并了解对象模型,熟悉c0x常用特性&#xff0c;了解Qt基础 转化之后会出现这样的显示效果&a…...

做点阵纸的网站/佛山百度网站快速排名

文章转载自 开源中国社区 http://www.oschina.net近日官方公布的“2018微信年度数据报告”在朋友圈中刷屏&#xff0c;微信在其报告中总结了不同年龄段用户的部分画像&#xff0c;其中有两点引起了网友的质疑。首先是报告指出了 55 岁以上的用户习惯在晚餐后与子女进行视频通话…...

wordpress theme/优化关键词的方法正确的是

题目 给定一个排序链表&#xff0c;删除所有重复的元素&#xff0c;使得每个元素只出现一次。 示例 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3 思路 解决删除重复问题的一个有效的思路就是双指针法&#x…...

招商网站建设解决方案/怎样在百度打广告

背景 java9的一再推迟发布,似乎让我们恍然想起离发布java8已经过去了三年之久,java8应该算的上java语言在历代版本中变化最大的一个版本了,最大的新特性应该算得上是增加了lambda表达式,借助lambda表达式,我们可以编写出性能更好,可读性更强的代码,更重要的,它给我们带来了一种…...