C语言指针(下)

前言:

上文我们已经学习了指针的基本概念内存单元地址的产生,以及指针和指针的类型。这时我们对指针已经有了一个初步的了解,接下来我们将继续深入的学习指针用法。

一. 野指针

 (一)概念:

野指针就是指针指向的位置使不可知的(随机的、不正确的、没有明确限制的)

int main()
{int* p;//p没有初始化就意味着没有明确的指向//一个局部变量不初始化的话,放的是随机值;//会初始化为一部内容,一般是0xcccccccc这样的值//这时它就会把0xcccccccc当作是它的地址//但这个地址所指向的空间不是它的//也就是说它使用的地址是一个非法的地址*p = 10;//非法访问内存了,这里的p就是野指针return 0;
}

(二)野指针成因

1. 指针未初始化(就是上面那种)  
2. 指针越界访问
int main()
{int arr[10] = { 0 };int* p = arr;for (int i = 0; i <= 10; i++){*p = i;p++;}//指针指到前面10个地址的时候还不是野指针//指针指到第10个地址后面的地址时就是野指针return 0;
}
3. 指针指向的空间释放 
int* test()
{int a = 0;return &a;//a会在这里取好一个地址然后返回去//这时*p的地址就是a所取的这个地址
}//但是一旦出了test()函数的时候,//a就会立即销毁这个地址,//也就是将地址还给了操作系统,//这时这个空间已经不属于a和p了,//但是p依然保存着这个地址,//所以p还能找到这个空间,//当p再往下执行的时候就是野指针。
int main()
{int* p = test();return 0;
}

(三)如何尽量避免野指针的出现

1.指针初始化

2.小心指针越界

3.避免返回局部变量

4.指针使用之前有效性的检查 

 二. 指针与数组

int main()
{int arr[10] = { 0 };//arr是首元素的地址int* p = arr;//通过指针来访问地址return 0;
}

三. 指针的运用

1. 指针+-整数

//例:给数组初始化
//法一:
#define n 5
int main()
{float arr[n];float* a;for (a = &arr[0]; a < &arr[n];){*a++ = 1;}return 0;
}
//法二:
#define n 10
int main()
{int arr[n] = { 0 };int* p = arr;for (int i = 0; i < n; i++){*p = 1;p++;}return 0;
}

补充:*a++ 与(*a)++的区别是:前者是给地址++;后者是给指针所指向的对象进行++,比如*a所指向的对象是0,那么(*a)++执行一次后*a所指向的对象就变为1了。

2. 指针-指针

 指针-指针得到绝对值的是指针和指针之间元素的个数,如下图

但不是所有的指针都能相减,只有指向同一块空间的两个指针相减才有意义。例如下面这种。

  

四. 二级指针

 二级指针是用来存放一级指针变量的地址

int main()
{int a = 10;int* pa = &a;//pa是一个一级指针变量int** pi = &pa;//pi是一个二级指针变量**pi = 20;return 0;
}

五. 指针数组

存放指针的数组其实指针数组,如下图。

使用指针数组模拟二维数组:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/295802.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java多线程技术四——定时器(备份)

1 定时器的使用 在JDK库中Timer类主要负责计划任务的功能&#xff0c;也就是在指定的时间开始执行某一个任务&#xff0c;Timer类的方法列表如下&#xff1a; Timer类的主要作用就是设置计划任务&#xff0c;封装任务的类却是TimerTask&#xff0c;该类的结构如下图 因为TimerT…

Michael Jordan:大模型在两个方向仍需“努力”丨智源专访

导读 回望过去的这一年&#xff0c;大模型的出现永远改变了当前的技术产业格局&#xff0c;却鲜少有人说起大模型真正的致命缺点。 “如果你问 ChatGPT&#xff0c;乌干达总统是谁&#xff1f;它会给出一个答案。但你问它对刚才说的话有多确定&#xff1f;它表示无法回答。”提…

手把手教你在飞书中搭建机器人

前言 大家好&#xff0c;我是潇潇雨声。飞书是一款在国内广受欢迎的企业内部管理和协同工具&#xff0c;同时也可以作为一个强大的个人知识管理工具。在本文中&#xff0c;我将帮助你迅速创建一个飞书对话机器人&#xff0c;并嵌入 chatGPT 的功能。这个机器人可以直接回答你的…

Ansible3

Templates 模块 Jinja模版架构&#xff0c;通过这个模版可以实现&#xff0c;往配置文件(模版文件)传参(python转义)把占位符参数传到配置文件中去 Jinja就是生产一个目标文本文件&#xff0c;然后传递变量需要配置文件&#xff08;web开发&#xff09; 创建文件 123 345 678…

【数据结构一】初始Java集合框架(前置知识)

Java中的数据结构 Java语言在设计之初有一个非常重要的理念便是&#xff1a;write once&#xff0c;run anywhere&#xff01;所以Java中的数据结构是已经被设计者封装好的了&#xff0c;我们只需要实例化出想使用的对象&#xff0c;便可以操作相应的数据结构了&#xff0c;本篇…

最小二乘法简介

最小二乘法简介 1、背景描述2、最小二乘法2.1、最小二乘准则2.2、最小二乘法 3、最小二乘法与线性回归3.1、最小二乘法与线性回归3.2、最小二乘法与最大似然估计 4、正态分布&#xff08;高斯分布&#xff09; 1、背景描述 在工程应用中&#xff0c;我们通常会用一组观测数据去…

Linux多线程:POSIX信号量,基于信号量的环形队列实现生产者消费者模型

目录 一、POSIX信号量1.1 初始化信号量1.2 销毁信号量1.3 等待信号量1.4 发布信号量1.5 基于环形队列的生产消费模型(用信号量控制生产者和消费者之间的同步互斥关系)1.5.1 makefile1.5.2 RingQueue.hpp1.5.3 Sem.hpp1.5.4 Task.hpp1.5.5 main.cc 二、信号量控制的环形队列原理…

Angular 11到升级到 Angular 16

日新月异&#xff0c;与时俱进… 随着Angular版本不断更新&#xff0c;再看所开发的项目版本仍然是Angular 11&#xff0c;于是准备升级 截止发博日最版本是 v17.1.0&#xff0c;考虑到稳定性因素决定升级到v16版本 一&#xff1a;查看 升级指南 二&#xff1a;按照指南&…

【Element】el-table 使用 el-table-infinite-scroll 插件实现滚动加载

虽然 el 官方提供了 Infinite Scroll 无限滚动 组件 但是却不支持 el-table 组件&#xff0c;这就很难受了&#xff0c;还好已经有大佬写好了插件&#xff0c;并且支持 element-plus/infinite-scroll 组件的所有选项。 el-table-infinite-scroll el-table-infinite-scroll 看…

「微服务模式」七种微服务反模式

什么是微服务 流行语经常为进化的概念提供背景&#xff0c;并且需要一个良好的“标签”来促进对话。微服务是一个新的“标签”&#xff0c;它定义了我个人一直在发现和使用的领域。文章和会议描述了一些事情&#xff0c;我慢慢意识到&#xff0c;过去几年我一直在发展自己的个人…

HarmonyOS的装饰器之BuilderParam 理解

BuilderParam 装饰器 使用时间&#xff1a;当定义了一个子组件&#xff0c;并且子组件的build()中有一个布局在不同的父组件&#xff0c;实现效果不一样的时候&#xff0c;可以在子组件中用这个BuilderParam装饰器&#xff0c; 在父组件用Builder 装饰器进行实现&#xff0c;然…

Netty-2-数据编解码

解析编解码支持的原理 以编码为例&#xff0c;要将对象序列化成字节流&#xff0c;你可以使用MessageToByteEncoder或MessageToMessageEncoder类。 这两个类都继承自ChannelOutboundHandlerAdapter适配器类&#xff0c;用于进行数据的转换。 其中&#xff0c;对于MessageToMe…