精品-清华大学C语言课件 第15章01 内存组织方式
合集下载
清华大学C语言教学课件(共16个PPT)第1个共26页文档
常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
55、 为 中 华 之 崛起而 读书。 ——周 恩来
清华大学C语言教学课件(共16个PPT)
第1个
21、没有人陪你走一辈子,所以你要 适应孤 独,没 有人会 帮你一 辈子, 所以你 要奋斗 一生。 22、当眼泪流尽的时候,留下的应该 是坚强 。 23、要改变命运,首先改变自己。
24、勇气很有理由被当作人类德性之 首,因 为这种 德性保 证了所 有其余 的德性 。--温 斯顿. 丘吉尔 。 25、梯子的梯阶从来不是用来搁脚的 ,它只 是让人 们的脚 放上一 段时间 ,以便 让别一 只脚能 够再往 上登。
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
55、 为 中 华 之 崛起而 读书。 ——周 恩来
清华大学C语言教学课件(共16个PPT)
第1个
21、没有人陪你走一辈子,所以你要 适应孤 独,没 有人会 帮你一 辈子, 所以你 要奋斗 一生。 22、当眼泪流尽的时候,留下的应该 是坚强 。 23、要改变命运,首先改变自己。
24、勇气很有理由被当作人类德性之 首,因 为这种 德性保 证了所 有其余 的德性 。--温 斯顿. 丘吉尔 。 25、梯子的梯阶从来不是用来搁脚的 ,它只 是让人 们的脚 放上一 段时间 ,以便 让别一 只脚能 够再往 上登。
清华大学C语言教学课件(共16个PPT)第2个共33页
16、业余生活要有意义,不要越轨。——华盛顿 17、一个人即使已登上顶峰,也仍要自强不息。——罗素·贝克 18、最大的挑战和突破在于用人,而用人最大的突破在于信任人。——马云 19、自己活着,就是为了使别人过得更美好。——雷锋 20、要掌握书,莫被书掌握;要为生而读,莫为读而生。——布尔沃
清华大学C语言教学课件(共16个PPT) 第2个
16、自己选择的路、跪着也要把它走 完。 17、一般情况下)不想三年以后的事, 只想现 在的事 。现在 有成就 ,以后 才能更 辉煌。
18、敢于向黑暗宣战的人,心里必须 充满光 明。 19、学习的关键--重复。
20、懦弱的人只会裹足不前,莽撞的 人只能 引为烧 身,只 有真正 勇敢的 人才能 所向披 靡。
ENDቤተ መጻሕፍቲ ባይዱ
精品-清华大学C语言课件 第15章04 变量的存储类别
通过实例4.14和实例4.13的比较,可以看出static变量和auto变量之间的区别。由于函数调用结束后 auto类型的变量的值不能被保留,所以第二次调用AddOne函数输出的结果仍然是3;而static变量是 从被定义开始直到整个程序结束一直保留其内存空间,所以,第二次调用AddOne函数输出的结果是4。
extern变量称为外部存储变量。extern声明了程序中将要用到的、但尚未定义的外部变量。通常, 外部存储类都用于声明在另一个转换单元中定义的变量。
一个工程是由多个C文件组成的。这些源代码文件分别编译,然后连接成一个可执行模块。把这样 的一个程序作为一个工程进行管理,并且生成一个工程文件来记录所包含的所有源代码文件。
只有局部自动变量和形式参数才能做寄存器变量,因为寄存器变量属于动态存储方式,凡采用静 态存储方式的量都不能定义为寄存器变量。
使用extern变量
在介绍extern存储类型之前,先来澄清一个概念——变量的声明和定义。变量的声明是告知编译 器变量的名称和数据类型;变量的定义将为变量分配存储区域。通常情况下,变量的声明也被认为是 变量的定义,但是可以使用extern关键字只声明而不定义变量。
下面总结一下static变量和auto变量之间的区别。
静态存储类型的局部变量是在静态存储区内分配内存单元。在程序的整个运行期间内都不释放空 间。而自动类型的局部变量属于动态存储类型,是在动态存储区内分配存储单元的,函数调用结束后 存储单元即被释放。
静态局部变量是在编译时赋初始值,并且只赋一次初值,在以后每次调用函数时,都不再重新为 其赋值,只是使用上一次函数被调用结束时变量的值。而自动局部变量的初值不是在编译时赋予的, 而是在函数调用时赋予的,每调用一次函数都对变量重新赋一次初值。
extern变量称为外部存储变量。extern声明了程序中将要用到的、但尚未定义的外部变量。通常, 外部存储类都用于声明在另一个转换单元中定义的变量。
一个工程是由多个C文件组成的。这些源代码文件分别编译,然后连接成一个可执行模块。把这样 的一个程序作为一个工程进行管理,并且生成一个工程文件来记录所包含的所有源代码文件。
只有局部自动变量和形式参数才能做寄存器变量,因为寄存器变量属于动态存储方式,凡采用静 态存储方式的量都不能定义为寄存器变量。
使用extern变量
在介绍extern存储类型之前,先来澄清一个概念——变量的声明和定义。变量的声明是告知编译 器变量的名称和数据类型;变量的定义将为变量分配存储区域。通常情况下,变量的声明也被认为是 变量的定义,但是可以使用extern关键字只声明而不定义变量。
下面总结一下static变量和auto变量之间的区别。
静态存储类型的局部变量是在静态存储区内分配内存单元。在程序的整个运行期间内都不释放空 间。而自动类型的局部变量属于动态存储类型,是在动态存储区内分配存储单元的,函数调用结束后 存储单元即被释放。
静态局部变量是在编译时赋初始值,并且只赋一次初值,在以后每次调用函数时,都不再重新为 其赋值,只是使用上一次函数被调用结束时变量的值。而自动局部变量的初值不是在编译时赋予的, 而是在函数调用时赋予的,每调用一次函数都对变量重新赋一次初值。
清华大学C语言教学课件(共16个PPT)第1个共26页
清华大学C语言教学课件(共16个PPT) 第1个
•
6、黄金时代是在我们的前面,而不在 我们的 后面。
•
7、心急吃不了热汤圆。
•
8、你可以很有个性,但某些时候请收口 (蹩脚 的工人 总是说 工具不 好)。
•
10、只要下定决心克服恐惧,便几乎 能克服 任何恐 惧。因 为,请 记住, 除了在 脑海中 ,恐惧 无处藏 身。-- 戴尔. 卡耐基 。
55、 为 中 华 之 崛起而 读书。 ——周 恩来
谢谢!
51、 天 下 之 事 常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
•
6、黄金时代是在我们的前面,而不在 我们的 后面。
•
7、心急吃不了热汤圆。
•
8、你可以很有个性,但某些时候请收口 (蹩脚 的工人 总是说 工具不 好)。
•
10、只要下定决心克服恐惧,便几乎 能克服 任何恐 惧。因 为,请 记住, 除了在 脑海中 ,恐惧 无处藏 身。-- 戴尔. 卡耐基 。
55、 为 中 华 之 崛起而 读书。 ——周 恩来
谢谢!
51、 天 下 之 事 常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
清华C--语言程序设计:第15章-多态性PPT课件
void show() const;
private:
double x,y;
double r;
};
#endif
.
18
例子2:抽象基类的例子(3/6)
//文件circle.cpp,实现类Circle #include "circle.h" Circle::Circle(double a, double b, double c) {
第15章 多态性
.
1
讲授内容
静态绑定和动态绑定的概念 多态性的意义和作用 虚函数的定义方法 抽象基类的作用和定义方法 虚析构函数的作用和使用方法 如何在程序中实现多态性
.
2
15.1 多态性的概念(1/5)
多态性:具有继承关系的类,其对象对 同一个函数调用可以作出不同的响应
同一个函数调用——同一条函数调用语句 不同的响应——执行不同的函数
x = a; y = b; r = c; } double Circle::area() const { return PI*r*r; }
.
6
15.1 多态性的概念(5/5)
多态性有助于提高程序的可扩展性
可以把控制模块与被操作的对象分开 可以添加已定义类的新对象,并能管理该对象 可以添加新类(已有类的派生类)的新对象,并能
管理该对象
常用的程序设计方法
为具有继承关系的类定义接口(虚函数) 用链表或数组组织所有对象 用基类指针操作这些对象
.
13
15.3 抽象基类和纯虚函数(2/4)
解决方法
不实现这些接口:纯虚函数 包含纯虚函数的类:抽象基类
抽象基类不能实例化对象
形状类Shape的对象是什么?
C语言详细教程(完整版)ppt课件
C语言有很多种,如:Microsoft C、Turbo C、
Quick C、Borland C++、Visual C等。本课程通
.
过Turbo C的环境来学习C语言。
C Programming Language
三、C程序格式和结构特点
例1.1 第一个程序 Hello,World!
/* example1.1 The first C Program*/
– 答疑时间:星期四 12:00~13:30 – 地点:鉴主-12楼-计算机技术研究所 – 第6周到第18周
考试
. C Programming Language
上机安排
地点:南湖计算中心机房
时间:待定 上机内容:随教学进度根据配套的实验书( 上机调试每次课堂作业) 要求:
• 所有作业必须独立完成
• 作业必须经上机调试通过
. C Programming Language
开始
N=0
N<10吗?
Y
输入 X
X>=0吗? N N=N+1
N
结束
Y 输出 X
[例1.4] 输入10个数,求它们的平均值。
N=0, SUM=0 当N<10 输入X SUM=SUM+X N=N+1 AVER=SUM/10 输出AVER的值
. C Programming Language
定点法
数制转换
数值数据:二进制
浮点法
数据
西文:ASCII
非数值数据:编码 汉字:国标码
. C Programming Language
图形:……
有符定点整数
ds dn dn-1 dn-2 ……..
C语言课件(非常详细)
内存释放
使用free函数释放已分配 的内存,避免内存泄漏。
内存管理工具
使用工具如Valgrind检测 内存泄漏和错误。
内存管理注意事项和常见错误
内存对齐
某些硬件平台要求数据 对齐,否则访问会引发
错误。
野指针
指向无效地址的指针, 可能导致程序崩溃。
内存越界
访问数组或内存区域越 界,可能导致未定义行
为。
重复释放
重复释放同一块内存, 导致程序崩溃或未定义
行为。
05
C语言文件操作和程序调试
文件的基本操作
文件打开
使用fopen()函数打开文件,指 定文件名和打开模式。
文件读写
使用fread()、fwrite()函数进行 文件的读写操作。
文件关闭
使用fclose()函数关闭已打开的 文件。
文件指针操作
02
C语言基础语法
数据类型
浮点型
包括float、double 等,用于存储小数 。
布尔型
bool,用于存储真 或假。
整型
包括int、short、 long等,用于存储 整数。
字符型
char,用于存储单 个字符。
指针型
用于存储内存地址 。
运算符和表达式
关系运算符
==、!=、>、<等,用于比较 两个值的大小关系。
位运算符
&、|、~、^等,用于对二进 制位进行操作。
算术运算符
+、-、*、/等,用于进行数学 运算。
逻辑运算符
&&、||、!等,用于进行逻辑 运算。
其他运算符
()、[]、->等,用于改变运算 顺序或访问结构体成员。
清华大学C语言教学课件(共16个PPT)第2个共33页
26、要使整个人生都过得舒适、愉快,这是不可能的,因为人类必须具备一种能应付逆境的态度。——卢梭
▪
27、只有把抱怨环境的心情,化为上进的力量,才是成功的保证。——罗曼·罗兰
▪
28、知之者不如好之者,好之者不如乐之者。——孔子
▪
29、勇猛、大胆和坚定的决心能够抵得上武器的精良。——达·芬奇
▪
30、意志是一个强壮的盲人,倚靠在明眼的跛子肩上。——叔本华
谢谢!
33
清华大学C语言教学课件(共16个PPT) 第2个
51、山气日夕佳,飞鸟相与还。 52、木欣欣以向荣,泉涓涓而始流。
53、富贵非吾愿,帝乡不可期。 54、雄发指危冠,猛气冲长缨。 55、土地平旷,屋舍俨然,有良田美 池桑竹 之属, 阡陌交 通,鸡 犬相闻 。
▪
清华大学C 课程PPT课件
• 引入了类的机制,最初的C++被称为“带类
语 的C” 言 • 1983年正式取名为C++ 概 • 从1989年开始C++语言的标准化工作 述 • 于1994年制定了ANSI C++标准草案
• 于1998年11月被国际标准化组织(ISO)批 准为国际标准。2003年发布了C++标准第二 版,成为目前的C++
j = 50000;
i = j;//将unsigned short赋值给signed short变量
cout <<" The short int is:"<< i <<endl; //整型数值溢出
cout <<" The short unsigned int is:"<< j<<endl;
return 0; }
15
第15页/共99页
基 数据类—型整型数据及取值范围
本
数 类型
说明符 位数 数值范围
据 短整
short 16 -32768~32767
类 基本
int
32 -231~(231-1)
型 长整
long
32 -231~(231-1)
和 无符号
表 unsigned short 16 0~65535
达 式
unsigned int unsigned long
赋值运算符和—赋值—表达赋式值表达式举例 基
本 数 据
a=5
表达式值为5
a=b=c=5 表达式值为5,a,b,c均为5
类
a=5+(c=6) 表达式值为11,a为11,c为6
C语言程序设计(上)清华大学出版社PPT课件
"\nluck"
字符串常量的长度 : – 所包含的字符个数
字符串常量的存储方式:
所占存储单元数:串长度+1
例如:
a \0
字符串 结束标记
\n l u c k \0
3. 变量
26
1) 变量的有关概念
在程序运行过程中,其值改变的数据,称
为变量,变量用标识符表示,称为变量名。
变量必须“先定义后使用”
占内存(位) 占内存(字节)
数值范围
有效位数
32
4
3.4E-38~3.4E+38
7
64
8
1.7E-308~1.7E+308
16
80
10
1.2E-493~1.2E+4932
19
35
(2)表示方式。实型常数的表示方式如下。 十进制数:例如6.2,.96,-387.29。 指数形式:例如-2.3E3,-7.5E-3。
007 008 012 010 013 009 011 092 063 039 034 000
40
③字符串常量。字符串常量是由一对双引号 括起来的字符序列。例如:"BOOK",
“$20.5”等都是合法的字符串常量。 ④字符变量。字符变量的取值是字符常量,
即单个字符。字符变量的类型说明符是char。 ⑤符号常量。在C语言中可以用一个标识符
表2.3 字符型数据所占位数
数据类型 类 型 符
有符号字 符型
无符号字 符型
char unsigne
d char
占内 存 ( 位)
8 8
占内存 (字 节)
1 1
数值范围 (ASCII码值)
-128~127(有 符号字符型)
字符串常量的长度 : – 所包含的字符个数
字符串常量的存储方式:
所占存储单元数:串长度+1
例如:
a \0
字符串 结束标记
\n l u c k \0
3. 变量
26
1) 变量的有关概念
在程序运行过程中,其值改变的数据,称
为变量,变量用标识符表示,称为变量名。
变量必须“先定义后使用”
占内存(位) 占内存(字节)
数值范围
有效位数
32
4
3.4E-38~3.4E+38
7
64
8
1.7E-308~1.7E+308
16
80
10
1.2E-493~1.2E+4932
19
35
(2)表示方式。实型常数的表示方式如下。 十进制数:例如6.2,.96,-387.29。 指数形式:例如-2.3E3,-7.5E-3。
007 008 012 010 013 009 011 092 063 039 034 000
40
③字符串常量。字符串常量是由一对双引号 括起来的字符序列。例如:"BOOK",
“$20.5”等都是合法的字符串常量。 ④字符变量。字符变量的取值是字符常量,
即单个字符。字符变量的类型说明符是char。 ⑤符号常量。在C语言中可以用一个标识符
表2.3 字符型数据所占位数
数据类型 类 型 符
有符号字 符型
无符号字 符型
char unsigne
d char
占内 存 ( 位)
8 8
占内存 (字 节)
1 1
数值范围 (ASCII码值)
-128~127(有 符号字符型)
C语言(清华大学出版社)ppt课件
结构。 (4)具有结构化的控制语句 ,是完全模块化
和结构化的语言。 (5)语法限制不太严格,程序设计自由度大。
C程序设计(第三版)
C语言的特点
(6)允许直接访问物理地址,能进行位操 作,能实现汇编语言的大部分功能,可直接 对硬件进行操作。兼有高级和低级语言 的特点 。
(7)目标代码质量高,程序执行效率高。 只比汇编程序成的目标代码效率低10 %-20%。
C程序设计(第三版)
算法如下 :
S1:输入n
S2:i=2
(i作为除数)
S3:n被i除,得余数r
S4:如果r=0,表示n能被i整除,则打印n“不 是素数”,算法结束。否则执行S5
S5:i+1→i
S6:如果i≤n-1,返回S3。否则打印 n “是素
实际上,n不必被2到(n-1)的整数除,只需 被2到n/2间整数除,甚至只需被2到 之n 间的 整数除即可。
C程序设计(第三版)
说明: 本程序的作用是输出一行信息:
1.3 简单的C语Th言is程i序s a介C绍program.
#include <stdio.h>
/*文件包含*/
main( )
/*主函数 */
{
/*函数体开始*/
printf ("This is a C program.\n"); /*输出语句*/
(8)程序可移植性好(与汇编语言比)。基 本上不做修改就能用于各种型号的计算 机和各种操作系统。
C程序设计(第三版)
1.2 C语言的特点
问题:既然有了面向对象的C++语言,为 什么还要学习C语言?
解释1:C++是由于开发大型应用软件的需 要而产生的,并不是所有的人都要去编 写大型软件。
和结构化的语言。 (5)语法限制不太严格,程序设计自由度大。
C程序设计(第三版)
C语言的特点
(6)允许直接访问物理地址,能进行位操 作,能实现汇编语言的大部分功能,可直接 对硬件进行操作。兼有高级和低级语言 的特点 。
(7)目标代码质量高,程序执行效率高。 只比汇编程序成的目标代码效率低10 %-20%。
C程序设计(第三版)
算法如下 :
S1:输入n
S2:i=2
(i作为除数)
S3:n被i除,得余数r
S4:如果r=0,表示n能被i整除,则打印n“不 是素数”,算法结束。否则执行S5
S5:i+1→i
S6:如果i≤n-1,返回S3。否则打印 n “是素
实际上,n不必被2到(n-1)的整数除,只需 被2到n/2间整数除,甚至只需被2到 之n 间的 整数除即可。
C程序设计(第三版)
说明: 本程序的作用是输出一行信息:
1.3 简单的C语Th言is程i序s a介C绍program.
#include <stdio.h>
/*文件包含*/
main( )
/*主函数 */
{
/*函数体开始*/
printf ("This is a C program.\n"); /*输出语句*/
(8)程序可移植性好(与汇编语言比)。基 本上不做修改就能用于各种型号的计算 机和各种操作系统。
C程序设计(第三版)
1.2 C语言的特点
问题:既然有了面向对象的C++语言,为 什么还要学习C语言?
解释1:C++是由于开发大型应用软件的需 要而产生的,并不是所有的人都要去编 写大型软件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
当函数A的实参压入栈后,函数B就在栈中以自变量的形式建立了形参。函数B内部的其他自变量 也是存放在栈里的。由于这些进栈操作,栈指针已经移到所有这些局部变量之下。但是函数B记录了 刚开始执行时的初始栈指针,以这个指针为参考,用正偏移量或负偏移量来访问栈中的变量。
当函数B正准备返回时,系统弹出栈中的所有自变量,这时栈指针移到了函数B刚开始执行时的位 置。接着,函数B返回,系统从栈中弹出返回地址,函数A就可以继续执行了。
内存组织方式
本讲大纲
1.内存组织方式 2.堆与栈 实例1 在堆中分配内存并释放 实例2 栈在函数调用时的操作
内存组织方式
开发人员将程序编写完成之后,程序要先装载到计算机的内核或者半导体内存中,然后再运行程 序。程序被组织成4个逻辑段: 可执行代码 静态数据 可执行代码和静态数据,存储在固定的内存位置。 动态数据(堆) 程序请求动态分配的内存来自内存池,也就是上面所列举中的堆。 栈
图15.1 错误提示
栈 程序不会像处理堆那样的在栈中显示地分配内存。当程序调用函数和声明局部变量时,系统将自动
分配内存。 栈是一个后进先出的压入弹出式的数据结构。在程序运行时,是每次向栈中压入一个对象,然后栈指
针向下移动一个位置。当系统从栈中弹出一个对象时,最近进栈的对象将被弹出,然后栈指针向上移动 一个位置。如果栈指针位于栈顶,表示栈是空的;如果栈指针指向最下面的数据项的后一个位置,表示 栈为满的。其过程如图15.2所示:
在内存的全局存储空间当中,用于程序动态分配和释放的内存块称为自由存储空间,通常也称之为堆。 在C程序中,是用malloc函数和free函数来从堆中动态的分配和释放内存。 注意: 在使用malloc函数和free函数时,要加上头文件#include<stdlib.h>,否则调试程序就会出现报错,如 图15.1所示。
那么栈是如何工作的呢?例如当一个函数A调用另一个函数B时,运行时系统将会把函数A的所有 实参和返回地址压入到栈中,栈指针将移到合适的位置来容纳这些数据。最后进栈的是函数A的返回 地址。
当函数B开始执行后,系统把函数B的自变量压入到栈中,并把栈指针再向下移,以保证有足够的 空间来存储函数B声明的所有自变量。
局部数据对象、函数的参数以及调用函数和被调用函数的联系放在称为栈的内存池中。 但是以上的4类根据操作平台和编译器的不同,堆和栈可以是被所有同时运行的程序共享的操作 系统资源,也可以是使用程序独占的局部资源。
堆与栈
在内存组织方式可以看到堆是用来存放动态分配内存空间的,而栈是用来存放局部数据对象、函数的 参数、调用函数和被调用函数的联系。接下来对两者进行详细的说明。 堆
当函数A继续执行时,系统还能从栈中弹出调用者的实参,于是栈指针又回到了调用发生前的位 置。
实例1 在堆中分配内存并释放
在本实例中,使用malloc分配一个整型变量的内存空间,在使用完该空间后。使用free函数进行释放。
#include<stdio.h> #include <stdlib.h> int main() { int *pInt;/*定义整型指针*/ pInt=(int*)malloc(sizeof(int));/*分配内存*/ *pInt=100;/*使用分配内存*/ printf("数值是:%d\n",*pInt);/*输出显示数值*/ free(pInt);/*释放内存*/ return 0; }
运行程序,显示效果如图15.4所示:
图15.4 栈在函数调用时的操作 在本程序中,定义函数A和B,其中在函数A中再次调用函数B。根据栈的原理移动栈中指针,进行 存储数据。
Thank you
பைடு நூலகம்
图15.2 栈操作
程序员经常会利用栈这种数据结构来处理那些最适用后进先出逻辑来描述的编程问题。这里讨论 的栈在程序中都会存在,它不需要程序员编写代码去维护,而是由运行时系统自动处理的。所谓的运 行时系统维护,实际上就是编译器所产生的程序代码。尽管在源代码中看不到他们,但程序员应该对 此有所了解。这个特性和后进先出的特性是栈明显区别于堆的标志。
运行程序,显示效果如图15.3所示:
图15.3 在堆中分配内存并释放 在程序中代码中,首先使用malloc分配一个整型变量的内存空间,通过指向该内存空间的指针,使用 该空间保存数据,然后使用free将整型变量的内存释放。
实例2 栈在函数调用时的操作
在本实例中,对上面栈的描述操作过程使用实例进行说明。其中函数的名称根据上面描述中所定。 通过该实例能够更好的理解栈的操作过程。
#include<stdio.h> void DisplayB(char* string)/*函数B*/ { printf("%s\n",string); } void DisplayA(char* string)/*函数A*/ { char String[20]="LoveWorld!"; printf("%s\n",string); DisplayB(String);/*调用函数B*/ } int main() { char String[20]="LoveChina!"; DisplayA(String);/*将参数传入函数A中*/ return 0; }
当函数B正准备返回时,系统弹出栈中的所有自变量,这时栈指针移到了函数B刚开始执行时的位 置。接着,函数B返回,系统从栈中弹出返回地址,函数A就可以继续执行了。
内存组织方式
本讲大纲
1.内存组织方式 2.堆与栈 实例1 在堆中分配内存并释放 实例2 栈在函数调用时的操作
内存组织方式
开发人员将程序编写完成之后,程序要先装载到计算机的内核或者半导体内存中,然后再运行程 序。程序被组织成4个逻辑段: 可执行代码 静态数据 可执行代码和静态数据,存储在固定的内存位置。 动态数据(堆) 程序请求动态分配的内存来自内存池,也就是上面所列举中的堆。 栈
图15.1 错误提示
栈 程序不会像处理堆那样的在栈中显示地分配内存。当程序调用函数和声明局部变量时,系统将自动
分配内存。 栈是一个后进先出的压入弹出式的数据结构。在程序运行时,是每次向栈中压入一个对象,然后栈指
针向下移动一个位置。当系统从栈中弹出一个对象时,最近进栈的对象将被弹出,然后栈指针向上移动 一个位置。如果栈指针位于栈顶,表示栈是空的;如果栈指针指向最下面的数据项的后一个位置,表示 栈为满的。其过程如图15.2所示:
在内存的全局存储空间当中,用于程序动态分配和释放的内存块称为自由存储空间,通常也称之为堆。 在C程序中,是用malloc函数和free函数来从堆中动态的分配和释放内存。 注意: 在使用malloc函数和free函数时,要加上头文件#include<stdlib.h>,否则调试程序就会出现报错,如 图15.1所示。
那么栈是如何工作的呢?例如当一个函数A调用另一个函数B时,运行时系统将会把函数A的所有 实参和返回地址压入到栈中,栈指针将移到合适的位置来容纳这些数据。最后进栈的是函数A的返回 地址。
当函数B开始执行后,系统把函数B的自变量压入到栈中,并把栈指针再向下移,以保证有足够的 空间来存储函数B声明的所有自变量。
局部数据对象、函数的参数以及调用函数和被调用函数的联系放在称为栈的内存池中。 但是以上的4类根据操作平台和编译器的不同,堆和栈可以是被所有同时运行的程序共享的操作 系统资源,也可以是使用程序独占的局部资源。
堆与栈
在内存组织方式可以看到堆是用来存放动态分配内存空间的,而栈是用来存放局部数据对象、函数的 参数、调用函数和被调用函数的联系。接下来对两者进行详细的说明。 堆
当函数A继续执行时,系统还能从栈中弹出调用者的实参,于是栈指针又回到了调用发生前的位 置。
实例1 在堆中分配内存并释放
在本实例中,使用malloc分配一个整型变量的内存空间,在使用完该空间后。使用free函数进行释放。
#include<stdio.h> #include <stdlib.h> int main() { int *pInt;/*定义整型指针*/ pInt=(int*)malloc(sizeof(int));/*分配内存*/ *pInt=100;/*使用分配内存*/ printf("数值是:%d\n",*pInt);/*输出显示数值*/ free(pInt);/*释放内存*/ return 0; }
运行程序,显示效果如图15.4所示:
图15.4 栈在函数调用时的操作 在本程序中,定义函数A和B,其中在函数A中再次调用函数B。根据栈的原理移动栈中指针,进行 存储数据。
Thank you
பைடு நூலகம்
图15.2 栈操作
程序员经常会利用栈这种数据结构来处理那些最适用后进先出逻辑来描述的编程问题。这里讨论 的栈在程序中都会存在,它不需要程序员编写代码去维护,而是由运行时系统自动处理的。所谓的运 行时系统维护,实际上就是编译器所产生的程序代码。尽管在源代码中看不到他们,但程序员应该对 此有所了解。这个特性和后进先出的特性是栈明显区别于堆的标志。
运行程序,显示效果如图15.3所示:
图15.3 在堆中分配内存并释放 在程序中代码中,首先使用malloc分配一个整型变量的内存空间,通过指向该内存空间的指针,使用 该空间保存数据,然后使用free将整型变量的内存释放。
实例2 栈在函数调用时的操作
在本实例中,对上面栈的描述操作过程使用实例进行说明。其中函数的名称根据上面描述中所定。 通过该实例能够更好的理解栈的操作过程。
#include<stdio.h> void DisplayB(char* string)/*函数B*/ { printf("%s\n",string); } void DisplayA(char* string)/*函数A*/ { char String[20]="LoveWorld!"; printf("%s\n",string); DisplayB(String);/*调用函数B*/ } int main() { char String[20]="LoveChina!"; DisplayA(String);/*将参数传入函数A中*/ return 0; }