c语言指针改良,重新认识C语言指针(上)(示例代码)
? 独创性并不是首次观察某种新事物,而是把旧的、很早就是已知的,或者是人人都视而不见的事物当新事物观察,这才证明是有真正的独创头脑 —尼采
本文已经收录至我的GitHub,欢迎大家踊跃star 和 issues。
https://github.com/midou-tech/articles
点关注,不迷路!!!
序言
指针是C语言学习者绕不过的一道坎,也是C语言学习者不得绕过的一道坎。辨别一个人C语言学的好赖就看他对指针的理解怎么样。指针内容也是工作面试经常问到的问题。本文将带你重新认识那个绊倒你的指针,以解大家的心头之惑(恨)。
为什么要学习指针?
有同学就要说了,既然指针这么难,这么不通俗易懂,为什么要学习他呢?其他高级语言都是把这块基本屏蔽掉了,不在让程序员直接操作指针,这里不直接操作指的是不让程序员用指针进行运算和强转而不是彻底没有了。举个java的例子
Object obj= new Object();
Object sec= obj;
sec = new Object();
如果你去仔细研究他们的行为,就会发现 obj, sec 都只是一个指向对象的东西,可以为空,也可以修改指向,所以它们其实都是指针,只是 Java 的教材里面不在去提这东西而已,具体原因看我后面讲解便知道了。
? 继续说为什么学习指针,为什么学习指针就必须要说到指针的优点了。
指针可以直接操作变量地址,所以很灵活。
指针操作会减少很多变量的拷贝使得程序性能提升。
可以动态分配内存。
这些优点使得很多后台性能要求很高的系统、游戏内核、一些高并发的中间件都是使用C&C++语言开发出来的。比如强大的linux系统、nginx,mysql、redis等等。
曾经看到一个搞笑的评论,hhh
道生一,一生二,二生三,三生万物
电脑生汇编,汇编生C , C生C++,C/C++生万物
指针是什么?
其实指针看起来复杂,听起来复杂,学起来复杂,但是总结下来指针到底是个啥,也就一句话。
指针就是地址,指针变量就是一个存放内存地址的变量
你没看看错,是的就是这么简单明了。通常我们说的指针就约等于说的是指针变量。
指针和内存地址的关系
很多人不明白指针其实也就是不明白内存地址,所以要想明白指针必须先明白指针和内存之间的关系。在讲内存和指针之间的关系之前先说下什么是内存。
先明白一个问题,什么是内存?编程人员常说的内存指的是什么?
? 内存是电脑的一个硬件组成部分。从单片机的组成我们可以看到,CPU、内存和输入输出接口,就组成一个完整的电脑,其他统统属于外设。内存是可以被CPU通过总线进行操作的,也就是与CPU之间有总线相连接的。电脑所有的输入输出,都是要从内存来实现的。内存包括只读内存ROM和读写内存RAM,但在个人电脑(PC)中,我们通常所说的内存,是指读写内存。
? 程序人员常说的内存其实是虚拟内存,程序直接操作的是虚拟内存而不是真正的物理内存。
纳尼
程序都是操作的虚拟内存? 那虚拟内存是个啥东西?
这里先给大家画张C语言程序的内存布局图。关于进程和内存管理会在后面的文章讲出来,记得微信搜索 龙跃十二 点关注。
这个图很好的描述了内存地址的布局,指针变量里面存放的地址也就是这个内存地址。顺便说下啥是内存地址,用十六进制表示出来的一串数字编号(就好比你家的门牌号),只是这个数字是给内存标号的。32位系统下这个编号是4byte(32个bit)表示的,64位系统下是8byte(64bit)表示的。(这个小问题面试会被问到的)
如何使用指针?
指针的声明
int *p;
char *p1;
float *p2;
声明还是很简单,指针的类型 * 变量名即可声明一个指针变量。
int num = 5;
int *p = #
此时就是一个int类型的指针变量指向一个int变量,画个图解释下。
以很清楚的看到指针p存放着变量num的地址,我们通常说指针p指向变量num,当p知道变量num之后,p就可以对变量num为非作歹了,比如
int main(){
int num = 5;
int *p = #
printf("*p=%d,num=%d
",*p,num); //此时num的值就变为5
p+=1;
printf("*p=%d
",*p); //此时p指向了哪里?这句代码会不会报错?
}
指针的大小和类型
从上面的声明实例可以看到我定义了三种类型的指针,可以看出指针是有类型的。这里有同学就有疑问了,不是存放内存地址的么,内存地址不就是一串十六进制表示的数字么(其实底层都是二进制),哪来的什么类型一说呢,为什么又需要类型呢?
这个疑问很好,我当时学习的时候也是很疑惑。首先我们明白了指针是一个存放地址的变量,明白这点还不够还必须理解另外一个问题就是
字节(Byte)是用于计量存储容量的一种单位,每一个字节由8位组成(1Byte = 8bit)。地址可以理解为在一片内存中,每个字节(Byte)的编号。
所以很多人肯定会明白了,指针存放的是一个变量的首个字节的地址,那么问题来了。
int a = 5;
int *p = &a;
我们声明指针p指向变量a的地址,也就是说指针p里面存放着变量a的首地址,在32位平台下,int a 是4字节,指针去取a的值的时候找到的是a的首地址,那怎么拿到变量a,聪明的同学已经恍然大悟,是的,没错,所以我们的指针需要类型的,编译器去取指针指向的内容时候会根据指针的类型去取。画个图如下
此刻我相信你对指针已经有了很高的理解了。指针的大小很好理解 就是存放地址的范围,地址的范围是操作系统地址线的根数决定,所以指针的大小是随操作系统的寻址范围决定的,一般32位系统地址总线也是32根,寻址范围是2^32次方
顺便说下32位操作系统和64位操作系统的区别在哪里,系统的位数代表运算能力,所谓32位就是能计算的字长是32位的,64位系统能计算的字长是64位。处理器的字长越大,说明它的运算能力越强。
点赞
c语言指针改良,重新认识C语言指针(上)(示例代码)相关推荐
- c语言Null详解,c语言NULL和0区别及NULL详解(示例代码)
先看下面一段代码输出什么: #include int main() { int *p=NULL; printf("%s",p); } 输出 ,单步调试可以看出执行int *p=NU ...
- 智能机器人走迷宫c语言游戏,(动态规划)机器人走迷宫问题(示例代码)
题目一:https://www.nowcoder.com/practice/166eaff8439d4cd898e3ba933fbc6358?tpId=46&tqId=29117&tP ...
- 利用QT加C++语言如何计算MACD指标,并请给出示例代码
MACD(Moving Average Convergence/Divergence)是一种趋势跟踪类指标,主要用于股市趋势判断.它由三部分组成:DIF.DEA和MACD柱. DIF的计算公式如下: ...
- 海盗分椰子c语言编程,水手分椰子——迭代法、递归解题(示例代码)
题目内容: n(1< n <=5)个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的n堆,还剩下1个给了猴子,自己藏起1堆.然后,第2个水手把剩下的n-1堆混合后重新分为等量的n堆, ...
- gmt时间转化函数c语言,时区缩写 UTC, CST, GMT, CEST 以及转换(示例代码)
UTC是协调世界时(Universal Time Coordinated)英文缩写,是由国际无线电咨询委员会规定和推荐,并由国际时间局(BIH)负责保持的以秒为基础的时间标度.UTC相当于本初子午线( ...
- C语言电池电压检测程序,电池温度检测原理和示例代码
一.原理 其实电池内部有个热敏电阻, 与外部分压电阻构成一个简单的分压电路, 根据ADC采样得到的电压j计算热敏阻值再反推此时的温度, 首先我们要先了解热敏电阻阻值和温度一个公式: /*NTC热敏电 ...
- 多人过河问题C语言贪心算法,过河问题(贪心算法)(示例代码)
一.问题描述 在漆黑的夜里,甲乙丙丁共四位旅行者来到了一座狭窄而且没有护栏的桥边.如果不借助手电筒的话,大家是无论如何也不敢过桥去的.不幸的是,四个人一共只带 了一只手电筒,而桥窄得只够让两个人同时过 ...
- c语言综合合计实验报告,C语言设计实验报告(第一次)
C程序设计实验报告 实验项目:PPT实验:1.3.2:1.3.3:1.3.4:2.3.1:2.3.2 姓名: 龚政 实验地点:家 实验时间:2020.02.25 一.实验目的与要求 1.实验目 ...
- c语言单向链表插入字符串,C语言之单向链表
1,单向链简洁. 单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的: ...
最新文章
- iis+nginx实现负载均衡
- SDUT-3378_数据结构实验之查找六:顺序查找
- 一位算法工程师从30+场秋招面试中总结出的超强面经——目标检测篇(含答案)
- 祝贺王远当选为中国区第二位 Teams MVP
- “平行驾驶”是无人车上路的安全高效智能途径!
- J-Rooms及时会议室 v4.5.5333.1104
- 【英语学习】【Daily English】U01 Greetings / L01 Same old, same old
- 计蒜客挑战难题:A+B+C问题
- JavaScript 中的相等检测
- 梯度下降和delta法则
- AD19调用器件封装时报错Access violation at address 0000000141A9EDD4 in module 'IntegratedLibrary.DLL'.
- 如何修正Linux下面MySQL中文乱码问题
- Servlet线程安全性
- Qt_ERRO Rundefined reference to `vtable for XXX'
- 通过url直接访问项目图片
- yum无法安装wget
- iShare.js分享插件
- matlab中画三瓣花瓣,如何绘制漂亮的“花瓣”韦恩图?
- raid5用户mbr还是gpt_对硬盘进行分区时,GPT和MBR有什么区别?
- ZIP 压缩解压命令