c语言ppt

上传人:正** 文档编号:56905949 上传时间:2018-10-17 格式:PPT 页数:42 大小:629.50KB
返回 下载 相关 举报
c语言ppt_第1页
第1页 / 共42页
c语言ppt_第2页
第2页 / 共42页
c语言ppt_第3页
第3页 / 共42页
c语言ppt_第4页
第4页 / 共42页
c语言ppt_第5页
第5页 / 共42页
点击查看更多>>
资源描述

《c语言ppt》由会员分享,可在线阅读,更多相关《c语言ppt(42页珍藏版)》请在金锄头文库上搜索。

1、15 Advanced tech about Array and pointer,School of Software 杜宇 ,内容提要,类型的扩展结构体 类型的组织链表,问题的提出,考虑一个问题:假如说我们已经能够解决前面提出的“最高成绩”问题了。可是我们得到的结果很不直观。仅仅可以输出一个最高成绩,而没有其他的辅助信息。 现在,威软公司正在着手开发一个新型的成绩排序程序,它能够输出某一科目所有成绩中的最大值,同时将拥有最高分数的学生的姓名输出。如:太极拳最高分,张三丰,100分独孤九剑最高分,令狐冲,95分降龙十八掌最高分,乔峰,97分无敌忽悠大法最高分,韦小宝,99分,问题的分析,思路:

2、拿到成绩单后,我们应该选定某一个科目,再在这个科目中找到最高成绩,同时得到拥有这个成绩的同学姓名。,事物是联系的,我们在解决这个问题时,仔细地分析一下: 事物都是有联系的,我们不能孤立地看待某一个事物。比如说:一台计算机有若干个部件,那么这台计算机“包含”了这些部件,或者说部件“属于”计算机。 在现实世界中这样的例子有很多,我们想想,使用C语言怎么来处理这种有关系的数据? 使用数组。,尝试使用数组解决问题,成绩可以存放成一个二维的数组,可是在储存科目名称和姓名的时候,我们发现一个重要的问题。 类型不同。成绩与姓名类型不同,无法定义变量。 近似的解决方案:定义三个数组。 姓名数组,科目名称数组,

3、成绩数组。 优点:可以实现我们的想法,完成程序设计。 缺点:与现实不符,割裂了事物的联系。,呼之欲出,结构,typedef struct point int x; int y; point; pointA.x = 21; pointA.y = 1; 数据组织的一次革命。将不同类型的数据捆绑在一起,作为一个整体。typedef的使用 回忆数据类型的扩展历程。位任意长度任意类型的捆绑。 成绩单怎么定义?,成绩单的一种写法,typedef struct student_t char * pName; char * pSubjectNamesM; float ScoresM; student_t; s

4、tudent_t studentN;,与结构有关的指针,student_t studentN; student_t * pStudent = NULL; pStudent = student;pStudent 是什么? pStudent - (*pName) 是什么? pStudent - ScoresM-1 是什么? pStudent = pStudent + 1; pStudent 是什么?,size问题,一个结构的成员变量在内存中是相邻的整个结构变量的将占用多少内存呢? 是所有成员变量的内存总和吗? 事实上,结构所占的实际空间一般是按照机器字长对齐的不同的编译器、不同的平台、不同的编译参

5、数,对齐方式会有变化。 应该用sizeof获得结构的大小.sizeof是一个C语言的关键字,并不是函数,返回类型size_t,可以用两种形式使用: sizeof(表达式),常使用sizeof(变量名) sizeof(类型) 求出的结果为表达式值所属类型或者类型占用的字节数.,结构相等之谜,定义结构相等 = 二进制相等。正确么? 填充位(Padding bits)的影响。 例子: typedef struct PaddingTest int aInt; char aChar; int anotherInt; short aShort; PaddingTest; PaddingTest Paddi

6、ngTest;,浪费空间!,想表达人的姓名、性别、肤色、出生年、月、日,都定义什么类型的成员变量? typedef struct person char name12; char sex; char color; int year; char month; char day; person; 这样有很多的空间浪费,比如month只可能取值1-12,位字段,typedef struct person char name12; unsigned int sex : 2; unsigned int color : 2; int year; unsigned int month : 4; unsign

7、ed int day : 5; person; 调整成员顺序可以让结构更紧凑,占用内存更少 每个位段都可以当作一个无符号整型数使用 表达范围当然受限,而且当然不能取地址,成员所占位数,联合(Union),union u_tag int ival; float fval; char* sval; u ; 使用上和struct一样 特点: u.ival、u.fval、u.sval的地址相同 sizeof(union xxx)取决于占空间最多的那个成员变量,再次扩张地盘,下面的结构什么意思?struct something struct something obj1; struct somethin

8、g obj2; ; 下面的的呢?struct something char name10; struct something* pOtherObj; ;,小结,结构是什么? 结构的作用是什么? 从bit到struct,我们学到了什么?,问题很严重,程序员很生气!,我们满怀信心地到计算机上编写取各科最高分程序的时候,一件不幸的事发生了我们发现,我们的机器内存“不足”了 typedef struct student_t char * pName; char * pSubjectNamesM; float ScoresM; student_t; 定义中,当M = 10,N = 10000时,在我们的

9、机器上,结构共占用84个字节,所有学生共占用840000字节,加上学生姓名约占100000个字节,科目名称约占1000000个字节,共有1940000个字节。,内存不足的原因,假设机器中有R块空闲内存,其中最大的两块均为1000000个字节,那么虽然总数超过了1940000个字节,但是,作为数组,还是无法分配。我们的程序不能运行! 解决的方法? 数组是连续的。只要有一种非连续的数据结构来“分块地”存放数据就可以了。显然用一个数组解决不了问题。,演绎,指向结构的指针,typedef struct student_t char * pName; char * pSubjectNamesM; flo

10、at ScoresM;student_t;student_t A, B; A.pNext = ,student_t * pNext;,换个双向的看看,typedef struct student_t char * pName; char * pSubjectNamesM; float ScoresM; student_t * pPrev; student_t * pNext; student_t;student_t A, B;A.pNext = ,链表图示,NULL,NULL,单向链表,NULL,双向链表,快使用多节棍,在链表中,各个“节点”之间通过指针连接在一起,可以形成单向或者双向的数据结

11、构。 访问链表需要顺序(一个接一个)的访问,这与数组有很大的不同。数组的访问是随机的,而链表的访问是顺序的。 一般在新的节点出现以后才同时与前面的节点进行“链接”。同时,将该节点的后连接设置为NULL。 新的内存单元一般通过系统调用来获得,我们将在后续的课程中学习。,思考题-插入和删除,已知一个N个元素的数组和一个N个节点的链表。 请思考在第i个位置插入一个元素(节点)的操作过程是什么?代价有多大? 那么,删除第i个位置元素(节点)的操作过程是什么?代价有多大? 这两个问题说明什么?,小节,以上我们对链表有了一个感性的认识,简单认识了它的构成和使用方法。 有关动态内存申请的内容,将在以后的课程

12、中继续学习。那时,我们才能够随心所欲的使用链表。 链表是C语言中的高级话题,在后续的科目中会经常使用,希望同学们能够多看、多练。,内容提要,动态内存申请及释放 链表深入,欢迎进入雷区,640K ought to be enough for everybody Bill Gates 1981,问题的引入,我们想编写一个程序,该程序能够对N个学生的成绩进行排序。该程序的应用范围在编写程序的时候无法确定。也就是说在编写程序的时候,不能够准确的估计出学生的个数N的范围。那么我们要用什么方法编写这个程序?用一个数组ScoreM 使得M+?方法可行么? 有没有其他的方法? 这个问题的实质是什么?编译时确定

13、的内存单元个数是固定的,而一些需要运行时确定的空间分配操作无法进行。,内存分配方式,从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc申请任意多少的内存,程序员自己负责在何时用free释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。,动态内存分配,C语言为我们提供了

14、一种在程序运行时分配内存的方法。即所谓的动态内存分配。 在 中定义了下面的函数 void* malloc(size_t size); void free(void* block);malloc申请的内存 在“堆(heap)”中分配,内容随机 被free之前,永久有效 在被free之后,该块内存不再属于你,malloc,void* malloc(size_t size); 向系统申请大小为size的内存块,把指向首地址的指针返回。如果申请不成功,返回NULL(一定要检查返回值) size_t是ANSI C定义的数据类型,一般就是unsigned int,但使用时要用size_t(还有什么操作返回

15、size_t?),free,void free(void* block); 释放由malloc()申请的内存块。block是指向此块首地址的指针( malloc()的返回值),注意事项,malloc()申请的内存不再使用时就要及时free() ,否则将产生内存泄露(Memory Leak) “内存泄露”一词类似“原料泄露”。泄露出去的原料不能被利用,导致生产过程中原料不足. malloc()时,系统找到一块未占用的内存,将其标记为已占用,然后把地址返回,并标记此程序占用此块内存,其它程序不能再用它. free()时,系统标记此块内存为未占用,可以被重新分配. 如果申请来的内存不用,别的程序也不

16、能用,就好像这块内存泄露出去一样,造成浪费 但不要频繁申请/释放,消耗时间,造成内存碎片,#include #include int main(void) int NumOfScores;void * p = NULL;scanf(“%d”, ,老鸟经验谈-常见的内存错误,内存分配未成功,却使用了它。 申请内存后,应检查指针值是否为NULL。 内存分配虽然成功,但是尚未初始化就引用它。 不要忘记为数组和动态内存赋初值。 内存分配成功并且已经初始化,但操作越过了内存的边界。 避免数组或指针的下标越界。 忘记了释放内存,造成内存泄露。 释放了内存却继续使用它。 用free 释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。,思考题,char *GetMemory(void) char p = “hello world“; return p; void Test(void) char *str = NULL; str = GetMemory(); printf(str); 请问运行Test 函数会有什么样的结果?,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号