【C语言】指针(1)——指针简单介绍及指针相关运算
目录1.内存和地址2.指针变量和地址2.1取地址操作符2.2指针变量和解引用操作符2.2.1指针变量2.2.2如何理解 int * p 如何拆解指针类型2.2.3解引用操作符*2.2.4指针变量的大小3.指针变量类型的意义3.1指针-整数3.2void*4.const修饰指针4.1 const修饰变量4.2 const修饰指针变量5.指针运算5.1指针-指针5.2指针-指针5.3指针的关系运算6.野指针6.1野指针成因1.指针未初始化2.指针越界访问3.指针指向的空间释放6.2如何规避野指针6.2.1指针初始化6.2.2小心指针越界6.2.4避免返回局部变量的地址7.assert断言8.传值调用和传址调用1.内存和地址计算机中最小的单位是比特位bit可以用来存储1个二进制位1byte 8bit 1KB 1024byte 1MB 1024KB 1GB 1024MB 1TB 1024GB 1PB 1024TB内存单元编号 地址 指针计算机中的编址不是把每个字节的地址记录下来而是通过硬件设计完成的。地址总线32位机器有32根地址总线可以表示2^32种含义每种含义表示一个地址。2.指针变量和地址2.1取地址操作符在C语言中创建变量的本质就是向内存申请空间。%p可以用来打印地址使用取出地址单目操作符a取出的是a所占四个字节中较小的字节的地址#includestdio.h int main() { int a 0; // 为a申请4个字节的空间 int *p a; return 0; }2.2指针变量和解引用操作符2.2.1指针变量使用取地址操作符取出的地址是一个数值需要存储在指针变量中。上述代码中p是一个指针变量。指针变量也是变量是用来存放地址的存放在指针变量中的值会被理解为地址。指针地址指针变量存放地址的变量口语中的指针一般指指针变量2.2.2如何理解 int * p 如何拆解指针类型*说明p是一个指针变量int说明p指向的对象是int类型同样的若p指向的类型是char类型定义时要使用char*2.2.3解引用操作符*解作符*又叫间接访问操作符*p表示通过p存放的地址找到p指向的对象可以通过*p间接访问p指向的对象例如可以通过*p0将p指向的对象的值变为0*和是可以相抵消的*a a2.2.4指针变量的大小32位机器假设有32根地址总线每根地址总线的电信号转换成数字信号后都表示0或1如果将32根地址总线产生的二进制序列当做一个地址那么该地址就需要32个bit位进行存储即32位机器的地址变量的大大小为4个字节。同理64位机器中的地址变量的大小为8个字节指针变量的大小与其所指向的对象类型无关只要是指针变量在相同平台上的大小都是相同的。如图在x86即32位环境下各种类型的指针变量大小均为4字节在x64即64位环境下均为8字节。3.指针变量类型的意义既然在同一个平台下各种类型的指针变量的大小是相同的为什么还要有各种各样的指针类型呢因为指针类型决定了对指针进行解引用操作时有多大的权限。比如char*指针在解引用时只能访问一个字节int*指针解引用时可以访问4个字节。3.1指针-整数#includestdio.h int main() { int a 10; int* pa a; char* pc (char*) a; printf(pa %p\n, pa); printf(pa1 %p\n, pa1); printf(pc %p\n, pc); printf(pc1 %p\n, pc1); return 0; }运行结果可以看出当int*类型的pa进行1操作时地址由006FFC08变为006FFC0C向后移动了4个字节sizeof(int)而char*类型的pc1时由006FFC08变为006FFC09向后移动了1个字节sizeof(char)。这就是不同指针变量类型的差别。结论指针类型决定了指针向前或向后一步有多大字节。3.2void*在指针类型中有一种特殊类型是void*类型的可以理解为无具体类型的指针或泛型指针。这种指针可以用来接受各种类型的地址但是也有局限性void*类型的指针不能直接进行指针-整数和解引用的运算。一般情况下void*类型的指针使用在函数参数的部分用来接收不同数据类型的地址可以实现泛型编程的效果使一个函数可以处理多种类型的数据。4.const修饰指针4.1 const修饰变量const int a 10; // a具有了常属性不能被修改在c语言中虽然a不能被修改了但本质上还是变量常变量在c中const修饰的变量就是常量被const修饰的变量可以通过指针修改破坏规则4.2 const修饰指针变量//代码1 void test1() { int n 10; int m 20; int* p n; *p 20;//ok? p m; //ok? } void test2() { //代码2 int n 10; int m 20; const int* p n; *p 20;//报错 p m; //ok? } void test3() { int n 10; int m 20; int* const p n; *p 20; //ok? p m; //报错 } void test4() { int n 10; int m 20; int const* const p n; *p 20; //报错 p m; //报错 } int main() { //测试⽆const修饰的情况 test1(); //测试const放在*的左边情况 test2(); //测试const放在*的右边情况 test3(); //测试*的左右两边都有const test4(); return 0; }一般来说const可以放在*的左边也可以放在*的右边当const放在*左边修饰的是指针指向的内容确保指针指向的内容不能通过指针改变但指针变量内容本身可以改变。当const放在*右边修饰的是指针变量本身保证了指针变量本身的内容不能修改但是指针指向的内容可以通过指针改变。也可以同时放在*左边和右边表示指针指向的内容和指针变量本身均不能修改。5.指针运算指针运算有三种分别是1指针-指针2指针-指针3指针的关系运算5.1指针-指针因为数组在内存中是连续存放的所以只要知道第一个元素的地址就可以找到后面所有元素。Type * p;p1 -- 跳过 1*sizeof(type)pn -- 跳过 n*sizeof(type)#includestdio.h int main() { int arr[10] { 0,1,2,3,4,5,6,7,8,9 }; int* p arr[0]; int sz sizeof(arr) / sizeof(arr[0]); for (int i 0; i sz; i) { printf(%d\n, *(p i)); } return 0; }以上代码可用于输出数组元素5.2指针-指针|指针-指针| 两指针间的元素个数前提两指针指向同一块空间如指向同一个数组不存在指针指针无意义5.3指针的关系运算指针的关系运算实际上就是指针和指针比较大小可以用来判断指针是否指向数组内、6.野指针概念野指针就是指针指向的位置是不可知的随机的不正确的没有明确限制的6.1野指针成因1.指针未初始化指针变量未初始化默认为随机值2.指针越界访问eg.当指针指向的范围超出数组范围时就成为野指针3.指针指向的空间释放eg.函数结束后指针指向的变量被释放p成为野指针6.2如何规避野指针6.2.1指针初始化指针初始化有两种情况1.明确知道指针应该指向哪里初始化一个明确的地址2.暂时不知道指针应该指向哪里初始化为NULLNULL是C语言中定义的标识符常量值为0,0也是地址这个地址是无法使用的读写该地址会报错6.2.2小心指针越界一个程序向内存申请了多少空间通过指针也就只能访问那些空间不能超出访问范围超出了就是越界访问。6.2.3指针变量不再使用时及时置为NULL指针使用前检查有效性。不再使用某个指针时要将指针置为NULL使用指针前先判断指针是否为NULL6.2.4避免返回局部变量的地址7.assert断言assert.h头文件定义了宏assert()用于在运行时确保特定程序符合指定条件如果不符合就报错终止运行这个宏常被称为“断言”。assert(p) //判断p是否为空指针等价于assert(p!NULL)assert()宏接受一个表达式作为参数任意表达式。如果该表达式为真返回值非零assert()不会有任何反应程序继续运行如果该表达式为假返回值为零assert()就会报错在标准错误流stderr中写入一条错误信息显示错误的表达式及其所在的文件名及行号。使用assert()的好处1.可以自动标识文件和出问题的行号2.如果已经确保程序没有问题不再需要assert()断言就在#includeassert.h前定义一个宏NDEBUG。然后重新编译编译器就会自动禁用文件中的所有assert()语句。#define NDEBUG #includeassert.hassert()的缺点因为引入了外部的检查增加了程序的运行时间。在vs中Release版本直接将assert()优化掉了在linux版本中Release版本仍会起作用。8.传值调用和传址调用传值调用把变量本身传递给函数。实参传递给形参时形参会单独创建一份临时空间来接收实参对形参的修改不会影响实参。传址调用把变量的地址传递给函数。可以让函数和主调函数之间建立真正的联系在函数内部可以修改主调函数中的变量。如果函数中只是需要主调函数中的变量值进行运算可以采用传值调用如果函数内部要修改主调函数变量的值就要采用传址调用。完

相关新闻

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南

Spring Cloud Contract消息契约测试:AMQP、Kafka与JMS集成实战指南 【免费下载链接】spring-cloud-contract Support for Consumer Driven Contracts in Spring 项目地址: https://gitcode.com/gh_mirrors/sp/spring-cloud-contract 在分布式微服务架构中&am…

2026/7/23 10:15:08 阅读更多 →
题解:洛谷 B3927 [GESP202312 四级] 小杨的字典

题解:洛谷 B3927 [GESP202312 四级] 小杨的字典

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

2026/7/24 21:01:11 阅读更多 →
BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照

BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照

BabelDOC:终极智能PDF文档翻译工具,3步实现专业级双语对照 【免费下载链接】BabelDOC Yet Another Document Translator 项目地址: https://gitcode.com/GitHub_Trending/ba/BabelDOC 还在为技术文档翻译后的格式错乱而烦恼吗?BabelDO…

2026/7/24 21:02:30 阅读更多 →

最新新闻

DRA78x通信接口深度解析:从GP Timer到McASP的实战配置与避坑指南

DRA78x通信接口深度解析:从GP Timer到McASP的实战配置与避坑指南

1. 项目概述与核心价值在嵌入式系统开发,尤其是汽车电子和工业控制这类对实时性、可靠性要求极高的领域,选对一颗处理器只是第一步,真正考验工程师功力的,往往是如何把芯片手册上那一页页密密麻麻的规格参数,变成稳定跑…

2026/7/26 13:57:21 阅读更多 →
深度学习数字识别:从MNIST到毕业设计实践

深度学习数字识别:从MNIST到毕业设计实践

1. 项目背景与核心价值 数字识别作为计算机视觉领域的经典问题,一直是深度学习入门的绝佳练手项目。这个毕设选题之所以值得推荐,关键在于它完美平衡了技术深度与实现可行性——既包含完整的深度学习流程(数据准备、模型设计、训练调优、部署…

2026/7/26 13:57:21 阅读更多 →
TI VDP视频电话开发平台:基于DM643 DSP的交钥匙方案解析

TI VDP视频电话开发平台:基于DM643 DSP的交钥匙方案解析

1. 项目概述:为什么我们需要一个“交钥匙”的视频电话开发平台?在嵌入式音视频通信这个领域摸爬滚打了十几年,我见过太多团队从零开始搭建一个视频电话系统时踩过的坑。从选型一颗合适的处理器,到搞定H.264编码的实时性&#xff0…

2026/7/26 13:57:21 阅读更多 →
DDR3 PCB信号完整性设计:从阻抗控制到时序匹配的工程实践

DDR3 PCB信号完整性设计:从阻抗控制到时序匹配的工程实践

1. 项目概述:为什么DDR3布线是硬件工程师的“必修课”?如果你做过高速数字电路设计,尤其是用过像TI AM389x这类高性能处理器,那你一定对DDR3内存接口的PCB设计又爱又恨。爱的是,它能让你的系统性能飞起;恨的…

2026/7/26 13:57:21 阅读更多 →
别再只看“像不像”!AI数字人产品价值评估必须关注的5个隐性指标(附可量化测量工具包)

别再只看“像不像”!AI数字人产品价值评估必须关注的5个隐性指标(附可量化测量工具包)

更多请点击: https://kaifayun.com 第一章:别再只看“像不像”!AI数字人产品价值评估必须关注的5个隐性指标(附可量化测量工具包) 当企业采购AI数字人时,90%的评估仍停留在“口型是否同步”“表情是否自然…

2026/7/26 13:57:21 阅读更多 →
如何快速抓取网页视频:猫抓浏览器嗅探插件的完整使用指南

如何快速抓取网页视频:猫抓浏览器嗅探插件的完整使用指南

如何快速抓取网页视频:猫抓浏览器嗅探插件的完整使用指南 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为无法下载网页视频而烦恼…

2026/7/26 13:56:21 阅读更多 →

日新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/26 0:00:31 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/26 0:00:31 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/26 0:00:31 阅读更多 →

月新闻