河北网站备案查询系统,网易企业邮箱下载电脑版官方下载,免费做链接的网站,天堂呦呦Hello,CSDN的各位家人们#xff0c;你们好啊#xff01;今天#xff0c;小赵要给大家分享的C语言知识是指针#xff0c;相信不少家人们都或多或少被指针搞得晕头转向#xff0c;小赵一开始也是#xff0c;但后来小赵经过不断地努力学习#xff0c;终于将这里面的知识弄懂… Hello,CSDN的各位家人们你们好啊今天小赵要给大家分享的C语言知识是指针相信不少家人们都或多或少被指针搞得晕头转向小赵一开始也是但后来小赵经过不断地努力学习终于将这里面的知识弄懂了。由于指针的知识点实在太多小赵决定将它分为几个小部分让大家更好地学习和吸收。 目录
内存与地址
⚾内存
⚾地址
指针变量与地址
⚾取地址
⚾指针变量
⚾如何认识指针类型
⚾解指针
⚾指针占多少内存
指针变量类型的意义
不同指针类型的影响
void型指针
const修饰指针
指针运算
指针与整数运算加减
指针与指针运算
指针的大小比较
野指针
野指针是什么
如何避免野指针
assert断言
指针的使用和地址的调用
⚽模拟strlen函数
⚽传值与传址
结束语 内存与地址
⚾内存
在开始指针之前小赵先和你们聊聊内存内存是什么其实我们大多数人心中应该是有自己的一个定义的因为我们的手机啊电脑啊存储一些软件音乐什么的靠的其实就是我们的内存可内存究竟是怎么调用的我们好像并不太清楚也并不太了解。但我们的生活中有一个有意思的例子可以让我们摸清楚就是我们的房子也是用来存东西的存我们的书籍衣服等等那它是怎么调用和找到的其实靠的点就两个一个门牌一个钥匙。 正是这两个东西的存在让我们所有人都可以井然有序的生活不会乱放自己的东西在别人家不会走错门也让自己的东西不会被别人偷。那我们的内存是不是也是一样呢。其实电脑和内存的关系就是下面这张图展现的。 我们的电脑其实就是通过给每个内存编号来进行存储和访问的而这个编号其实就是我们下面要讲的地址了。
⚾地址
如此庞大的内存究竟是靠着怎么编写的地址来进行有序的访问相信这是不少小伙伴们的疑惑其实要解决这个问题还是要借助我们的内存。我们都知道我们的内存存储是分很多的单位。正如下面这张图。 在这些茫茫的内存中我们的地址选择了字节内存把自己分成了无数个细小的字节单位给每一个字节编写编号而这个编号就是我们的地址。 指针变量与地址
⚾取地址
我们说既然每个东西它都有自己的内存也都有自己的地址那我们如何去取出我们的地址呢又该如何去看到我们的地址。那么小赵就在这里为大家演示一下首先呢在我们的C语言中是有一个专门的操作符用来取这个地址的这操作符就叫取地址操作符即。那么如何用呢
利用我们VS的调试的功能 在里面输入我们的地址然后再按一下回车就可以出来我们的地址了。 ⚾指针变量
那么既然已经如此完美了那为什么还要我们指针的存在呢就像你要去往任何一个房屋总要直到它的地址而我们的指针干的就是存地址的活同时它还可以帮助你去打开地址往那块内存里面去存。这一点就相当于什么呢就好比这个房子的主人把自己房子的门牌号告诉给了那个人同时还给了它钥匙让他能够去拥有这个房子的使用权但这个房子其实还是归属于这个房主的在现实中其实也有对应就是租房子给别人的那种感觉。
⚾如何认识指针类型
讲到现在也没把指针长啥样拉出来给大家看看那么现在我们就当当当请出我们的指针来看看这究竟长啥样能如此强大。 其实看完了这个图相必大家也能推出其他类型的指针比如字符指针short类型的指针long.....等一系列指针但其实指针也有一些需要注意的或者说难写的这个我们后面再聊。
⚾解指针
那好了现在指针我们拿到了地址了可你不能光给我地址啊我都租了你好歹让我在你这个房子里倒腾一下这个我们C语言也早就准备好了我们C语言的解指针用的就是*对没错这个是不是超级像你那个钥匙插进去的那个门缝所以这个可好记了下面小赵就要给大家演示一下我们该怎么用这个指针去倒腾这个房子了。 怎么样是不是很神奇其实这里小赵还有一个比较有意思的说法a10,其实就相当于我们家本来的样子*p150,就相当于我们打开家把家倒腾成的样子然后我们再输出家的样子。怎么样还是有意思的吧。 ⚾指针占多少内存
那么我们的指针究竟占多少的内存呢
这个其实这要分情况的首先就是我们x64即64位的版本下面我们可以打出来看看。 接着就是我们的x86(即32位 指针变量类型的意义
相信这个时候就有人问了指针变量所占的内存的大小是一样的吗?那当然是一样的。那为什么还要划分为各种指针类型呢既然大家内存都一样直接用就好了分这么多类干嘛那么接下来小赵就来帮助你去解决这个问题。
不同指针类型的影响
其实我们都知道不同的类型所占的内存大小是不一样的而到了指针这里就完全可以看作是它所控制的内存大小比如你租房子只租给一个人卧室那么对这个人来说他所能改变的其实就只能是这个卧室以内的范围外面的厨房其实他没办法去改变。那么对指针来讲也是一样的。比如你一个指向char类型的指针去指向人家int的类型的指针那你所能改变的也只有人家的四分之一部分咯。 在上面的这些案例中我们不难发现不同类型的指针变量所拥有的权利是不一样的它们的访问权完全由自身所指向的类型的所占的内存大小决定。
void型指针
但一个队伍总会有这么一个特殊的存在也可以说是几乎全能的存在没错这个在指针中可以访问一切类型的指针类型是存在的就是我们的void型指针这个指针类型可以接收所有的指针类型但全能未必是好事它的遗憾就是它无法打开门读取即无法解指针也无法对内存做出任何修改。如果要进入其中修改就必须强制类型转化成其他类型这个我们后边会多次使用这个指针去接收一些其他指针在这里小赵就不多讲了就给大家举个简单的例子吧。 const修饰指针
首先我们先再一次认识一下我们const. const 限定符它把一个对象转换成一个常量。 既然const是把我们修饰的变量转变为常量那你说这个变量还能变吗当然是不能啦。比如我们的常量1还能有一天忽然变了不成当然不可能变啦。下面可以看一下小赵举得一个例子更加深刻地体会一下。 那放到我们的指针上又是怎么样呢
先看第一种 那么这里为什么会报错呢其实这里就相当于是修饰我们指针变量所指的地址的那部分内存就是我把你这部分内存给定下来了既然定下来了那你说这个内存我还能变吗
但是我们p这个租房子的是可以走的你定了房子的样子但不代表我这个租房子的人不能走啊。 我们的p只需要重新去租个房子就好了。
下面看第二种 其实这里也相当于我们的第一种当然小赵在这里有个比较有意思的说法啊就是把这个*p人和钥匙绑一起就是那个房间当成我们租的那块地盘你把我租的地盘定下了那你说这个地盘还能动吗而单独的一个P则相当于一个自由自在的人那它不就可以改变了吗
接下来看第三种。 第三种其实你再用小赵上面的理解就好理解了就是我把你这个租客定下来也就是这个指针变量所指的地址定下来那你说他还自由吗他不久不能换地址了但这时候地址那块空间没定下来那不就可以随便改吗
总结 结论const修饰指针变量的时候 • const如果放在*的左边修饰的是指针指向的内容保证指针指向的内容不能通过指针来改变。 但是指针变量本身的内容可变。 • const如果放在*的右边修饰的是指针变量本身保证了指针变量的内容不能修改但是指针指 向的内容可以通过指针改变。 指针运算
那么接下来就有人要问了指针可以运算吗运算的意义又是什么呢
下面小赵来为你解答。
指针与整数运算加减
指针于整数的与运算上面我们提到了我们地址在内存中是以一个一个的单元存储的每个单元是1个字节那我们的指针与整数的加减运算其实就是跳过了多少个这样的单元而跳过多少个单元的问题那究竟跳过多少个呢其实就是整数*指向的类型所占的字节大小
这里小赵为了方便大家理解用我们的数组做个示范。因为数组里面存储的数据是连续的。 指针与指针运算
那么指针与指针的运算这个就比较有意思了它的结果其实就是这两个地址之间的元素多少当然这个其实我们一般也是数组用的多因为其他的数据都不一定是连续的只有数组我们目前确定是连续的。 指针的大小比较
那么两个指针的大小比较呢其实这个就跟我们的地址高低有关了其实也是后面小赵要与各位聊的但可以透露的一点是数组下面的下标越高它的地址一般越高毕竟也是后创建的。 当然还有一点要提的是我们的数组必须是在一个数组中两个数组是不连续的。
野指针
野指针是什么
野指针往往其实指的就是一块没有被开发的内存就是你这个指针啊没有指向任何地址这个地址就是随机的同时也是不允许被使用的。就像你随便找了一个房子没被人授权这能允许吗 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化其值是随机的指针变量的值是别的变量的地址意味着指针指向了一个地址是不确定的变量此时去解引用就是去访问了一个不确定的地址所以结果是不可知的。 像我们在敲代码时候常遇到的情况有 三种
第一种是由于我们没给它地址。 这时候我们的编译器是会报错的
第二种越界访问。
这里我们跳过了a这块区域然后就是未知区域所以出来的也是随机值。
第三种使用的空间被回收或释放 这里出现的情况就是我们的函数在运行结束后将自己开辟的那块空间收回了所以再找也就是一块野指针了。这里函数栈帧会讲
如何避免野指针
那么如何避免这个野指针呢
方案一
我们把我们的指针上来就指向一个明确的地址。
方案二
给它一个空指针让它什么都没有无法使用。 它既然是一块空区域那你也就没办法塞东西给里面了。
assert断言
assert是用来干嘛呢我们可以先用小赵上次说的网站查查。 我们注意到assert是看你括号里面的东西是否是真的如果错了它就会终止程序的运行。
那么这个就刚好可以判断我们的指针是否是空指针防止我们的错误使用。 指针的使用和地址的调用
好了我们了解上面的一些关于指针的相关知识下面小赵带你去实际应用我们的指针吧。
⚽模拟strlen函数 其实这个函数也是小赵多次提到的一个函数它的主要作用就是去算一个字符串在\0之前的字母数同时还要注意的一点是它的是要头文件的即#includestring.h 那我们究竟该如何实现呢在这里小赵就不卖关子了。
int my_strlen(char* a)
{int count 0;while (*a ! \0)//*a不等于\0,继续运行{a;//看下一个字母count;//统计字母数量}return count;//返回字母数量
}
int main()
{char a[10] abcdef;int m my_strlen(a);printf(%d, m);} ⚽传值与传址
其实之前学完函数后就有不少人有这样的困惑了就是要给两个变量在函数里面换值的无法成功这其实是因为函数里面创建的变量都是临时变量当函数运行完了这些代码的空间什么的都会回收我们的值就像我们输入进去给它们里面的两个在里面换但人间不会影响到你外面的人
但如果这里你用我们的地址就不一样了因为我们如果用地址那么它就可以开打开我们这边的房间对我们进行换值了。
void Swap(int* px, int* py)//传入的地址给你
{int tmp 0;tmp *px;//这部分和之前的交换一样*px *py;*py tmp;
}
int main()
{int a 0;int b 0;scanf(%d %d, a, b);printf(交换前a%d b%d\n, a, b);Swap(a, b);printf(交换后a%d b%d\n, a, b);return 0;
} 结束语
好了小赵今天的分享就到这里了如果大家有什么不明白的地方可以在小赵的下方留言哦同时如果小赵有什么地方说得不对也希望得到大家的指点谢谢各位家人们的支持。你们的支持是小赵创作的动力加油。
如果觉得文章对你有帮助的话还请点赞关注收藏支持小赵如有不足还请指点小赵及时改正感谢大家支持