180 likes | 340 Views
TKS. 1. 高级语言. (第二十一讲). 如何灵活控制内存空间 ?. 绍兴文理学院. 计算机系计算机应用教研室. 第六章 指针 (3) 、第七章 函数 (4). 一、教学目的: 明确变量存储属性和作用域的概念,掌握利用不同变量存储属性进行程序设计。明确动态存储分配的概念,掌握动态分配的 new 和 delete 的运算方法和功能。算法和程序设计能力的训练。. 二、教学重点: 不同变量存储属性的程序设计,动态分配的 new 和 delete 的运算方法和功能。算法和程序设计能力的训练。.
E N D
TKS 1 高级语言 (第二十一讲) 如何灵活控制内存空间? 绍兴文理学院 计算机系计算机应用教研室
第六章 指针(3)、第七章 函数(4) 一、教学目的:明确变量存储属性和作用域的概念,掌握利用不同变量存储属性进行程序设计。明确动态存储分配的概念,掌握动态分配的new和 delete的运算方法和功能。算法和程序设计能力的训练。 二、教学重点:不同变量存储属性的程序设计,动态分配的new和 delete的运算方法和功能。算法和程序设计能力的训练。 三、教学难点:动态分配的new和 delete的运算方法和功能的程序设计。算法和程序设计能力的训练。 四、教学过程:
§7.3 变量的作用域 TKS 3 从变量定义的位置开始,到相应的位置自动结束(失去作用),这个起作用的范围称为此变量的作用域。根据变量定义位置和情况的不同具有不同的作用域。 §7.3.1 作用域分类 变量的作用域可分为四类:全局、文件、函数和块。 1、全局作用域 (1)概念 在所有函数定义之外定义的变量,在该程序的所有文件里都可用,其中在本程序文件里从定义开始到程序文件结束都可用。 这样的变量具有全局作用域,称全局变量。 当定义一个全局变量时,若没有对其初始化,则默认的初始值为0。 14:48
(2) 全局变量作用域示例 TKS 4 全局变量作用域图示 int a,b; // 全局变量 void f1() // 函数f1 { …… } float x,y; // 全局变量 int fz() // 函数fz { …… } int main() // 主函数 { …… } 全局变量a,b的作用域 全局变量x,y的作用域 14:48
例1 全局变量作用域演示 C+21_1 TKS 5 int main(void) {a(); b(); cout<<"x3="<<x<<endl; return 0; } #include <iostream> using namespace std; int x=3; void a() {int a=1; cout<<"a1="<<a<<endl; cout<<"x1="<<x<<endl; x=x+5; } void b() {cout<<"x2="<<x<<endl; } ▲设全局变量的作用是增加了函数间数据联系的渠道。 但对数据的“封装性”不利。 ▲ 关于extern 14:48
例2 有一个一维数组,内放10个学生成绩,写一函数,求出平均分,最高分和最低分。C+21_2 TKS 6 分析:把最高分和最低分设成全局变量。程序如下: float max=0,min=0; float average(float array[],int n) {int i; float aver,sum; max=min=sum=array[0]; for(i=1;i<n;i++) {if(array[i]>max) max=array[i]; else if(array[i]<min) min=array[i]; sum=sum+array[i]; } aver=sum/n; return(aver); } int main() {float ave,sc[10]; int i; for(i=0;i<10;i++) cin>>sc[i]; ave=average(sc,10); printf("max=%6.2f\nmin=%6.2f \nrage=%6.2f\n",max,min,ave); return 0; } 14:48
2、文件作用域 TKS 7 在所有函数定义之外使用static保留字定义的变量,只在本文件中有效。 如:static int a=10; 若定义一个文件作用域变量时,没有对其初始化,则默认初始值为0。 其用法和全局变量相同,只是文件作用域变量只能用于本文件。 3、函数作用域 一般不用(略) 4、块作用域 (1) 概念 在一条复合语句(函数)内定义,只在该语句内有效。 块作用域的变量或常量称为局部变量或常量。 块作用域中的变量和常量的存储属性如下表: 14:48
TKS 8 定义前面的标识符 使 用 说 明 auto 可省略。在"栈存储区"中分配数据存储单元 register 尽可能在CPU的寄存器内分配数据存储单元 static 在“堆存储区"中分配数据存储单元 具有static的局部变量称为静态变量。若定义时未初始化,则系统对其初始化为0。 静态变量的作用是在不改变局部变量有效范围的前提下,当块中的语句执行完毕后,变量的值仍保留。而在有效范围之外是不可以使用的。 (2) 示例: 14:48
例3 演示局部变量作用域C+21_3 TKS 9 #include<iostream> using namespace std; int main(void) {cout<<"a1="<<a; int a=3; cout<<"a2="<<a; {int b=5; cout<<"b1="<<b; } cout<<"b2="<<b; cout<<"a3="<<a<<endl; return 0; } 14:48
例4 用静态局部变量的一个增量函数的应用C+21_4 TKS 10 #include <iostream> using namespace std; void increment(void); int main(void) {increment(); increment(); increment(); return 0; } void increment(void) {static int x=0; x++; cout<<x<<endl; } 注意:静态局部变量在编译时赋初值,即只赋初值一次。 14:48
§6.6 动态存储分配 TKS 11 1、结构成员的间接访问—用指针操作访问结构成员 (1) 指向结构变量的指针及其定义 ①概述 一个指针变量用来指向一个结构变量时,称为结构指针变量。结构指针变量中的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量,这与指向数组的指针是相同的。 ② 指向结构体变量指针的定义 定义格式: 结构类型名 *结构指针变量名; 如:struct student {int nnum; char name[20]; char sex; float score; }; studentstu, *p; p=&stu; p中存放着结构体变量stu在内存中的首地址 14:48
(2) 使用指向结构体变量的指针引用结构体变量的成员 TKS 12 ①访问结构体成员变量的三种方法 Ⅰ stu.num、stu.name、stu.score Ⅱ (*p).num、(*p).name、(*p).score Ⅲp->num、p->name、p->score ②说明 Ⅰ “->”为指向运算符,是优先级最高的运算符; Ⅱ 成员运算符“.”的优先级高于指针运算符“*”,因此采用 “(*p).成员名” 形式时,括号不能省略; Ⅲ 注意以下几种运算: p->num 得到p指向的结构体变量中的成员num的值 p->num++ 得到p指向的结构体变量中的成员num的值,用完后该值加1 ++p->num 使p指向的结构体变量中的成员num的值加1 14:48
(3) 例5 结构成员的间接访问—用指针操作访问结构成员 C+21_5 TKS 13 int main(void) { struct person { char a[10]; int b; }; person p2={"beijing", 46},*px; px=&p2; cout<<p2.a<<' '<<p2.b<<endl; cout<<px->a<<' '<<px->b<<endl; //间接成员访问使用箭头操作符 return 0; } 14:48
2、动态分配的概念 TKS 14 为指针所进行的内存空间动态分配是在程序运行过程中在自由内存区---堆(heap)区分配的。堆可以形成比较大的存储空间,供动态分配使用。 动态分配的特点是,可以由程序员控制,在需要时分配,在不需要时释放。这些功能主要通过new和delete运算实现。 3、使用用new运算符申请动态存储空间 (1)格式 new <已知数据类型> [(初值表达式)] (2) 功能 首先从内存的动态分配的堆存储区内分配一块存储空间,其大小等于new运算符在[]中指明的数据类型的长度;然后返回该存储空间的(首)地址,若无法得到所需的存储空间,则表明动态分配失败,返回空指针(即NULL)。 14:48
(3) 例6 使用用new运算申请动态存储空间及访问C+21_6 TKS 15 #include <iostream> using namespace std; int main(void) { int *p1=new int(8),n,i; n=10; int *p2=new int[n]; cout<<*p1<<endl; for(i=0;i<n;i++) cin>>p2[i]; for(i=0;i<n;i++) cout<<p2[i]<<' '; cout<<endl; return 0; } 14:48
(4) 说明 TKS 16 ①当用new运算动态分配一维数组空间时,[]内的数组长度是常量和变量表达式均可。 ② 当用new运算动态分配二维及以上的数组空间时,除第一维[]内的数组长度是常量和变量表达式均可外,其余维[]内的数组长度必须为常量表达式。 ③ 用new运算可以动态分配存储空间,但用户只有把它的返回值保存到一个指针变量后,才能通过这个指针变量间接地访问这个存储空间(数据对象)。 4、使用用delete运算符释放动态存储空间 使用new运算符动态分配给变量的存储空间,可以通过使用delete运算符重新归还给系统。其格式如下: delete p1;或 delete []p1; 14:48
例7 使用用delete运算符释放动态存储空间C+21_7 TKS 17 #include <iostream> using namespace std; int main(void) { int *p1=new int(8),n,i; n=10; int *p2=new int[n]; cout<<*p1<<endl; delete p1; for(i=0;i<n;i++) cin>>p2[i]; for(i=0;i<n;i++) cout<<p2[i]<<' '; cout<<endl; delete []p2 return 0; } 14:48
五、作业与实践: TKS 18 1、上机编程:6085~6087 2、实验三 结构和链表程序设计 ? 14:48