C语言指针浅谈(一)

1.内存和地址

1.1内存     

     在生活中,如果你想到宿舍楼去找你的好基友玩,如果没有房间号码,你就得一个一个去找,效率极其低下,但如果有房间号,你就可以立马找到,效率超高

    对应到计算机中也是同样的道理,我们知道计算机CPU在处理数据时,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那是怎么管理这些内存呢,其实就是把内存划分为一个个的内存单元,每个内存单元的大小取1个字节

其中每个内存单元就相当于一个宿舍,一个人字节空间里面能放8个比特位,相当于宿舍八人间,每个人都是一个比特位。

   每个内存单元都有一个编号,就相当于宿舍门牌号,有了这个编号,CPU就可以快速找到一个内存空间。我们通常把门牌号叫作地址,在计算机中我们也把内存单元的编号称为地址,而C语言给地址起了个新名字:指针

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

1.2如何理解地址

    CPU访问内存中的某个字节空间,应该知道这个字节空间在内存的1什么位置,而内存中字节空间是非常多的,所以就需要给每一个字节空间一个地址。

    而计算机的编址,并不是把每个字节的地址记录下来,而是通过硬件设计完成的。第一,计算机内是有很多的硬件单元的,它们之间相互协同工作,进行数据传递。但是硬件与硬件之间是互相独立的,它们之间通过“线”连接。

    CPU与内存之间也需要进行数据传递,它们之间通过地址总线进行连接,其中64位机器有64根地址总线,每根线有两个状态,表示0和1,那么一根线表示两种含义,两根线表示四种含义,64根地址线,就表示2^64种含义,每一个含义都代表一个地址,地址信息被传达给内存,就可以找到该地址对应的数据,再将数据通过数据总线传入CPU内寄存器。

2.指针变量和地址

2.1指针变量

    理解了内存和地址的关系,为了存储地址,以便后面使用,我们需要创建一个东西来存放,就是:指针变量

    这个变量就是用来存放地址的,存放在指针变量中的值都理解位为地址(指针)

   如上图所示,我们创建了一个指针变量,有的人可能对图中的*和&有疑问

   其实在C语言中*是在声明pa是一个指针(地址)变量,而int是在声明pa存储的地址对应的值是int类型的值

    而&其实是取地址操作符,它负责把a所占4个字节中地址较小的字节的地址取出来,然后再赋值给pa指针变量

2.2解引用操作符

   我们把地址存储起来,怎么使用它呢,在生活中,我们使用地址找到一个房间,然后在房间里可以拿或者放东西,在C语言中也是同理,我们只要拿到了指针(地址),就可以通过它找到地址指向的对象,怎么找到呢,要通过解引用操作符(*)。

     上面的代码中*pa的意思就是通过pa中存放的地址,找到指向的空间,*pa其实就是变量a了,所以*pa=100就把a的值变为了100。

2.3指针变量的大小

     因为指针变量存储的是地址,而根据前面的内容我们了解到,64位机器有64根地址总线,没跟地址线出现的电信号转换成数字信号后是0或1,我们把64根地址线产生的2进制序列当作一个地址,一个地址就是64个比特位,需要8个字节才能存储,所以指针变量的大小在64位机器中就是8个字节,同理在32位机器上就为4个字节       

   所以我们还可以知道,指针变量的大小和类型是无关的,因为地址总是64个比特位,只要是指针变量,在相同平台下,其大小是相同的。

3.指针变量类型的意义

    有的人就会有疑问,既然指针变量大小都是一样的,那为什么还要分指针类型呢,下面就会来讲为什么要分类型

3.1指针的解引用

    对比下面的代码和调试结果

   我们可以看到,结果是不一样的,其实第一个代码将n的4个字节全部变为0,而第二个代码只是将n的第一个字节改为0

   可以得到结论:指针的类型决定了对指针解引用时指向的空间有多大的使用权限(一次能操作几个字节),char*类型的指针解引用一次只能使用一个字节,int*类型的指针解引用一次能使用四个字节。

3.2指针+-整数

     先看一段代码,观察地址的变化

我们可以看出,char*类型的指针变量+1跳过1个字节,int*类型的指针变量+1跳过了4个字节,这就是指针变量的类型不同带来的差异

结论:指针的类型决定了指针向前或向后走一步有多大

3.3void*指针

     在指针类型中有一种特殊的类型是void*类型,理解为无具体类型的指针(或者叫泛型指针),这种类型的指针可以用来接受任意类型地址,都是void*类型指针不能直接进行指针的+-整数和解引用的运算。

我们可以看到,void类型的指针可以接收不同类型的地址,但是不能直接进行指针运算。

那void*类型的指针岂不是没用?并不是这样的

一般void*类型的指针是使用在函数参数的部分,用来接收不同类型数据的地址,这样可以实现泛型编程的效果,使得一个函数来处理多种类型的数据,后续我们会讲到。

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
对于计算机专业的学生而言,参加各类比赛能够带来多方面的益处,具体包括但不限于以下几点: 技能提升: 参与比赛促使学生深入学习和掌握计算机领域的专业知识与技能,如编程语言、算法设计、软件工程、网络安全等。 比赛通常涉及实际问题的解决,有助于将理论知识应用于实践中,增强问题解决能力。 实践经验: 大多数比赛都要求参赛者设计并实现解决方案,这提供了宝贵的动手操作机会,有助于积累项目经验。 实践经验对于计算机专业的学生尤为重要,因为雇主往往更青睐有实际项目背景的候选人。 团队合作: 许多比赛鼓励团队协作,这有助于培养学生的团队精神、沟通技巧和领导能力。 团队合作还能促进学生之间的知识共享和思维碰撞,有助于形成更全面的解决方案。 职业发展: 获奖经历可以显著增强简历的吸引力,为求职或继续深造提供有力支持。 某些比赛可能直接与企业合作,提供实习、工作机会或奖学金,为学生的职业生涯打开更多门路。 网络拓展: 比赛是结识同行业人才的好机会,可以帮助学生建立行业联系,这对于未来的职业发展非常重要。 奖金与荣誉: 许多比赛提供奖金或奖品,这不仅能给予学生经济上的奖励,还能增强其成就感和自信心。 荣誉证书或奖状可以证明学生的成就,对个人品牌建设有积极作用。 创新与研究: 参加比赛可以激发学生的创新思维,推动科研项目的开展,有时甚至能促成学术论文的发表。 个人成长: 在准备和参加比赛的过程中,学生将面临压力与挑战,这有助于培养良好的心理素质和抗压能力。 自我挑战和克服困难的经历对个人成长有着深远的影响。 综上所述,参加计算机领域的比赛对于学生来说是一个全面发展的平台,不仅可以提升专业技能,还能增强团队协作、沟通、解决问题的能力,并为未来的职业生涯奠定坚实的基础。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c++机械师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值