| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 第一站:初识C语言(终幕)你真的理解指针了吗? -> 正文阅读 |
|
[C++知识库]第一站:初识C语言(终幕)你真的理解指针了吗? |
目录 ? 十三、指针1.内存要理解指针,我们首先要理解内存,那什么是内存呢?内存是计算机上的一种存储空间,我们的电脑中常见的由8G/16G内存,程序在运行的时候会载入内存,程序如果有数据需要存储也会申请内存空间。那么如何有效的使用内存呢? 在生活中,我们有很多的空间,很多的楼,为了方便我们使用这些空间,我们会对其进行编号,比如西安邮电大学长思四101,102,103等等。这就是一种一个门牌号对应一个房间的关系,有了这些门牌号,我们可以很方便的找到对应的空间。 而我们计算机也是采用了这一种方式,我们假设内存是一个大长方形,然后我们对其进行等分,如下图所示(笔者画图水平不高,还望包涵) ?然后我们将每一个小格子称作内存单元,我们可以对每一个内存单元进行编号,如下图所示,这样未来在我们可以通过编号很快的找到我们的每一个内存单元 中间的每一个格子叫做内存单元,实践中,每一个内存单元的大小是一个字节,我们将右边的称作内存单元编号 ? ?由于在现实生活中我们将西安邮电大学a栋教学楼a101也叫做地址,通过这些地址可以找到所需要的空间,事实上我们也将内存单元编号称作地址,而在c语言中我们也将地址叫做指针。 ?那我们又有了一个新问题,如果访问一个内存单元,那内存单元的地址(指针)该如何产生呢? 我们的电脑机器常见的就是32位,64位(这里的位指的是比特位)。当然,现在主流的都是64位机器,但是我们为了能形象一点,我们这里以32位机器为例子
那如果32根地址线全部通电呢?这样就会产生32位二进制序列,如下图所示,而这些二进制序列恰好对应于上面的每一个内存编号,因为二进制与上面的十进制的内存编号是可以互相转换的,这在进制转换这篇外传中已经详细讲过了。 ?因此,我们将这些二进制序列与内存编号一一对应得到如下 ?这样的话,每一个由32根地址线决定的二进制序列就可以管理我们的内存,而这些二进制序列就称作我们这每一个内存单元的地址。 而且我们这32根地址线最多产生,2的32次方个地址,每一个地址对应一个内存单元,而每一个内存单元是一个字节的大小,也就是说,最多可以管理2的32次方个字节的内存大小。
经过上面的讲解,相信大家已经较为深刻的理解内存了,内存单元编号就是我们的地址也就是c语言中的指针。通过内存单元编号,也就是指针可以去找到我们这个内存里的数据。这叫做访问,通过一个指针去访问。 我们看下面一段代码
?不难得知结果是4,也就是a向内存申请了四个字节的空间,如下图所示,假设橙色区域即为a所申请的四个字节空间。 ?在这里我们有个习惯,因为使用32个二进制位(也就是比特位)表示内存单元的编号,太过于冗杂,由于四位二进制数等于一位十六进制数,于是我们采用十六进制数来表示内存,这样我们就只需要八个数字即可清晰的表示出地址,也就是我们c语言中的指针。 这里有一点需要注意,我们c语言中的十六进制数需要加上前缀0x,八进制数加上前缀0。 我们打印一下a的地址 这段代码需要注意的是,&a的意思是取出a的地址,%p是打印地址的意思。可以跟%d是打印整型类比。
运行后,我们会发现,只打印出来了一个地址,可是,我们的a占了四个字节啊,也就是四个内存单元,应该占据了四个地址,那我们这个地址是这四个地址中的哪一个呢? ?
想要直到到底占用了哪一个地址,我们调试打开内存窗口,按住crtl +fn+f10(有的电脑直接ctrl+f10),然后点击调试,点击窗口,点击内存,内存1,2,3,4随便选择一个即可。 我们选择内存1,先将下面改成4 ?变成如图所示 这是a的地址,0x0093FCE8,当然这个显示是四个字节中a的地址,但是我们此时已经得知a的地址了。 然后我们将列改为1 ?我们发现有四个地址,其中最小的那个地址刚好就是a的地址
用图片来表示即为 ?a的地址为对应内存单元最小的一个,也就是第一个字节的地址 那么现在我们讲了这么多的内容,那么指针怎么用呢?先阅读下面一段代码,我们来讲解一下
??????? 这段代码中,我们创建了a,并申请了四个字节的空间,然后我们使用一个变量pa来存放a的地址,这个变量pa就叫做指针,pa因为也是一个变量,所以我们习惯上叫它为指针变量。pa前面的那颗*表示pa是一个指针,而前面的int代表着pa这个指针(地址)指向的是一个int类型,所以合起来pa的类型我们称作int*,也就是所谓的指针类型。 ?这段代码运行结果为上图所示,也就是说&a,和pa其实是一回事。 那么我们使用指针变量可不仅仅只是记录一下a的地址什么的,我们是需要通过这个地址来改变它里面的数据。这才是指针的用处。
如图所示,这个*pa中,*的意思是解引用,也就是说这个操作可以使我们通过pa这个地址找到a的值。然后我们对其赋值,从而篡改了a的值,此时a的值已经变成了20 2.指针变量的大小我们运行一下下面这段代码
32位机器下结果应该是两个4,64位机器结果是两个8 可见指针变量的大小与其所指向类型无关,只与机器是多少位有关系。 为什么会产生这种情况? 因为指针变量存放的是一些比特位 32位环境下,一共有32个比特位,也就是4个字节。 64位环境下,一共有64个比特位,也就是8个字节 十四、结构体在c语言中我们已经见过许多的类型了,有int,char,short,long,long long ,double ,float等等这些都是c语言中的内置类型。除此之外,我们c语言中还有一种类型是自定义类型,自定义类型分为三种,结构体,联合体,枚举。这三种类型之中,我们已经初步了解过枚举类型了,那么我们现在来了解一下结构体。 当我们在描述一个人的时候需要描述它的身高,体重,姓名性别,年龄等等。当我们需要了解一本书的时候,需要描述它的书名,作者,出版社,定价等。这些都是一种比较复杂的类型。这时候就需要结构体了。 结构体的关键词是struct,那这个该怎么用呢?我们定义一个学生类型
我们使用一下这个结构体
?在main函数中,我们定义两个结构体变量,然后对其初始化,最后打印出来。值得注意的是这个.操作符,是通过结构体变量来找到成员的。 结构体变量.成员名 除此以外我们还可以采用函数的方式来打印结构体,具体代码实现如下
运行结果如下 ?这里有两种打印方式,一种是将结构体指针解引用后使用.操作符。 另外一种是使用->操作符。也就是结构体指针->结构体成员。 ? 总结本节我们讲解了指针与结构体。我们需要对指针有一个深刻的理解。 本站结束,下一站,分支和循环 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/11 12:36:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |