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

【理解指针(二)】

文章目录

  • 一、指针的运算
    • (1)指针加整数
    • (2)指针减指针(指针关系运算)
  • 二、野指针
    • (1)野指针的成因
      • (1.1)指针未初始化
      • (1.2)指针的越界访问
      • (1.3)指针指向的空间释放
  • (2)如何避免野指针
      • (2.1)指针需要初始化
      • (2.2)指针变量不再使用时,及时置NULL,指针使用之前检查有效性
  • 三、 strlen的模拟实现
  • 四、总结

一、指针的运算

(1)指针加整数

例子,我们打印一组数字:

#include<stdio.h>
int main()
{int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };int* pa = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", *(pa + i));}return 0;
}

在这里插入图片描述

这里的pa + i就是指针变量加上一个整数,pa + i是地址,*是对这个地址的解引用。

(2)指针减指针(指针关系运算)

#include<stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10};int* pa = &arr[0];printf("%d ", &arr[9] - pa);return 0;
}

在这里插入图片描述
上面的代码我们也可以用指针关系运算来写:(这里我们需要用到循环)

#include<stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);while (pa < arr+sz){printf("%d ", *pa);pa++;}return 0;
}

这里的pa < arr+sz是指针的比较,pa就是第一个元素开始的地址,而arr+sz就是最后一个元素结束的地址:

这里的&arr[9] - pa也可以写成&arr[9]-&arr[0],而得到的结果是 9 。由此我们可以得到一个结论:
指针的关系运算,得到的是指针和指针之间元素的个数。

二、野指针

(1)野指针的成因

(1.1)指针未初始化

示范一个错误例子:

#include<stdio.h>int main()
{int* pa;*pa = 1;printf("%d ", *pa);return 0;
}

在这里插入图片描述

局部变量指针未初始化,默认为随机值。

(1.2)指针的越界访问

#include<stdio.h>
int main()
{int arr[10] = { 0 };int* pa = &arr[0];for (int i = 0; i <= 11; i++){*(pa++) = i;printf("%d ", *pa);}return 0;
}

指针指向的范围超出数组arr的范围,pa就是野指针(指针指向的范围有11个,而数组arr的范围只有10个)

在这里插入图片描述

(1.3)指针指向的空间释放

#include<stdio.h>
int Print()
{int a = 90;return &a;
}
int main()
{int* pa = Print();printf("%d ", *pa);return 0;
}

我们写一个函数,将a赋值为90,然后把a的空间返回到主函数中,*pa可以接受到a的地址,但是出了Print()函数,空间就被回收了,此时*pa带着地址去访问该空间,不会得到任何数字,这就是空间的释放。

(2)如何避免野指针

(2.1)指针需要初始化

  • 如果我们明确知道指针指向哪里就直接赋值地址:
#include<stdio.h>
int main()
{int a = 20;int* pa = &a;return 0;
}

这里前面就是知道pa指针指向的是a的地址,所以我们直接:int* pa = &a

  • 如果我们不知道指针应该指向哪里,可以给指针赋值NULL。NULL 是C语⾔中定义的⼀个标识符常量,值是0,0也是地址,这个地址是⽆法使⽤的,读写该地址会报错。
#include<stdio.h>
int main()
{int* p = NULL;*p = 20;          //errprintf("%d ", *p);return 0;
}

小心指针的越界:

⼀个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问。(可以见上面的(1.2))

(2.2)指针变量不再使用时,及时置NULL,指针使用之前检查有效性

#include<stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* pa = &arr[0];for (int i = 0; i < 10; i++){*(pa++) = i;}pa= NULL;pa = &arr[0];if (pa != NULL){for (int i = 0; i < 10; i++){printf("%d ", *(pa + i));}}return 0;
}

*(pa++) = i;循环结束后,pa是超出了arr的范围的,此时可以把pa重置;当我们要重新用到pa时,可以让pa重新获得地址,重新获得地址后,我们需要判断pa是不是空指针,以确保代码的安全性。

  • 避免返回局部变量的地址(可见(1.3))

三、 strlen的模拟实现

库函数strlen的功能是求字符串长度,统计的是字符串中 \0 之前的字符的个数。

如果要模拟实现只要从起始地址开始向后逐个字符的遍历,只要不是 \0 字符,计数器就+1,这样直到 \0 就停止。

#include<stdio.h>
#include<string.h>
int my_strlen(char* pc)
{int count = 0;while (*pc != '\0'){count++;pc++;}return count;
}
int main()
{char arr[] = { "abcdf" };int len = my_strlen(arr);printf("%d ", len);return 0;
}

上面的代码,我们可以发现有很多的不足之处,不可以确保代码完全的安全性:

  1. 如果用户不小心把数组传成了空指针
    在这里插入图片描述

  2. int是有符号的整形,它可以为负数,但是我们统计数字不可能是负数

  3. char *pc只是用于遍历的,不能对*pc进行修改
    在这里插入图片描述
    所以最后的代码应该改为:

#include<assert.h>
#include<stdio.h>
#include<string.h>
size_t my_strlen( const char* pc)
{assert(pc != NULL);size_t count = 0;while (*pc != '\0'){count++;pc++;}return count;
}
int main()
{char arr[] = { "abcdf" };size_t len = my_strlen(arr);printf("%zd ", len);return 0;
}

四、总结

指针需要理解的东西有很多,希望大家可以自己慢慢去消化,指针这一章的内容还没有结束哟,希望与大家下一次再见。ԅ(¯ㅂ¯ԅ)

在这里插入图片描述

相关文章:

【理解指针(二)】

文章目录 一、指针的运算&#xff08;1&#xff09;指针加整数&#xff08;2&#xff09;指针减指针&#xff08;指针关系运算&#xff09; 二、野指针&#xff08;1&#xff09;野指针的成因&#xff08;1.1&#xff09;指针未初始化&#xff08;1.2&#xff09;指针的越界访问…...

使用AI纠正文章

我写了一段关于哲学自学的读书笔记&#xff0c;处于好奇的目的&#xff0c;让AI帮我纠正语法和逻辑。我的原文如下&#xff1a; 泰勒斯第一次提出了水是万物本源的说法&#xff0c;对于泰勒斯为什么提出这样的观点&#xff0c;或者是这样的观点是怎么来的&#xff0c;我们无从所…...

拼多多API批量获取商品详情信息

随着电子商务的蓬勃发展&#xff0c;淘宝作为中国最大的在线购物平台之一&#xff0c;每天需要处理海量的商品上架和交易。为了提高工作效率&#xff0c;自动化上架商品和批量获取商品详情信息成为了许多商家和开发者的迫切需求。本文将详细介绍淘宝的API接口及其相关技术&…...

杨辉三角(C语言)

杨辉三角 一.什么是杨辉三角 一.什么是杨辉三角 每个数等于它上方两数之和。 每行数字左右对称&#xff0c;由1开始逐渐变大。 第n行的数字有n项。 前n行共[(1n)n]/2 个数。 … 当前行的数上一行的数上一行的前一列的数 void yanghuisanjian(int arr[][20], int n) {for (int i…...

宏任务与微任务:JavaScript异步编程的秘密

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

vant van-field 密码输入框小程序里隐藏、显示密码bug总结

老规矩先上效果图: vant 输入框组件 密码的隐藏与显示功能&#xff1a; 注: 用password属性控制密码的显示与隐藏 不要用type属性&#xff0c;type属性在真机上有时会没有效果 1、当然如果只用typepassword 不需要切换显示、隐藏也可以使用。 2、如果用到了密码的显示与…...

代理ip应用场景

代理IP是一种网络技术&#xff0c;它允许用户通过中间来访问互联网资源&#xff0c;隐藏真实的IP地址代理IP的应用场景非常泛&#xff0c;以下是一些常见的应用场景&#xff1a; 1 隐私保护&#xff1a;使用代理IP可以隐藏用户的真实IP地址&#xff0c;保护个人隐私。在浏览网…...

C/C++指针详解

接下来我们来介绍一下什么是指针&#xff1f; 指针其实就是元素存放地址&#xff0c;更加形象的比喻&#xff1a;在酒店中如果你想要去注必须去付费不然不能住&#xff0c;在计算机也同样如此&#xff08;但是不需要付费哦&#xff09;每当我们使用一个变量或其他需要申请空间…...

实验一:华为VRP系统的基本操作

1.1实验介绍 1.1.1关于本实验 本实验通过配置华为设备&#xff0c;了解并熟悉华为VRP系统的基本操作 1.1.2实验目的 理解命令行视图的含义以及进入离开命令行视图的方法 掌握一些常见的命令 掌握命令行在线帮助的方法 掌握如何撤销命令 掌握如何使用命令快捷键 1.1.3实验组网 …...

ChatGPT发不出消息?GPT发不出消息怎么办?

前言 今天发现&#xff0c;很多人的ChatGPT无法发送信息&#xff0c;我就登陆看一下自己的GPT的情况&#xff0c;结果还真的无法发送消息&#xff0c;ChatGPT 无法发送消息&#xff0c;但是能查看历史的对话&#xff0c;不过通过下面的方法解决了。 第一时间先打开官方的网站&a…...

【论文笔记】Language Models are Few-Shot Learners

Language Models are Few-Shot Learners 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意力机制、残差、Layernorm&#xff09;&a…...

解决:Glide 在回调中再次加载图片报错

一、问题说明 Glide 加载图片时监听了回调&#xff0c;并在失败时再次加载其它图片后报错。 代码&#xff1a; Glide.with(mContext).load(imgTeacher).listener(new RequestListener<Drawable>() {Overridepublic boolean onLoadFailed(Nullable GlideException e, O…...

Java学习笔记之IDEA的安装与下载以及相关配置

1 IDEA概述 ​IDEA全称IntelliJ IDEA&#xff0c;是用于Java语言开发的集成环境&#xff0c;它是业界公认的目前用于Java程序开发最好的工具。 集成环境&#xff1a; ​把代码编写&#xff0c;编译&#xff0c;执行&#xff0c;调试等多种功能综合到一起的开发工具。 2 IDEA…...

【共享内存】System V共享内存{通信原理/相关接口/代码测试}

文章目录 1.初识共享内存1.0浅谈System V1.1什么是共享内存&#xff1f;1.2Linux-System V共享内存1.3图解共享内存1.4对共享内存的理解 2.创建共享内存2.1共享内存如何创建&#xff1f;2.2代码运行与测试2.3shm与pipe的区别2.4shm缺乏访问控制 3.代码理解shm3.1Log.hpp3.2comm…...

Web渗透测试流程

什么是渗透测试 渗透测试 (penetration test),是通过模拟恶意黑客的攻击方法&#xff0c;来评估计算机网络系统安全的一种评估方法。这个过程包括对系统的任何弱点、技术缺陷或漏洞的主动分析&#xff0c;这个分析是从一个攻击者可能存在的位置来进行的&#xff0c;并且从这个…...

探索机器学习的无限可能性:从初学者到专家的旅程

探索机器学习的无限可能性&#xff1a;从初学者到专家的旅程 在当今数字时代&#xff0c;机器学习无疑是最引人注目的技术之一。它已经深入到我们生活的方方面面&#xff0c;从个性化推荐到自动驾驶汽车&#xff0c;再到医疗诊断和金融预测。但是&#xff0c;即使我们已经见证…...

【python】六个常见爬虫案例【附源码】

大家好&#xff0c;我是博主英杰&#xff0c;整理了几个常见的爬虫案例&#xff0c;分享给大家&#xff0c;适合小白学习 一、爬取豆瓣电影排行榜Top250存储到Excel文件 近年来&#xff0c;Python在数据爬取和处理方面的应用越来越广泛。本文将介绍一个基于Python的爬虫程序&a…...

Java零基础-多维数组

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一个人虽可以走的更快&#xff0c;但一群人可以走的更远。 我是一名后…...

Linux网络套接字之UDP网络程序

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 实现一个简单的对话发消息的功能&#xff01; 目录…...

Apache POI 解析和处理Excel

摘要&#xff1a;由于开发需要批量导入Excel中的数据&#xff0c;使用了Apache POI库&#xff0c;记录下使用过程 1. 背景 Java 中操作 Excel 文件的库常用的有Apache POI 和阿里巴巴的 EasyExcel 。Apache POI 是一个功能比较全面的 Java 库&#xff0c;适合处理复杂的 Offi…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...