【C语言入门】由浅入深学习指针 【第二期】

news2025/7/19 7:25:55

 

目录

 1. 指针变量为什么要有类型?

2. 野指针

2.1 未初始化导致的野指针

2.2 指针越界导致的野指针

2.3 如何规避野指针 

3. 指针运算

3.1 指针加减整数

3.2 指针减指针

3.3 指针的关系运算

4. 二级指针

5. 指针数组

5.1 如何使用指针数组模拟二维数组

        上一期已经解释了指针和指针变量的区别以及含义,这一期我们来具体了解一下指针到底有什么作用。

 1. 指针变量为什么要有类型?

        我们知道指针变量的大小是根据所在平台决定的,若平台是32位即x86环境,则指针变量是4个字节,若平台是64位,则指针变量是8个字节。既然指针变量不会根据指针类型变化,那么我们为什么要区分指针变量的类型呢?换句话说char* 和 int* 都有能力存储4个字节的地址,为什么不统一成一个自定义的指针变量例如ptr*

        从上图可以得知,我们把int*类型的地址强行赋给char*类型的地址,再进行取值调用的时候,会根据char*来进行赋值以至于只会将一个字节赋值成0,若是正常使用int*来接收,那么四个字节都是0 ,如下图所示。

        由下图可知,虽然不同指针变量的存储类型不影响地址的存储,但是当直接对地址进行运算,还是会根据指针类型的不同进行运算。char*类型+1,跳过1个字节,int*类型+1,跳过4个字节。

所以我们会得到这样的结论:指针变量的类型在存取地址的时候可有可无,在修改地址指向的内容的时候是非常有必要的,它决定了在利用地址更改值的时候需要更改多少个字节;若直接对地址进行运算,那么会根据指针变量的类型+‘1’,这个‘1’可能是char类型的一个字节,也可能是int类型的四个字节。 

使用float*和int*的时候,无论是访问内存还是使用内存,都是4个字节,那么可不可以混用呢?

答案是:不可以

下图是整型解引用赋值整型,我们可以看到100以16进制存入内存。

我们把100.0存入内存,发现内存存的数据发生了变化, 虽然都是100,但是浮点数存入内存的方式是不同的。

2. 野指针

        指针指向的内存没有初始化,或者已经被销毁,此时的指针称为野指针。

2.1 未初始化导致的野指针

2.2 指针越界导致的野指针

2.3 如何规避野指针 

①指针初始化。

②指针小心越界。

③指针指向的空间置为NULL。NULL是0,类型是void*,如果取值的话一定会报错(默认0地址不能访问),所以,我们可以先判断这个指针如果不是NULL再进行取值。

④避免返回局部变量的地址,因为局部变量已经被销毁了(没有那块内存空间的使用权限了)。

⑤指针使用之前检查有效性。

3. 指针运算

3.1 指针加减整数

这里的values[N_VALUES]并不算下标越界,因为并没有使用这段内存,只是用了一下这个地址作为判断条件。

3.2 指针减指针

当同类型的地址减去同类型的另外一个地址,得出的结果的绝对值是两个地址之间的元素个数

需要注意的是,两个指针指向的必须是同一块内存,不然毫无意义。

        那么有同学会想,指针+指针得到的结果是什么呢,这个结果毫无意义,类似于你可以把日期相减,得到天数,但是你不能把日期相加,这样就毫无意义

3.3 指针的关系运算

其实就是地址之间的比较,判断两个地址谁大谁小,从而对地址指向的内容进行操作。

4. 二级指针

        简单描述一下,就是指针变量里面存的地址,这个地址是一个指针的地址。乍一听是不是以为在说绕口令呢?下面用一张图来进行诠释。

        上图中表示int * pa = &a;我们可以这么理解:*号表明pa的类型是一个指针类型,int表明这个指针类型指向的是int类型;那么我们是不是可以来理解一下二级指针。

        int* *ppa = &pa;还是将类型拆开,距离ppa最近的*表明ppa是一个指针,int* 表明ppa指向的类型是int*的类型

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

5. 指针数组

主语是数组,即存放指针的数组就是指针数组

5.1 如何使用指针数组模拟二维数组

        首先构造出三个一维数组,所谓二维数组就是将这三个一维数组连起来;我们构造一个指针数组,分别存入之前构造的一维数组名,在之前的帖子说明,一维数组名是数组的第一个元素的地址,所以分别存入了三个地址,我们需要遍历指针数组,得到三个一维数组的首地址,再引入一个变量j,根据指针加减法,就可以访问一维数组中除了第一个元素的其他元素的地址,最后解引用就可以得到最后的结果。

#include <stdlib.h>
 

int main()
{
    int arr1[4] = {1,2,3,4};
    int arr2[4] = {2,4,6,8};
    int arr3[4] = {3,6,9,12};
// 用一维数组模拟出二维数组的效果
    int* arr_sum[3] = {arr1,arr2,arr3};
    for(int i = 0;i < 3;i++)
    {
        for(int j = 0;j < 4;j++)
        {
            printf("%d ",*(arr_sum[i] + j));
        }
        printf("\n");
    }
    return(0);
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于Ubuntu系统的远程控制及文件传输

目录 1. 网络配置1.1 虚拟机Ubuntu网络配置1.2树莓派网络配置 2. 远程终端登录3. FTP文件传输4. 安装Xming和PuTTY5. 使用X11转发6. 安装和使用VNC思考题解答参考资料 1. 网络配置 1.1 虚拟机Ubuntu网络配置 将虚拟机的网络连接设置为“桥接模式”&#xff0c;这样虚拟机的网…

IS-IS-单区域的配置

一、IS-IS的概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种‌链路状态路由协议‌&#xff0c;最初设计用于‌OSI&#xff08;Open Systems Interconnection&#xff09;参考模型‌的网络层&#xff08;CL…

Flask使用MySQL数据库通过Flask-SQLAlchemy 迁移数据库,实际更新文件,但是提示没有检测到数据更新。

本地写了一个model的用户类&#xff0c;数据库连接信息正确&#xff0c;执行下面2条命令进行数据库迁移。 flask db migrate 生成迁移文件 flask db upgrade 执行迁移文件的升级 发现执行完后&#xff1a;提示没有检测到数据的更新 PS C:\Users\mu> flask db migrate IN…

USB3.0走线注意事项和其中的协议

USB3.0走线的要求&#xff1a; 1、USB要走差分&#xff0c;阻抗控制为90欧姆&#xff0c;并包地处理&#xff0c;总长度最好不要超过1800mil. 2、尽可能缩短走线长度&#xff0c;优先考虑对高速USB差分&#xff08;RX、TX差分&#xff09;的布线&#xff0c;USB差分走线在走线…

QML 菜单控件:MenuBar、MenuBarItem、Menu、MenuItem层级关系和用法

目录 引言相关阅读关于MenuBarItem核心代码1. 主菜单栏 (MenuBar.qml)2. 主页面&#xff0c;包含右键菜单 (MainPage.qml)3. 主界面绑定 (Main.qml)整体结构 运行效果总结工程下载 引言 在 GUI 开发中&#xff0c;菜单是用户交互的核心组件。QML 提供了一套灵活的菜单控件&…

蓝桥杯嵌入式第十四届模拟二

一.LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 二.按键 按键配置,由原理图按键所对引脚要GPIO_Input 生成代码,在文件夹中添加code文件夹,code中添加fun.c、fun.h、headfile.h文件,去资源包中把lc…

Qt 入门 1 之第一个程序 Hello World

Qt 入门1之第一个程序 Hello World 直接上操作步骤从头开始认识&#xff0c;打开Qt Creator&#xff0c;创建一个新项目&#xff0c;并依次执行以下操作 在Qt Creator中&#xff0c;一个Kits 表示一个完整的构建环境&#xff0c;包括编译器、Qt版本、调试器等。在上图中可以直…

架构思维: 全链路日志深度解析

文章目录 引言&#xff1a;微服务时代的日志挑战一、业务痛点与需求分析二、技术选型的六维评估模型1. 标准化支持 OpenTracing2. 存储扩展性3. 性能损耗4. 功能完备性5. 侵入性控制6. 社区生态 三、SkyWalking落地实践与调优1. 核心架构解析2. 关键配置示例&#xff1a; 采样率…

唯美社区源码AM社区同款源码

源码介绍 唯美社区源码AM社区同款源码 后端修改application.properties文件内容为你的数据库 前端修改/config/config.js文件内容为你的后端地址 这两个文件里要修改的地方我已经用中文标注出来了 截图 源码免费下载 唯美社区源码AM社区同款源码

3. go-zero中如何使用redis

问题 go-zero项目相关文档中redis是这样配置的&#xff1a; Name: account.rpc ListenOn: 0.0.0.0:8080 Etcd:Hosts:- 127.0.0.1:2379Key: account.rpcMysql:Host: xxxx:3306User: rootPass: xxxData: mall-userCharset: utf8mb4Cache: - Host: 192.168.145.10:6379Type: nod…

cpp自学 day19(多态)

一、基本概念 同一操作作用于不同的对象&#xff0c;产生不同的执行结果 &#x1f449; 就像「按F1键」&#xff1a;在Word弹出帮助文档&#xff0c;在PS弹出画笔设置&#xff0c;​同一个按键触发不同功能 &#xff08;1&#xff09;多态类型 类型实现方式绑定时机​静态多态…

【算法/c++】利用中序遍历和后序遍历建二叉树

目录 题目&#xff1a;树的遍历前言题目来源树的数组存储基本思想存储规则示例 建树算法关键思路代码总代码 链表法 题目&#xff1a;树的遍历 前言 如果不是完全二叉树&#xff0c;使用数组模拟树&#xff0c;会很浪费空间。 题目来源 本题来自 PTA 天梯赛。 题目链接: 树…

基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(一)

1. 背景 arXiv简介&#xff08;参考DeepSeek大模型生成内容&#xff09;&#xff1a; arXiv&#xff08;发音同“archive”&#xff0c;/ˈɑːrkaɪv/&#xff09;是一个开放的学术预印本平台&#xff0c;主要用于研究人员分享和获取尚未正式发表或已完成投稿的学术论文。创…

cpp经典数论问题

题目如下 思路 代码如下

C++中如何比较两个字符串的大小--compare()函数实现

一、现在有一个问题描述&#xff1a;有两个字符串&#xff0c;要按照字典顺序比较它们的大小&#xff08;注意所有的小写字母都大于所有的大写字母 &#xff09;。 二、代码 #include <bits/stdc.h> using namespace std;int main() {string str1 "apple";…

Scala面向对象2

1. 抽象属性和方法&#xff1a;用 abstract 关键字定义抽象类&#xff0c;其中抽象属性无初始值&#xff0c;抽象方法无实现 。重写抽象方法需用 override &#xff0c;重写抽象属性时&#xff0c;可变属性用 var &#xff0c;不可变属性用 val 。 匿名子类&#xff1a;和 Jav…

【FPGA基础学习】状态机思想实现流水灯

目录 一、用状态机实现LED流水灯1.状态机思想简介1. 1基本概念1.2.核心要素1.3分类与模型 2.LED流水灯 二、CPLD与FPGA1.技术区别2.应用场景3.设计选择建议 三、HDLbits组合逻辑题目 一、用状态机实现LED流水灯 1.状态机思想简介 1. 1基本概念 ​ 状态机&#xff08;Finite …

图片尺寸修改软件下载

【图片尺寸调整工具v1.0&#xff1a;高效便捷的图像处理助手】 图片尺寸调整工具v1.0是一款专为简化图像处理流程设计的轻量级软件&#xff0c;兼顾高效批量处理与个性化单图调整需求。该工具以"零学习成本"为核心设计理念&#xff0c;通过简洁直观的交互界面&#…

MySQL-SQL-DDL语句、表结构创建语句语法、表约束、表数据类型,表结构-查询SQL、修改SQL、删除SQL

一.SQL SQL&#xff1a;一门操作关系型数据库的编程语言&#xff0c;定义操作所有关系型数据库的统一标准 二. DDL-数据库 1. 查询所有数据库 命令&#xff1a;show databases; 2. 查询当前数据库 命令&#xff1a;select database(); 3. 创建数据库 命令&#xff1a;create da…

网络钓鱼攻击的威胁和执法部门的作用(第一部分)

在当今的数字世界中&#xff0c;网络犯罪分子不断开发新技术来利用个人、企业和政府机构。 最普遍和最具破坏性的网络犯罪形式之一是网络钓鱼——一种社会工程手段&#xff0c;用于欺骗人们提供敏感信息&#xff0c;例如登录凭据、财务数据和个人详细信息。 随着网络钓鱼攻击…