(C语言)深入理解指针1基础

news2024/11/26 10:40:02

指针是C语言中的一个难点,但如果真正理解了指针,其实没有很难,本篇文章介绍了指针的基础知识,后面还会继续更行指针的内容。感谢支持。

目录

1. 内存和地址

1.1 内存

1.2 究竟该如何理解编址

2. 指针变量和地址

2.1 取地址操作符(&)

2.2 指针变量和解引⽤操作符(*)

2.2.1 指针变量

2.2.2 如何拆解指针类型

2.2.3 解引⽤操作符

2.3 指针变量的⼤⼩

3. 指针变量类型的意义

3.1 指针的解引⽤

3.2 指针+-整数

3.3 void* 指针

4. const修饰指针

4.1 const修饰变量

4.2 const修饰指针变量

5. 指针运算

5.1 指针+- 整数

5.2 指针-指针

5.3 指针的关系运算


1. 内存和地址

1.1 内存

CPU( 中央处理器) 在处理数据的时候 ,需要的数据是在内存中读取的 ,处理后的数   据也会放回内存中 ,那我们买电脑的时候  电脑上内存是8GB/16GB/32GB等 内存划分为一个个的内存单元 ,每个内存单元的大小取1个字节,方便高效管理。

计算机中常见的单位

其实每个内存单元都有自己的唯一确定的编号,通过这个编号,CPU就可以快速,找到对应的内存空间,这个编号也就是地址,在C语言中也有一个名字叫作:地址。

我们可以理解为:内存单元的编号==地址==指针

1.2 究竟该如何理解编址

CPU访问内存中的某个字节空间 ,必须知道这个 字节空间在内存的什么位置 ,而因为内存中字节很多 ,所以需要给内存进行编址(就如同宿舍很 ,需要给宿舍编号一样)。

计算机中的编址 ,并不是把每个字节的地址记录 下来 ,而是通过硬件设计完成的。

首先 ,必须理解 ,计算机内是有很多硬件单元,而硬件单元是要互相协同工作的。所谓的协 ,至少相互之间要能够进行数据传递。

但是硬件与硬件之间是互相独立的 ,那么如何通信呢?答案很简单 ,用"线"连起来。

而CPU和内存之间也是有大量的数据交互的 ,所 ,两者必须也用线连起来。

不过 ,我们今天关心一组线 ,叫做地址总线

我们可以简单理解,32位机器有32根地址总线,每根线只有两态 ,表示0或1【电脉冲有无】 ,那么一根线 ,就能表示2种含义 ,2根线就能表示4种含  ,依次类推。32根地址线 ,就能表示2^32种含   ,每一种含义都代表一个地址。

地址信息被下达给内存 ,在内存上 ,就可以找到该地址对应的数据 ,将数据在通过数据总线传入 CPU内寄存器。

2. 指针变量和地址

2.1 取地址操作符(&)

理解了内存和地址的关系,我们再回到C语⾔,在C语⾔中创建变量其实就是向内存申请空间,

我们知道C语言中一个整形占4个字节,创建时会向内存申请4字节的空间,当取整形变量的地址时会取出4个字节地址的第一个地址,因为知道是int类型,当需要这个变量时就能顺藤摸瓜,将这4个字节全部访问。

2.2 指针变量和解引⽤操作符(*)

2.2.1 指针变量

在这里p就是指针变量,int*是指针变量类型,p变量里存放的是变量a的地址。

2.2.2 如何拆解指针类型

其实int* p理解为:int是p指针变量所指向的变量的类型。

              *理解为:告诉我们p是指针变量。

              p理解为:指针变量的名字。

如果是char类型的数据:

2.2.3 解引⽤操作符

我们得到了一个变量的地址,将他存在了一个指针变量中,我们这样做有什么用呢?

我们可以通过地址找到这个地址所指向的变量。来操作,改变它。我们必须要用到解引用操作符:*。

*pa=0;相当于通过pa中存放的地址找到了这个a变量,并把a赋值为0;

我们因为可以看到打印a与打印*pa的结果是一样的。

2.3 指针变量的⼤⼩

前⾯的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。
同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变的⼤⼩就是8个字节。

我们可以分别看一下在X86(32位)和X64(64位)下打印地址大小的结果:

32位下的结果:

64位下的结果:

可以看到在同一环境下不同类型的地址所占内存的大小是相同的,也就是说地址无贵贱,所占内存大小都遵循下面的规律:

32位平台下地址是32个bit位,指针变量⼤⼩是4个字节
64位平台下地址是64个bit位,指针变量⼤⼩是8个字节
注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。

3. 指针变量类型的意义

3.1 指针的解引⽤

代码一:

代码二:

代码一是将int*类型强制类型转变成了char*类型,解引用时只访问了一个字节将44变成了00

而代码二int*类型的pi解引用访问了四个字节,将n全变为0;

结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。
⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节。

3.2 指针+-整数

我们可以看出, char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。
这就是指针变量的类型差异带来的变化。
结论:指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)。

3.3 void* 指针

在指针类型中有⼀种特殊的类型是 void* 类型的,可以理解为⽆具体类型的指针(或者叫泛型指
针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进⾏指针的+-整数和解引⽤的运算。
举例:
将⼀个int类型的变量的地址赋值给⼀个char*类型的指针变量。编译器给出了⼀个警
告,是因为类型不兼容。⽽使⽤void*类型就不会有这样的问题。
但是void*并不是万能的:
这⾥我们可以看到, void* 类型的指针可以接收不同类型的地址,但是⽆法直接进⾏指针运算。
那么 void* 类型的指针到底有什么⽤呢?这里有一篇博客可以参考,使用在了函数传参上面
(C语言)qsort函数模拟实现: http://t.csdnimg.cn/FMB3k

4. const修饰指针

4.1 const修饰变量

变量是可以修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量。
但是如果我们希望⼀个变量加上⼀些限制,不能被修改,怎么做呢?这就是const的作⽤
上面代码中m被const修饰了不能再被修改了,
但是如果我们绕过m直接通过地址去修改m也是可以的。
我们可以看到这⾥⼀个确实修改了,但是我们还是要思考⼀下,为什么m要被const修饰呢?就是为了不能被修改,如果p拿到m的地址就能修改m,这样就打破了const的限制,这和我们的想法是不一样的,所以应该让p拿到m的地址也不能修改m,那接下来怎么做呢?

4.2 const修饰指针变量

总结: const修饰指针变量的时候
const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。
但是指针变量本⾝的内容可变。
const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指
向的内容,可以通过指针改变。

5. 指针运算

指针的基本运算有三种,分别是:
指针+- 整数
指针-指针
指针的关系运算

5.1 指针+- 整数

因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸⽠就能找到后⾯的所有元素。
我们通过运用地址访问了数组中所有的元素,并打印出来。

5.2 指针-指针

5.3 指针的关系运算

C语言中指针的知识多而复杂,可能有的地方写的不明白,欢迎在评论区讨论。
感谢观看,感谢指正错误。

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

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

相关文章

Midjourney是个什么软件?midjourney订阅教程

数字时代,AI的应用正在不断推动各个领域的发展。其中,AI在艺术和设计领域的运用引起了广泛的关注。作为一款爆火的AI绘画软件,Midjourney通过其独特的原理和便捷的使用方法,为创作者提供了一个创作逼真绘画作品的全新平台 1、AI绘…

初阶数据结构:二叉树

目录 1. 树的相关概念1.1 简述:树1.2 树的概念补充 2. 二叉树2.1 二叉树的概念2.2 二叉树的性质2.3 二叉树的存储结构与堆2.3.1 存储结构2.3.2 堆的概念2.3.3 堆的实现2.3.3.1 堆的向上调整法2.3.3.2 堆的向下调整算法2.3.3.3 堆的实现 1. 树的相关概念 1.1 简述&a…

Java多线程——信号量Semaphore是啥

目录 引出信号量Semaphore ?Redis冲冲冲——缓存三兄弟:缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java多线程——信号量Semaphore是啥 信号量Semaphore ? Semaphore 通常我们叫它信号量, 可以用来控制同时访问特…

Day36 网络概述、IP划分、网络模型

文章目录 网络发展史局域网和广域网局域网(LAN)广域网(Wan) 光猫路由器 IP地址基本概念地址划分特殊地址(后续编程使用)IP地址转换端口字节序 网络模型网络模型OSI模型(了解)TCP/IP模…

15:Zookeeper高可用集群|分布式消息队列Kafka|搭建高可用Hadoop集群

Zookeeper高可用集群|分布式消息队列Kafka|搭建高可用Hadoop集群 Zookeeper集群Zookeeper角色与特性Zookeeper角色与选举Zookeeper的高可用Zookeeper可伸缩扩展性原理与设计Zookeeper安装zookeeper集群管理 Kafka概述在node节点上搭建3台kafka 高可用Had…

Vue.js+SpringBoot开发高校学院网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学院院系模块2.2 竞赛报名模块2.3 教育教学模块2.4 招生就业模块2.5 实时信息模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 学院院系表3.2.2 竞赛报名表3.2.3 教育教学表3.2.4 招生就业表3.2.5 实时信息表 四、系…

循环队列--C语音实现

目录 一、循环队列的特点: 二、普通的队列的缺点: 三、循环队列实现原理: 四、循环队列是实现步骤: 1.循环队列的头文件: 2.循环队列的源文件: 3.注意点: 一、循环队列的特点&#xff1…

灯塔:CSS笔记(1)

CSS&#xff1a;层叠样式表 所谓层叠 即叠加的意思&#xff0c;表示样式可以一层一层的层叠覆盖 css写在style标签中&#xff0c;style标签一般写在head标签里面&#xff0c;title标签下面 <!DOCTYPE html> <html lang"en"> <head><meta cha…

java 从环境变量中获取参数及值

window直接在这设置&#xff1a; linux在/etc/profile文件里存放&#xff1a; export keyvalue 然后立即生效&#xff1a;source /etc/profile 代码获取值这样获取&#xff1a; System.getenv("key");

C++初阶篇----类与对象中卷

目录 引言1. 构造函数1.1概念1.2 特性 2. 析构函数2.1 概念2.2 特性 3. 拷贝构造函数3.1 概念3.2特征 4. 赋值运算符重载4.1 运算符重载4.2 赋值运算符重载4.3 前置和后置重载 5.日期类的实现6.const成员7.取地址及const取地址操作符重载 引言 当一个类既没有成员变量又没有成…

【特征选择】CMA-ES(协方差矩阵适应进化策略)

导 读 当将模型拟合到数据集时&#xff0c;可能需要执行特征选择&#xff1a;由于多种原因&#xff0c;仅保留某些特征子集来拟合模型&#xff0c;而丢弃其余特征具有一定的必要性&#xff0c;如下&#xff1a; 保持模型的可解释性&#xff08;特征太多会使解释变得更加困难&am…

css-解决Flex布局下居中溢出滚动截断问题

css-解决Flex布局下居中溢出滚动截断问题 1.出现的问题2.解决方法2.1 Flex 布局下关键字 safe、unsafe2.2 使用 margin: auto 替代 justify-content: center2.3 额外嵌套一层 1.出现的问题 在页面布局中&#xff0c;我们经常会遇到/使用列表内容水平居中于容器中&#xff0c;一…

Codesys自定义库的帮助文档的美化

文章目录 1.前言2.美化的方式2.1.利用html标签2.2.利用reStructuredText 3.相关说明3.1.使用reStructuredText时&#xff0c;中文注释的问题3.2.将文档需要的图片包含到库中3.3.文档的作用区域 1.前言 当我们在codesys中写好自己的库&#xff0c;并且发布给别人使用时&#xf…

overleaf latex 笔记

overleaf: www.overleaf.com 导入.tex文件 1.代码空一行&#xff0c;代表文字另起一段 2. 1 2 3 排序 \begin{enumerate} \item \item \item \end{enumerate} 3.插入图片 上传图片并命名 \usepackage{float}导包\begin{figure}[H]&#xff1a;表示将图…

大数据最佳实践

本文主要收录一些大数据不错的实践文章 1、数禾云上数据湖最佳实践 https://blog.51cto.com/u_15089766/2601706 该文章介绍了数禾云的数据胡实践&#xff0c;包含presto以及数据湖等组件的一些部署架构&#xff0c;文章听不错的&#xff0c;里面提到了为了避免presto与yarn计…

汽车中网上的logo不能改,需要到车管所备案

需要备案。 车辆改装需到车辆管理所办理登记。 机动车每年检验时&#xff0c;需要对外观进行检测。 中国在线的标志不能更改。 汽车格栅是汽车前部进气口附近相关部件的总称。 汽车的中网主要位于水箱、发动机、空调等设备的前面&#xff0c;控制进气和通风&#xff0c;防止行…

3d怎么拖模型---模大狮模型网

在3D建模软件中拖动(移动)模型通常是一种基本的操作&#xff0c;用来调整模型的位置或布局。以下是一般情况下在3D建模软件中拖动模型的基本步骤&#xff1a; 3d拖模型的步骤&#xff1a; 选择模型&#xff1a;在3D建模软件中选中你要拖动的模型。通常可以通过单击模型来选中它…

#define MODIFY_REG(REG, CLEARMASK, SETMASK)

#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) 这个宏 MODIFY_REG 是在嵌入式编程中&#xff0c;它用于修改一个寄存器的特定位&#xff0c;而不影响其他位。这个宏接受三个参数&#xff…

无代理方式实现VMware的迁移?详细解析

在当今数字化时代&#xff0c;数据的安全性和可用性对于企业至关重要。尤其是在VMware转变订阅策略后&#xff0c;原本永久订阅的产品转变为以年付费订阅的形式&#xff0c;导致客户不得不支付更多的费用&#xff0c;大幅增加了成本。同时&#xff0c;客户也对VMware未来发展前…

鹅厂打工8年,我为啥突然裸辞?

公众号&#xff1a;程序员白特&#xff0c;欢迎一起交流学习~ 原文&#xff1a;以下文章来源于沐洒 &#xff0c;作者ASCII26 今天跟大家分享一个重磅消息&#xff0c;沐洒终于从腾讯离职了&#xff01; 不知不觉已经在鹅厂打了8年工&#xff0c;如果说在大厂里工作如同在高校…