指针(一)------指针概念+指针类型+野指针+指针运算+二级指针

💓博主csdn个人主页:小小unicorn
⏩专栏分类:C语言
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

指针(一)

  • 指针是什么
    • 指针的定义
    • 指针的大小
  • 指针类型
    • 指针有哪些类型
    • 指针类型的意义:
      • 指针+-整数:
      • 指针解引用:
  • 野指针
    • 野指针的成因
    • 如何避免野指针
  • 指针运算
    • 指针+-整数
    • 指针-指针
    • 指针的关系运算
  • 二级指针

指针是什么

指针是什么?
指针理解的2个要点:
1. 指针是内存中一个最小单元的编号,也就是地址
2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

总结:指针就是地址,口语中的说的指针通常指指针变量。

指针的定义

在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的内存单元,可以说地址指向该内存单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

官方对指针的定义,其实我们可以理解为:在内存中,内存被细分为一个个大小为一个字节的内存单元,每一个内存单元都有自己对应的地址。
在这里插入图片描述

我们可以将这些内存单元形象地看成一个个的房间,将内存单元(房间)对应的地址形象地看成房间的门牌号。而我们通过门牌号(地址)就可以唯一的找到其对应的房间(内存单元),即地址指向对应内存单元。所以说,可以将地址形象化的称为“指针”

我们可以通过&(取地址操作符)取出变量的内存起始地址,把地址可以存放到一个变量中,这个变量就是指针变量

#include<stdio.h>
int main()
{int a = 10;//在内存中开辟一块空间int* p = &a;//将a的地址取出,放到指针变量p中return 0;
}

总结:

指针变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。

指针的大小

这里的问题是:
1.一个小的单元到底是多大?(1个字节)
2.如何编址?

经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。
对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0);

那么32根地址线产生的地址就会是:
在这里插入图片描述
这里就有2的32次方个地址。

同样的算法,在64位的机器上一共能产生 264 个不同的地址。

232 可以用32个bit位进行存储,而8个bit位等价于1个字节,所以在32位的平台下指针的大小为4个字节。

264 可以用64个bit位进行存储,所以在64位的平台下指针的大小为8个字节。

这里我们就明白:

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。

那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。

总结:

指针变量是用来存放地址的,地址是唯一标示一个内存单元的。
指针的大小在32位平台是4个字节,在64位平台是8个字节。

指针类型

指针有哪些类型

这里我们在讨论一下:指针的类型
我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?

准确的说:有的。

当有这样的代码:

int num = 10;
p = &num;

要将&num(num的地址)保存到p中,我们知道p就是一个指针变量,那它的类型是怎样的呢?我们给指针变量相应的类型。

char  *pc = NULL;
int   *pi = NULL;
short *ps = NULL;
long  *pl = NULL;
float *pf = NULL;
double *pd = NULL;

从上面可以看出:

指针的定义方式是type+ *
char * 类型的指针存放的是char类型的变量地址;
int *类型的指针存放的是int类型的变量地址;
float * 类型的指针存放的是float类型的变量地址等。

指针类型的意义:

指针±整数:

若指针类型为int * 的指针+1,那么它将跳过4个字节的大小指向4个字节以后的内容:
在这里插入图片描述
若指针类型为char * 的指针+1,那么它只会跳过1个字节的大小指向下一个字节的内容,以此类推。

指针解引用:

指针的类型决定了指针解引用的时候能够访问几个字节的内容。

若指针类型为int *,那么将它进行解引用操作,它将可以访问从指向位置开始向后4个字节的内容:

在这里插入图片描述
若指针类型为char *,那么将它进行解引用操作,它将可以访问从指向位置开始向后1个字节的内容,以此类推。

总结:

1.指针的类型决定了指针向前或向后走一步有多大距离。
2.指针的类型决定了指针在进行解引用操作时,能向后访问的空间大小。

野指针

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

野指针的成因

1.指针未初始化

#include <stdio.h>
int main()
{ int *p;//局部变量指针未初始化,默认为随机值*p = 20;return 0;
}

局部指针变量p未初始化,默认为随机值,所以这个时候的p就是野指针。
2.指针越界访问

#include <stdio.h>
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

当指针指向的范围超出arr数组时,p就是野指针。
3.指针指向的空间被释放

#include<stdio.h>
int* test()
{int a = 10;return &a;
}
int main()
{int* p = test();return 0;
}

指针变量p得到地址后,地址指向的空间已经释放了,所以这个时候的p就是野指针。(也就是说:局部变量出了自己的作用域就会被释放)

如何避免野指针

1.指针初始化
当指针明确知道要存放某一变量地址时,在创建指针变量时就存放该变量地址。当不知道指针将要用于存放哪一变量地址时,在创建指针变量时应置为空指针(NULL)。

#include<stdio.h>
int main()
{int a = 10;int* p1 = &a;//明确知道存放某一地址int* p2 = NULL;//不知道存放哪一地址时置为空指针return 0;
}

2. 小心指针越界
3. 指针指向空间释放,及时置NULL
4. 避免返回局部变量的地址
5. 指针使用之前检查有效性

指针运算

指针±整数

#include<stdio.h>
int main()
{int arr[5] = { 0 };int* p = arr;int i = 0;for (i = 0; i < 5; i++){*(p + i) = i;}return 0;
}

指针-指针

int my_strlen(char* p)
{char* pc = p;while (*p != '\0')p++;return p - pc;
}

指针-指针的绝对值是是两个指针之间的元素个数。

指针的关系运算

指针的关系运算,即指针之间的大小比较。
我们如果要将一个数组中的元素全部置0,可以有两种方法。

第一种:从前向后置0

#include<stdio.h>
int main()
{int arr[5] = { 1, 2, 3, 4, 5 };int* p = &arr[0];for (p = &arr[0]; p <= &arr[4]; p++){*p = 0;}return 0;
}

最终指向数组最后一个元素后面的那个内存位置的指针将与&arr[4]比较,不满足条件,于是结束循环。

第二种:从后向前置0

#include<stdio.h>
int main()
{int arr[5] = { 1, 2, 3, 4, 5 };int* p = &arr[4];for (p = &arr[4]; p >= &arr[0]; p--){*p = 0;}return 0;
}

最终指向第一个元素之前的那个内存位置的指针将与&arr[0]比较,不满足条件,于是结束循环。

标准规定
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

总结:

这两种方法在绝大部分编译器下均能将arr数组中的元素置0,但是我们要尽量使用第一种方法,因为标准并不保证第二种方法可行。

二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
这就是二级指针。
在这里插入图片描述
对于二级指针的运算有:
*ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa .

int b = 20;
*ppa = &b;//等价于 pa = &b;

**ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a .

**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;

总结:

存放普通变量的地址的指针叫一级指针,存放一级指针变量的地址的指针叫二级指针,存放二级指针变量地址的指针叫三级指针,以此类推。

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

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

相关文章

WordPress关注公众号可见内容插件源码

Wordpress公众号引流工具——关注公众号可见内容插件推荐 通过关注微信公众号&#xff0c;获取随机验证码从而获得隐藏文本的访问权限。 插件特点 隐藏内容扫码关注获取验证码 可以作为引流公众号 支持无必须API接口&#xff0c;无备案域名也可以 自定义验证接口URL 自定…

java八股文面试[数据库]——B树和B+树的区别

B树是一种树状数据结构&#xff0c;它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作。 1、B树的特性 B树中允许一个结点中包含多个key&#xff0c;可以是3个、4个、5个甚至更多&#xff0c;并不确定&#xff0c;需要看具体的实…

Linux——常用命令大汇总(带你快速入门Linux)

纵有疾风起&#xff0c;人生不言弃。本文篇幅较长&#xff0c;如有错误请不吝赐教&#xff0c;感谢支持。 &#x1f4ac;文章目录 一.终端和shell命令解析器终端和shell命令解析器概述终端提示符的格式常用快捷键 二.Linux命令格式帮助文档&#xff1a;man 三.目录基础知识Wind…

LabVIEW是如何控制硬件的?

概述 工程 师 和 科学 家 可以 使用 LabVIEW 与 数千 种 不同 的 硬件 设备 无缝 集成&#xff0c; 并 通过 方便 的 功能 和 跨 所有 硬件 的 一致 编 程 框架 帮助 节省 开发 时间。 内容 通过更简单的系统集成节省开发时间 连接到任何硬件 NI 硬件 第三方硬件 快速找到…

基础知识回顾:借助 SSL/TLS 和 NGINX 进行 Web 流量加密

原文作者&#xff1a; Robert Haynes 原文链接&#xff1a; 基础知识回顾&#xff1a;借助 SSL/TLS 和 NGINX 进行 Web 流量加密 NGINX 唯一中文官方社区 &#xff0c;尽在 nginx.org.cn 网络攻击者肆无忌惮、作恶多端&#xff0c;几乎每天都有网络入侵、数据窃取或勒索软件攻击…

RabbitMQ-常用命令

RabbitMQ常用命令 3.1 启动停止rabbitMQ命令 # 前台启动Erlang VM 和 RabbitMQ 当窗口关闭或者ctrlc时&#xff0c;使退出了。 rabbitmq-server# 使用系统命令启动 systemctl start rabbitmq-server# 后台启动 rabbitmq-server -detached# 停止rabbitMQ和Erlang VM rabbitmq-…

基于 Debian 12 的 Devuan GNU+Linux 5 为软件自由爱好者而生

导读Devuan 开发人员宣布发布 Devuan GNULinux 5.0 “代达罗斯 “发行版&#xff0c;它是 Debian GNU/Linux 操作系统的 100% 衍生版本&#xff0c;不包含 systemd 和相关组件。 Devuan GNULinux 5 基于最新的 Debian GNU/Linux 12 “书虫 “操作系统系列&#xff0c;采用长期支…

企业如何充分借助大数据下精准营销?

技术的发展和智能终端的普及移动互联网用户的大规模增长使移动互联网快速发展&#xff0c;使中国移动互联网软件进入移动互联网时代越来越多地涉及到改变生活大家习惯。移动互联网时代的到来也意味着大数据时代的到来。精准营销数据方法&#xff0c;移动互联网和大数据的兴起不…

从Gamma空间改为Linear空间会导致性能下降吗

1&#xff09;从Gamma空间改为Linear空间会导致性能下降吗 2&#xff09;如何处理没有使用Unity Ads却收到了GooglePlay平台的警告 3&#xff09;C#端如何处理xLua在执行DoString时候死循环 4&#xff09;Texture2DArray相关 这是第350篇UWA技术知识分享的推送&#xff0c;精选…

【VR】Network Manager HUD

&#x1f4a6;本专栏是我关于VR开发的笔记 &#x1f236;本篇是——Network Manager HUD Network Manager HUD组件 简介基础知识 简介 网络管理器 HUD是一种快速启动工具&#xff0c;可帮助您立即开始构建多人游戏&#xff0c;而无需首先构建用于游戏创建/连接/加入的用户界面…

STM32f103入门(7)pwm驱动led驱动舵机驱动直流电机

PWM驱动 PWM介绍TIM_OC1Init 配置通道TIM_OCStructInit 输出比较参数默认值输出比较模式 TIM_OCInitstructure输出比较极性 TIM_OCInitstructure设置输出使能以下三个决定了PWM的频率 占空比初始化通道 TIM_OC1Init(TIM2, &TIM_OCInitstructure);GPIO复用 PWM通道 驱动LED复…

学习 使用pandas库 DataFrame 使用

1 、 数据排序 sort_values()函数 by:要排序的名称或名称列表&#xff0c; sorted_df df.sort_values(byAge,ascendingFalse) 由大到小排序&#xff1b; sorted_df df.sort_values(byAge) 由小到大排序&#xff1b; # 创建一个示例数据帧 data {Name: [Tom, Nick, John…

【C++从0到王者】第二十五站:多继承的虚表

文章目录 前言一、多继承的虚函数表二、菱形继承与菱形虚拟继承的虚函数表1.菱形继承2.菱形虚拟继承的虚函数表 三、抽象类1.抽象类的概念2.接口继承与实现继承 总结 前言 其实关于单继承的虚函数表我们在上一篇文章中已经说过了&#xff0c;就是派生类中的虚表相当于拷贝了一…

面向对象的设计原则

设计模式 Python 设计模式&#xff1a;对软件设计中普遍存在&#xff08;反复出现&#xff09;的各种问题&#xff0c;所提出的解决方案。每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计 面向对象 三大特性&#xff1a;封装、继承、多态 …

xsschallenge靶场练习1-13关

文章目录 第一关第二关第三关第四关第五关第六关第七关第八关第九关第十关第十一关第十二关第十三关 第一关 观察页面 http://192.168.80.139/xsschallenge/level1.php?nametest尝试在name后面输入最近基本的xss语法 <script>alert(1)</script>第二关 查看页面源…

java.lang.classnotfoundexception: com.android.tools.lint.client.api.vendor

Unity Android studio打包报错修复 解决方式 java.lang.classnotfoundexception: com.android.tools.lint.client.api.vendor 解决方式 在 launcherTemplate 目录下找到 Android/lintOptions 选项 加上 checkReleaseBuilds false lintOptions { abortOnError false checkRelea…

阿里云效和阿里在线idea使用

阿里云效 https://flow.aliyun.com/all?page1 阿里在线idea&#xff1a;https://ide.aliyun.com/ 在云效中创建的项目可以在在线idea 打开 运行中的项目 设置ssh 设置以后可以使用云效率的代码构建来构建代码 设置 添加自有云或者体验5h

C++/C:pass-by-value(值传递)与pass-by-reference(引用传递)

一、C的引用&#xff08;reference&#xff09; 1.1、引用的概念 c中新增了引用&#xff08;reference&#xff09;的概念&#xff0c;引用可以作为一个已定义变量的别名。 Declares a named variable as a reference, that is, an alias to an already-existing object or f…

Android 1.1 背景相关与系统架构分析

目录 1.1 背景相关与系统架构分析 分类 Android 基础入门教程 1.Android背景与当前的状况 2.Android系统特性与平台架构 系统特性&#xff1a; 平台架构图&#xff1a; 架构的简单理解&#xff1a; 3.本节小结&#xff1a; 1.1 背景相关与系统架构分析 分类 Android 基础…

【python使用 Pillow 库】缩小|放大图片

当我们处理图像时&#xff0c;有时候需要调整图像的大小以适应特定的需求。本文将介绍如何使用 Python 的 PIL 库&#xff08;Pillow&#xff09;来调整图像的大小&#xff0c;并保存调整后的图像。 环境准备 在开始之前&#xff0c;我们需要安装 Pillow 库。可以使用以下命令…