先介绍本文的介绍顺序哈
一、基本数据类型和内存的关系(为后面讲数组和指针关系做铺垫)
二、指针的基本介绍和本质的剖析
三、数组的基本介绍和本质剖析
四、数组和指针的关系剖析
五、数组与指针在实际工程中应用的问题
那么,废话不多说,咱们直接整干货。。。
一、数据类型和内存的关系
数据类型
首先咱们的了解下数据类型有哪些,来张图,咱们开心下。。。
(清晰度不是很好,各位看官咱们将就下,不影响咱们后续的讲述,当然也可以自己在网上搜索)
基本类型简单提一下我觉得可能需要用的东西
1.在不同位的机器上,其同一数据类型的大小也不一样(大小,是指什么的大小嘞?嘿嘿)
举个例子,可以查询下int型在自己机器上所占内存的字节数(没错,是内存的大小,千万别理解成范围的大小,int(signed:-32767~32767/unsigned:0~65535)其范围大小固定,没什么可说的)
printf("sizeof(int):%d", sizeof(int));
//sizeof用法我姐不介绍了,不懂的去查下咯
(我这里没什么问题,32位的机器,4个字节,一般16位的可能2个字节)
咳咳,这个稍微提下内存,对内存不够清楚的,咱们继续往下走
2.空类型(void)
这个可不能像前几个一样可以用来声明一般型变量类型
例如
void a;
编译器会给你报错。原因是声明一个void类型,编译器并不知道要给你这个变量分配多大的内存。
但是But 可以声明无类型的指针
void *flag; //我就不赋初地址了
(关于void的指针我会在后面将指针会系统说到,不知道void类型指针做什么用的或者在什么场合下会用到,小白咱们偷偷往下看)
void 初学者常常会见到
void CS(void)
当然函数名我随便起的,第一个void声明CS为空类型,也就是CS没有返回值或者CS返回值为空类型
第二个void表示CS没有形参。
当然也可以声明类型为无类型指针的函数,其中malloc()就是此类型,它返回了一个无类型的指针。
好,基本类型,我就介绍到这,下面,我给各位看官抛个砖。
请问:变量的本质是什么?
A同学会这样说 变量就是可以变化的量,可以向变量读写数据(这句话有几个错呢?无奖精彩哟,猜中获得题主口头称赞一次)
int a=0,b=0;
a=5;
一般变量无非就是这几种操作:定义,读,写。
A同学说的这句话,可以说是初学的层次。来我们先揭下变量的面纱,最后只有赤诚相对,才能真正提升。。。
变量概念可以这样理解(开始粗暴的要撕下面纱了,敲黑板)
变量!!!可以理解为固定大小内存的别名,或者说一段连续内存空间的别名,像一个门牌号
(不懂,没有关系,接下来,我们赤诚相对,必有收获)
所谓定义 int a;它就是程序用来申请和命名内存空间,自此之后我们可以通过变量名a,来访问编译器给我们分配的内存空间。
也就是说上面A同学说的后一句的话改成:可以通过变量向内存进行读写数据的操作。就没有什么问题了。
(有一点指针基础又不是很清楚的同学可能在这里混淆,不过没关系,后面指针也会有讲到,通过对比相信你会理解的)
下面我们通过实例来论证下
int a=0;
*(int*)2293436=250;
printf("&a:%d\n",&a);
printf("a:%d\n",a);
见证奇迹的时刻到了!!!
诶???我的a怎么是250,想当初它还是个孩子,怎么一转眼a变成250了???
有同学会注意到我第二行代码的操作。没错!问题出在第二行上,偷天换日的就是它。。。
第二行先不做过深的讲解,以免初学者陷的太深。先理解第二行我是通过直接访问变量a所代表的内存空间对变量a所代表的内存空间进行了写操作。
然后我再printf a,此时变量a所代表的内存空间的内容已经被改成了250。因此结果就改变了。
这就说明我前面说的A同学错的不冤枉吧~。
(有同学会说我用指向a的指针也可以做出这个效果啊,这里我也考虑到了,操作指针是间接赋值(如int *p=&a;*p=250;),没有直接通过操作内存标号理解来的更加透彻)
最后再来抛砖
最后总结下
(1)变量的定义 实质是程序听过变量来申请和命名内存空间
(2)变量的本质 实质可以理解为固定大小内存的别名,或者说一段连续内存空间的别名,像一个门牌号
(3)可以通过变量名来对内存进行读写操作,并非是对变量本身进行读写操作
内存(Memory)
内存是什么?
百度会告诉你内存是内部的存储器,作用是用于暂时存放CPU的运算数据,以及与硬盘灯外部存储器交换的数据。只要计算机在运行,CPU就会把需要运算的数据调到内存中去运行。
但是对于咱们这篇学习来说,到这只记住本文所说的内存作用是用来存放数据就OK。
下来我们通过内存四区的概念来深入了解内存
还是直接粗暴上图
这个图表明了个啥意思啊?
通俗的翻译一下
(1)操作系统把硬盘代码Load到内存
(2)操作系统把代码分成四个区进行管理
(3)操作系统找到main函数入口开始执行
这一部分我们重点放在前三个数据储存区的概念理解上。
不多说,上干货,不可避免的概念理解
1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
2、堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时由操作系统回收 。
3、 全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变
量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
程序结束后由系统释放。
4、常量区 :常量字符串就是放在这里的。 程序结束后由系统释放
5、代码区:存放函数体的二进制代码。
后面的后来再更哈