C语言教程(十四):C 语言指针详解
一、指针的基本概念
指针是一个变量,其值为另一个变量的内存地址。简单来说,指针指向了内存中的某个位置,通过指针可以间接访问该位置存储的数据。指针的使用可以让程序更加高效地处理数据,特别是在处理数组、动态内存分配等方面。
二、指针的定义和初始化
2.1 指针的定义
定义指针变量的语法格式为:数据类型 *指针变量名;
数据类型:指定指针所指向的变量的数据类型,如 `int`、`float`、`char` 等。
指针变量名:是用户自定义的标识符,用于标识这个指针变量。
`*` :是指针声明符,用于表明这是一个指针变量。
例如,定义一个指向整数的指针:int *ptr;
2.2 指针的初始化
指针变量在使用之前最好进行初始化,否则它可能包含一个随机的内存地址,访问该地址可能会导致未定义行为。指针可以初始化为 `NULL` 或者某个变量的地址。
初始化为 `NULL`:`NULL` 是一个特殊的指针值,表示指针不指向任何有效的内存地址。int *ptr = NULL;
初始化为某个变量的地址:使用取地址运算符 `&` 来获取变量的地址,并将其赋值给指针。
#include <stdio.h>int main() {int num = 10;int *ptr = # // ptr 指向 num 的地址printf("num 的地址: %p\n", &num);printf("ptr 存储的地址: %p\n", ptr);return 0;
}
三、指针的解引用
解引用是指通过指针访问其所指向的内存位置的数据。使用解引用运算符 `*` 来实现。
#include <stdio.h>int main() {int num = 10;int *ptr = #printf("num 的值: %d\n", num);printf("通过指针访问 num 的值: %d\n", *ptr);*ptr = 20; // 通过指针修改 num 的值printf("修改后 num 的值: %d\n", num);return 0;
}
在上述代码中,`*ptr` 表示访问 `ptr` 所指向的内存位置的数据。可以通过 `*ptr` 来读取或修改该位置的数据。
四、指针与数组
4.1 数组名与指针的关系
在C语言中,数组名在大多数情况下会被隐式转换为指向数组第一个元素的指针。例如:
#include <stdio.h>int main() {int numbers[5] = {1, 2, 3, 4, 5};int *ptr = numbers; // numbers 被转换为指向第一个元素的指针printf("数组的第一个元素: %d\n", *ptr);return 0;
}
4.2 通过指针访问数组元素
可以使用指针的算术运算来访问数组元素。指针的算术运算包括指针的加法和减法。
#include <stdio.h>int main() {int numbers[5] = {1, 2, 3, 4, 5};int *ptr = numbers;for (int i = 0; i < 5; i++) {printf("%d ", *(ptr + i));}printf("\n");return 0;
}
在上述代码中,`ptr + i` 表示指向数组中第 `i` 个元素的指针,`*(ptr + i)` 表示访问该元素的值。
五、指针与函数
5.1 指针作为函数参数
将指针作为函数参数可以实现通过函数修改实参的值。这是因为传递的是实参的地址,函数可以直接访问和修改该地址所存储的数据。
#include <stdio.h>void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}int main() {int x = 10, y = 20;printf("交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);return 0;
}
在上述代码中,`swap` 函数接受两个指针作为参数,通过指针交换了两个变量的值。
5.2 指针作为函数返回值
函数可以返回一个指针,但需要注意返回的指针必须指向有效的内存地址。如果返回的是局部变量的地址,可能会导致未定义行为,因为局部变量在函数结束后会被销毁。
#include <stdio.h>int *getMax(int *arr, int size) {int *max = arr;for (int i = 1; i < size; i++) {if (*(arr + i) > *max) {max = arr + i;}}return max;
}int main() {int numbers[5] = {1, 3, 2, 5, 4};int *maxPtr = getMax(numbers, 5);printf("数组中的最大值: %d\n", *maxPtr);return 0;
}
在上述代码中,`getMax` 函数返回一个指向数组中最大值的指针。
六、动态内存分配
6.1 `malloc` 函数
`malloc` 函数用于在堆内存中分配指定大小的内存块。其原型为:void *malloc(size_t size);
`size` 是要分配的内存块的大小,单位是字节。
`malloc` 函数返回一个指向分配的内存块的指针,如果分配失败则返回 `NULL`。
#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = (int *)malloc(5 * sizeof(int));if (ptr == NULL) {printf("内存分配失败\n");return 1;}for (int i = 0; i < 5; i++) {ptr[i] = i + 1;}for (int i = 0; i < 5; i++) {printf("%d ", ptr[i]);}printf("\n");free(ptr); // 释放分配的内存return 0;
}
在上述代码中,使用 `malloc` 函数分配了一个可以存储 5 个整数的内存块,并对其进行初始化和访问,最后使用 `free` 函数释放了分配的内存。
6.2 `calloc` 函数
`calloc` 函数也用于在堆内存中分配内存块,与 `malloc` 不同的是,`calloc` 会将分配的内存块初始化为 0。其原型为:void *calloc(size_t num, size_t size);
`num` 是要分配的元素个数。
`size` 是每个元素的大小,单位是字节。
#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = (int *)malloc(3 * sizeof(int));if (ptr == NULL) {printf("内存分配失败\n");return 1;}for (int i = 0; i < 3; i++) {ptr[i] = i + 1;}ptr = (int *)realloc(ptr, 5 * sizeof(int));if (ptr == NULL) {printf("内存重新分配失败\n");return 1;}for (int i = 3; i < 5; i++) {ptr[i] = i + 1;}for (int i = 0; i < 5; i++) {printf("%d ", ptr[i]);}printf("\n");free(ptr);return 0;
}
七、指针的注意事项
空指针解引用:对 `NULL` 指针进行解引用会导致未定义行为,可能会使程序崩溃。在使用指针之前,最好检查其是否为 `NULL`。
野指针:野指针是指指向无效内存地址的指针,如指向已经释放的内存或未初始化的指针。使用野指针会导致未定义行为,要避免产生野指针。
内存泄漏:在使用动态内存分配函数(如 `malloc`、`calloc`、`realloc`)分配内存后,要记得使用 `free` 函数释放内存,否则会导致内存泄漏,使系统的可用内存逐渐减少。
相关文章:
C语言教程(十四):C 语言指针详解
一、指针的基本概念 指针是一个变量,其值为另一个变量的内存地址。简单来说,指针指向了内存中的某个位置,通过指针可以间接访问该位置存储的数据。指针的使用可以让程序更加高效地处理数据,特别是在处理数组、动态内存分配等方面。…...
2025年04月24日Github流行趋势
项目名称:markitdown 项目地址url:https://github.com/microsoft/markitdown项目语言:Python历史star数:53,351今日star数:822项目维护者:afourney, gagb, sugatoray, PetrAPConsulting, l-lumin项目简介&a…...
切割PDF使用python,库PyPDF2
使用 Python 将大型 PDF 文件分割成多个小文件 理解任务 将一个 170M 的 PDF 文件分割成多个 10M 左右的小文件。这在处理大型 PDF 文件时非常有用,例如: 减少单个文件的大小,方便传输或存储分别处理不同的文件部分提高 PDF 处理的效率 选…...
网络IP冲突的成因与解决方案
网络IP冲突的成因与解决方案 一、IP冲突的常见现象与危害二、IP冲突的常见原因三、6种实用解决方案四、预防IP冲突的4个最佳实践五、总结 前言 肝文不易,点个免费的赞和关注,有错误的地方请指出,看个人主页有惊喜。 作者:神的孩子…...
python版本得数独游戏
python版本得数独游戏 游戏说明: 游戏使用9x9数独棋盘,.表示可填写的空格 输入格式为行,列,数值(如3,5,7表示第3行第5列填7) 系统会自动检查以下内容: 输入格式是否正确 数字是否在1-9范围内 是否修改固定数字 是…...
64位系统上编译32位openh264 x264
在64位系统上要使用i386(32位库)的时候,有些是找不到apt可以安装的版本,所以需要手动编译安装,下面是openh264和x264的编译过程。 默认编译openh264 git clone https://github.com/cisco/openh264make ARCHi386 OSlinux PREFIX/lib/i386-li…...
加深对vector理解OJ题
17. 电话号码的字母组合 - 力扣(LeetCode) OJ(一)电话号码的字母组合 思路:这里以引用leetcode里面的一个大佬里面的图 1.这道题中,我们用递归的方法来写。 为了简洁展示,我们举例子”456“&am…...
协作开发攻略:Git全面使用指南 — 第三部分 特殊应用场景
协作开发攻略:Git全面使用指南 — 第三部分 特殊应用场景 Git 是一种分布式版本控制系统,用于跟踪文件和目录的变更。它能帮助开发者有效管理代码版本,支持多人协作开发,方便代码合并与冲突解决,广泛应用于软件开发领域…...
机器学习(9)——随机森林
文章目录 1. 随机森林的基本原理想2. 算法流程2.1. 数据采样(Bootstrap):2.2. 构建决策树:2.3. 聚合预测: 3. 随机森林的构建过程3.1. 数据集的随机抽样3.2. 决策树的训练3.3. 树的生长3.4. 多棵树的集成3.5. 输出预测…...
(第三篇)Springcloud之Ribbon负载均衡
一、简介 1、介绍 Spring Cloud Ribbon是Netflix发布的开源项目,是基于Netflix Ribbon实现的一套客户端负载均衡的工具。主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时&…...
Linux并发与竞争:从生活例子到内核实战
Linux并发与竞争:从生活例子到内核实战 一、并发与竞争:多车道公路的交通问题 想象一条四车道的高速公路(多核CPU),所有车辆(线程/进程)都想通过同一个收费站(共享资源)…...
【金仓数据库征文】——金仓数据库:国产数据库的卓越之选
目录 一、金仓数据库的核心技术优势 (一)强大的事务处理能力 (二)高度安全 (三)全面兼容与深度适配 (四)强大的扩展性 (五)智能便捷的工具 二、电信行…...
人脸识别考勤系统实现教程:基于Face-Recognition、OpenCV与SQLite
引言 随着人工智能技术的飞速发展,人脸识别技术已广泛应用于安防、金融、教育等多个领域。本文将带领大家利用Python的face-recognition库、OpenCV和SQLite数据库,从零开始构建一个具备异常报警功能的人脸识别考勤系统。该系统能够实时检测视频流中的人…...
Golang 闭包学习
引言 在平常的 Go 语言开发中,常常需要将一段函数逻辑封装起来,异步执行、作为回调传递,甚至保持某些运行时状态。此时,闭包成为一种非常自然的编程手段。它允许我们在函数内部“记住”外部作用域中的变量,从而实现变…...
Trae+DeepSeek学习Python开发MVC框架程序笔记(四):使用sqlite验收用户名和密码
继续通过Trae向DeepSeek发问并修改程序,实现程序运行时生成数据库,用户在系统登录页面输入用户名和密码后,控制器通过模型查询用户数据库表来验证用户名和密码,验证通过后显示登录成功页面,验证失败则显示登录失败页面…...
【mdlib】0 全面介绍 mdlib - Rust 实现的 Markdown 工具集
mdlib 是由开发者 bahdotsh 创建的一个多功能 Markdown 工具集合,包含两个主要组件:一个轻量级 Markdown 解析库和一个功能完善的个人 Wiki 系统。该项目完全采用 Rust 实现,兼具高性能与跨平台特性。 核心组件 Markdown 解析库 特性&#…...
使用Django REST Framework快速开发API接口
以下是使用 Django 和 Django REST Framework (DRF) 开发 API 接口的核心步骤,涵盖模型、迁移、序列化、视图、路由等关键环节: 前言 什么是DRF? Django REST Framework(DRF) 是基于Django的一个强大且灵活的工具包&…...
Vue3项目中 npm 依赖安装 --save 与 --save-dev 的区别解析
这两个命令的区别如下: bash npm install --save types/crypto-js # 安装到 dependencies(生产依赖) npm install --save-dev types/crypto-js # 安装到 devDependencies(开发依赖) 核心区别 依赖分类不同…...
开源模型应用落地-语音合成-MegaTTS3-零样本克隆与多语言生成的突破
一、前言 在人工智能技术飞速发展的今天,文本转语音(TTS)技术正以前所未有的速度改变着人机交互的方式。近日,字节跳动与浙江大学联合推出了一款名为MegaTTS3 的开源TTS模型,再次刷新了行业对高质量语音合成的认知。作为一款轻量化设计的模型,MegaTTS3以仅0.45亿参数 的规…...
connection.cursor() 与 models.objects.filter
在 Django 中操作数据库时,connection.cursor() 和 models.objects.filter 是两种不同的方式,各有特点和适用场景: models.objects.filter (ORM 方式) 特点: 基于 Django 的 ORM(对象关系映射)框架&am…...
深入浅出JavaScript常见设计模式:从原理到实战(1)
深入浅出JavaScript常见设计模式:从原理到实战(1) 设计模式是一种在特定情境下解决软件设计中常见问题的通用方案或模板。在特定的开发场景中使用特定的设计模式,可以提升代码质量,增强代码可读性和可维护性,提高团队开发效率&…...
RCE学习
一、远程代码执行漏洞 1. 远程代码执行的定义 定义:远程代码执行漏洞(Remote Code Execute,简称RCE)是指程序预留了执行命令或代码的接口并被黑客利用的漏洞。广义上也包括远程命令执行(Remote Command Execute&…...
Redis安装及入门应用
应用资料:https://download.csdn.net/download/ly1h1/90685065 1.获取文件,并在该文件下执行cmd 2.输入redis-server-lucifer.exe redis.windows.conf,即可运行redis 3.安装redis客户端软件 4.安装后运行客户端软件,输入链接地址…...
【棒球运动】户外运动安全技巧·棒球1号位
以棒球运动为例,在棒球这项结合力量、速度与策略的户外运动中,安全防护是保障运动表现的核心。以下是针对棒球特点的户外安全指南,涵盖装备、环境与行为规范三大维度: 一、场景化防护装备选择 击球场景 击球手需佩戴双重防护头盔…...
卸载rpm包
昨天了解了查询rpm包的流程和命令,那么今天了解一下删除rpm包的语法,那么话不多说,来看. 1.基本语法 rpm -e RPM包的名称 注:e erase擦除 2.案例 删除firefox软件包 :rpm -e firefox 3.细节讨论 1.如果其它软件包依赖于要卸载的软件包,卸载时…...
【AI提示词】艺人顾问
提示说明 专业艺人顾问,专注于为客户提供全面的艺术、娱乐和商业咨询服务,帮助他们在竞争激烈的行业中树立品牌影响力,提升市场竞争力 提示词 # Role: 艺人顾问## Profile - language: 中文 - description: 专业艺人顾问,专注于…...
第七部分:向量数据库和索引策略
什么是矢量数据库? 简单来说,向量数据库是一种专门化的数据库,旨在优化存储和检索以高维向量形式表示的文本。 为什么这些数据库对RAG至关重要?因为向量表示能够在大规模文档库中进行高效的基于相似性的搜索,根据用户…...
26考研|数学分析:数项级数
数项级数这一章的开始,开启了新的关于“级数”这一新的概念体系的学习进程,此部分共包含四章的内容,分别为数项级数、函数项级数、幂级数以及傅里叶级数。这一章中,首先要掌握级数的相关概念与定义,重难点在于掌握判断…...
2025 年免费 Word 转 PDF 转换器有哪些?
我们列出了最好的 Word 到 PDF 转换器,以便轻松轻松地将 .doc 文件导出到 .pdf 而不会丢失原始格式。 尽管 Microsoft 365 包含一个 Word 版本,该版本可以将您正在处理的 .docx 文档无缝导出为 PDF 格式,但仍在使用旧版 Word 的人可能缺少此…...
【Spring Boot】深入解析:#{} 和 ${}
1.#{} 和 ${}的使用 1.1数据准备 1.1.1.MySQL数据准备 (1)创建数据库: CREATE DATABASE mybatis_study DEFAULT CHARACTER SET utf8mb4;(2)使用数据库 -- 使⽤数据数据 USE mybatis_study;(3ÿ…...
SpringMVC知识体系
SpringMVC 知识体系 1. SpringMVC 基础 MVC 设计模式 Model: 模型层,处理业务逻辑View: 视图层,负责界面展示Controller: 控制层,处理请求并协调模型和视图 核心组件 DispatcherServlet: 前端控制器HandlerMapping: 处理器映射Controller: …...
如何将 PDF 中的文本提取为 JSON 格式
一些 PDF 文件是“带标签”的,意味着它们包含关于文件结构的信息。这种结构作为元数据嵌入在 PDF 中,由一系列标签组成,用于标记诸如标题、段落、列表、表格和图像等元素。 这非常类似于 HTML,其中的文本包含在具有语义意义的元素…...
深度解析:基于Python的微信小程序自动化操作实现
引言 在当今数字化时代,自动化技术正在改变我们与软件交互的方式。本文将深入解析一个使用Python实现的微信小程序自动化操作脚本,该脚本能够自动识别屏幕上的特定图像并执行点击操作。这种技术在自动化测试、批量操作和效率工具开发中有着广泛的应用前…...
【网络安全】网络钓鱼的类型
1. 网络钓鱼简介 网络钓鱼是最常见的社会工程学类型之一,它是一种利用人为错误来获取私人信息、访问权限或贵重物品的操纵技术。之前,您学习了网络钓鱼是如何利用数字通信诱骗人们泄露敏感数据或部署恶意软件的。 有时,网络钓鱼攻击会伪装成…...
Python----深度学习(基于深度学习Pytroch线性回归和曲线回归)
一、引言 在当今数据驱动的时代,深度学习已成为解决复杂问题的有力工具。它广泛应用于图像识别、自然语言处理和预测分析等领域。回归分析是统计学的一种基础方法,用于描述变量之间的关系。通过回归模型,我们可以预测连续的数值输出…...
重构智能场景:艾博连携手智谱,共拓智能座舱AI应用新范式
2025年4月24日,智能座舱领域创新企业艾博连科技与国产大模型独角兽智谱,在上海国际车展艾博连会客厅签署合作协议。双方宣布将深度整合智谱在AI大模型领域的技术积淀与艾博连在汽车智能座舱场景的落地经验,共同推进下一代"有温度、懂需求…...
Streamlit从入门到精通:构建数据应用的利器
在数据科学与机器学习日益普及的今天,如何快速将模型部署为可交互的应用成为了许多数据科学家的重要任务。Streamlit,作为一个开源的Python库,专为数据科学家设计,能够帮助我们轻松构建美观且直观的Web应用。本文将从入门到精通&a…...
4.1.1 类的序列化与反序列化(XmlSerializer)
本文介绍XML序列化和反序列化操作 本例子中被序列化的类(Devices)中有一个List,其元素类型为:DigitalInputInfo. 序列化以及反序列化都很简单: 序列化:即把类的对象输出到文件中。 StreamWriter streamWriter new StreamWriter(filePath); …...
新增优惠券
文章目录 概要整体架构流程技术细节小结 概要 接口分析 一个基本的新增接口,按照Restful风格设计即可,关键是请求参数。之前表分析时已经详细介绍过这个页面及其中的字段,这里不再赘述。 需要特别注意的是,如果优惠券限定了使…...
Qt 处理 XML 数据
在 Qt 中,处理 XML 数据通常使用 Qt 提供的 QDomDocument、QXmlStreamReader 和 QXmlStreamWriter 类。这些类可以帮助你读取、修改和写入 XML 数据。 1. 使用 QDomDocument 处理 XML QDomDocument 提供了对 XML 文档的 DOM(Document Object Model&…...
STM32F407使用ESP8266实现阿里云OTA(下)
文章目录 前言一、函数分析1.get_bin()函数2.download_bin()函数3.串口1中断函数二、完整工程分析前言 从上一章中,我们已经成功连接阿里云并且成功拿到了升级包的下载地址,在本文我们将升级包下载下来并且存储到SD卡中,最终将程序写入FLASH中完成APP的跳转,至此我们的OTA…...
树型结构(知识点梳理及例题精讲)
大家好啊,这一集,我们来学习树型结构,请确保看完预习篇,再来看此篇哦 树型结构(预习课)-CSDN博客 话不多说,直接开讲 -------------------------------------------------------分割线-------…...
使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
使用HYPRE库并行装配IJ稀疏矩阵指南 HYPRE是一个流行的并行求解器库,特别适合大规模稀疏线性系统的求解。下面介绍如何并行装配IJ格式的稀疏矩阵,包括预先分配矩阵空间和循环使用。 1. 初始化矩阵 首先需要创建并初始化一个IJ矩阵: #incl…...
win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法
现象: 1. 当时新建运行的资源管理器的任务卡了或者原本资源管理器卡了 比如:当时在文本框中输入explorer 注:explorer.exe是Windows的文件资源管理器,它用于管理Windows的图形外壳,包括桌面和文件管理 按住CtrlAltEs…...
C语言编程--15.四数之和
题目: 给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复)&…...
从单机工具到协同平台:开源交互式模拟环境的技术演进之路
从单机工具到协同平台:开源交互式模拟环境的技术演进之路 一、引言:从“孤岛”到“生态”的模拟技术变革 二十年前,模拟软件如LAMMPS(分子动力学)、ANSYS(工程仿真)以单机版为主,用…...
Python函数与模块笔记
Python函数与模块笔记 目录 函数 无参函数带参函数变量作用域Lambda函数常用内置函数 模块与包 模块的定义与导入包的使用常用模块(keyword、random、sys、time) 一、函数 1. 无参函数 定义语法: def 函数名(): 代码块 return [表达式]…...
Jenkins:开启高效软件开发的魔法之门
一、Jenkins 是什么 Jenkins 是一款基于 Java 开发的开源持续集成工具,在软件开发流程中占据着举足轻重的地位。它的前身是 Hudson ,于 2004 年由 Sun 公司的 Kohsuke Kawaguchi 开发,2011 年因商标纠纷更名为 Jenkins。发展至今,…...
正则表达式学习指南
正则表达式学习指南 在编程的世界里,正则表达式(Regular Expressions,简称regex)是一门不可或缺的艺术,它赋予了开发者强大的文本处理能力,让看似复杂的字符串匹配和替换任务变得简单而高效。本文旨在为初…...
React-组件通信
1、父子组件通信 (1)父传子(props 传值) // 父组件 function App() {const name 张三return (<div className"App"><Son name{name} /></div>); }// 子组件 function Son(props) {return (<div…...