微博: weibo.com/zhnitj QQ: 1307573198 —— 实验11 自定义类型 天津大学精仪学院 生物医学工程系 张宁 Email: zhni@tju.edu.cn 微博: weibo.com/zhnitj QQ: 1307573198 本课资料下载网址:http://www.zhni.net/cpp/ y188041.51host.net/cpp
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
练习55——结构体变量的初始化和输入输出 1001 Zhang M 85.0 1001 Zhang M _ 1001 Zhang M 1002 Qian F 90 1001 Zhang M 85.0 1001 Zhang M 85 1002 Qian F 90 1001 _ _ 1001 Zhang _ #include <iostream.h> struct stu { int num; char name[10]; char sex; float score; }; main() { stu s1,s2={1002, "Qian", 'F', 90.0}; cin>>s1.num; cin>>s1.name; cin>>s1.sex; cin>>s1.score; cout<<s1.num<<" "; cout<<s1.name<<" "; cout<<s1.sex<<" "; cout<<s1.score<<endl; cout<<s2.num<<" "; cout<<s2.name<<" "; cout<<s2.sex<<" "; cout<<s2.score<<endl; } cout<<s1.num<<"\t"; cout<<s1.name<<"\t"; cout<<s1.sex<<"\t"; cout<<s1.score<<endl; cout<<s2.num<<"\t"; cout<<s2.name<<"\t"; cout<<s2.sex<<"\t"; cout<<s2.score<<endl; } num name sex score ? s1: 1001 'M' 85.0 Zhang\0 s1.num=1001; s1.sex='M'; s1.score=85.0; s1.name="Zhang"; strcpy(s1.name, "Zhang"); num name sex score 1002 'F' 90.0 Q i a n \0 s2: 数组名的值不可改
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
相反条件 i不<5了→没找到 仍然i<5→找到! 练习56——用结构体数组查找书库库存信息 用结构体数组保存书的库存信息并实现查找。根据输入的书号,查找书库中 是否有该书,若有显示库存信息,若没有给出相应提示。 相反条件 #include <iostream.h> struct Book { int isbn; // 书号 char name[100]; // 书名 float price; // 价格 int stock; // 库存量 }; Book bks[5]={{978, "C++程序设计", 28.0, 125}, {730, "数据结构", 29.0, 182}, {228, "操作系统", 17.5, 220},{310, "数据库系统", 'F', 18.5}, {102, "网络技术", 'F', 19.5}}; // 全局变量 main() { int n; int i; cout<<"请输入要查询的书号:"; cin>>n; for (i=0; i<5; i++) if (bks[i].isbn==n) break; if (i>=5) { cout<<"查无此书!"<<endl; } else { cout<<"ISBN\t书名\t\t单价\t库存量\n"; cout<<bks[i].isbn<<"\t"; cout<<bks[i].name<<"\t"; cout<<bks[i].price<<"\t"; cout<<bks[i].stock<<endl; 如何能运行到这儿? (1) for 正常结束; (2) 是执行了break;被强制跳出for才到这儿的。 i不<5了→没找到 仍然i<5→找到! 978-7-302-28310-2 #include <iostream.h> struct Book { int isbn; char name[100]; float price; int stock; // 库存量 }; Book bks[5]={{978, "C++程序设计", 28.0, 125}, {730, "数据结构", 29.0, 182}, {228, "操作系统", 17.5, 220},{310, "数据库系统", 'F', 18.5},{102, "网络技术", 'F', 19.5}}; // 全局变量 main() int n; int i; cout<<"请输入要查询的书号:"; cin>>n; for (i=0; i<5; i++) if (bks[i].isbn==n) break; if (i<5) cout<<"ISBN\t书名\t\t单价\t库存量\n"; cout<<bks[i].isbn<<"\t"; cout<<bks[i].name<<"\t"; cout<<bks[i].price<<"\t"; cout<<bks[i].stock<<endl; } else cout<<"查无此书!"<<endl; 请输入要查询的书号:_ 请输入要查询的书号:123 查无此书! 请输入要查询的书号:_ 请输入要查询的书号:978 ISBN 书名 单价 库存量 978 C++程序设计 28 125 请输入要查询的书号:978
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
练习57——结构体数组(指针)做函数参数 #include <iostream.h> struct stu { int num; char name[10]; float score;}; float fun(stu *p, int n); main() { struct stu a[3]={ {1001,"Zhao",85.0}, {1002, "Qian", 90.0}, {1003, "Sun", 92.0} }; float av; av=fun(a,3); cout<<"平均分:"<<av<<endl; } float fun(stu p[ ], int n) { float a=0.0; int i; for (i=0; i<n; i++) a = a + p[i].score; return a/n; 平均分:89 stu *p main的空间 a[0] a[1] a[2] num name score 1001 Zhao\0 85.0 num name score 1002 Qian\0 90.0 num name score 1003 Sun\0 92.0 a: 1000 1020 1040 fun 的空间 p: [ 1000 ] 1000 (*(p+i)) .score
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
练习58——->、.与++、--、*的优先级 #include <iostream.h> main() { struct { int a; char *s; } x[2], *p=x; x[0].a=10; x[0].s="ABCD"; x[1].a=100; x[1].s="EFGH"; cout<<++p->a<<endl; cout<<(++p)->a<<endl; p=x; cout<<p++->a<<endl; cout<<*p->s<<endl; cout<<*p->s++<< endl; cout<<*p++->s; } [1008] [1000] [1008] [1000] ->和.优先级最高, ++、--与*相同从右至左结合 [1008] p: [ 1000 ] 2000 x: [ 1000 ] 1000 x[0] x[1] a s ? [ ? ] a s ? [ ? ] ++x[0].a x: 10 [3000] 100 [4000] 11 100 11 100 A B 11 100 A 11 100 A 11 11 100 [1008]->a 11 [3001] [1008] 1000 1008 [1000] 'A' 'B' 'C' 'D' '\0' [1000]->a 3000 *[3000] 'E' 'F' 'G' 'H' '\0' *[3000] [3000] 4000 *[1000]->s *[3001] [1000]
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
练习59——用结构体实现书P118.习题17
练习59——用结构体实现书P118.习题17(2) 这两个函数在函数内cout了,main调用它们时只调用即可,main中不必再cout。 struct stu *data cout<<printG85(s, NN); struct stu *data 函数无返回值,不能cout函数返回值
练习59——用结构体实现书P118.习题17(3) 这两个函数在函数内没有cout,main在调用它们后,main还要亲自cout。 struct stu *data 这两个函数在函数内没有cout,main在调用它们后,main还要亲自cout。 调用CoutMAvg后,main应cout这个函数的返回值; 调用sort后,数组已排好序(但没有cout),main应cout这个数组。 cout<<CountAvg(s, NN); struct stu *data cout<<sort(s, NN); 函数无返回值,不能cout函数返回值
练习59——用结构体实现书P118.习题17(4)
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
文件简介... 我们在使用计算机时,几乎每天都要接触文件,像文本文件(.txt)、word文件(.docx)、图片文件(.jpg)、网页文件(.html)等都属于文件的范畴。 现在我们简要介绍如何通过C++语言创建自己的文件,如何把C++语言程序中的变量保存到自己的文件中,以及如何将文件的内容再次读入到我们自己程序中的变量,以便在程序中进一步处理。
使用VC++输出文件 定义ofstream类的对象, 并初始化它指定文件名和 文件打开方式 #include <fstream.h> main() { ofstream outfile("C:\\d1.txt", ios::out); outfile<<"这是第一行"<<endl; int a=10, b=20; outfile<<a<<" "; outfile<<b; outfile<<endl; 像使用cout<<向屏幕输出一 样,用刚刚定义的对象<< 向文件中写入各种内容。 outfile<<"30 40"; outfile<<endl; #include <fstream.h> main() { ofstream outfile("C:\\ab.txt", ios::out); outfile<<"这是第一行"<<endl; int a=10, b=20; outfile<<a<<" "; outfile<<b; outfile<<endl; outfile<<"30 40"; outfile.close(); } 这是第一行 10 20 30 40 文件内容: 这是第一行 10 20 文件内容: 这是第一行 文件内容: outfile.close(); } 最后关闭文件, 释放资源。
练习 1) 设有以下程序, 2) 设有以下程序, #include <iostream.h> main() { int a, b; cin>>a>>b; } #include <iostream.h> main() { char str[80]; } cin>>str; cin.getline(str, 80); 若程序运行时,用户从键盘上输入: 10 20 则程序中变量a的值为 , 变量b的值为 。 若程序运行时,用户从键盘上输入: 这是第一行 则程序中数组str中保存的字符串 为 。 10 20 "这是第一行"
使用VC++将文件数据读入变量 #include <fstream.h> #include <iostream.h> main() { char str1[80]; int a, b, c, d; ifstream infile("C:\\d1.txt", ios::in); infile>>a>>b; infile>>c>>d; infile.close(); // 输出结果: cout<<str1<<endl; cout<<a<<" "<<b<<endl; cout<<c<<" "<<d<<endl; } 设文件C:\d1.txt的内容如下, 这是第一行 10 20 30 40 请编程将第一行的字符串读入程序中的数组str1, 将第二行和第三行的4个整数分别读入程序中的变量a、b、c、d 。 infile>>str1; infile.getline(str1, 80); #include <fstream.h> #include <iostream.h> main() { char str1[80]; int a, b, c, d; ifstream infile("C:\\ab.txt", ios::in); infile>>str1; infile>>a>>b; infile>>c>>d; infile.close(); // 输出结果: cout<<str1<<endl; cout<<a<<" "<<b<<endl; cout<<c<<" "<<d<<endl; } 这是第一行 10 20 30 40
文件读写方式总结 ① ② ③ ④ #include <fstream.h> 是否再#include <iostream.h>均可,因fstream.h里自动include了iostream.h ② 定义变量 写文件时,类型为 ofstream 如 ofstream f1("C:\\a1.txt", ios::out); 读文件时,类型为 ifstream 如 ifstream f2("C:\\a1.txt", ios::in); 定义变量 写文件时,类型为 ofstream 如 ofstream f1; 读文件时,类型为 ifstream 如 ifstream f2; 在定义变量时还需同时赋初值,( )内写文件名及ios::out(欲读文件时)或ios::in(欲写文件时) (文件名中的 \ 要表示为 \\,双引号引起) ③ 像用 cout、cin 一般写文件、读文件,只不过不用cout、cin,而是 用第②步定义的变量;如f1<<a<<endl; f2>>a>>b; 数据将写到文件而不是屏幕(不会同时在屏幕上显示);数据从文件读入而不是由用户从键盘输入。但与显示到屏幕或从键盘输入的方式是十分相似的。 读入字符串时,至少有两种方法: cin>>一级地址; cin.getline(一级地址,空间大小); ④ 释放资源 f1.close(); f2.close();
文件练习1 #include <iostream.h> #include <fstream.h> 键入下面程序,分别观察屏幕输出结果和文件中的内容: #include <iostream.h> #include <fstream.h> void main() { ofstream x("d:\\data.txt"); x<<"Hello, world!\n"<<1<<" "<<3.14<<endl; x.close(); cout<<"好了!自己打开d:\\data.txt文件看一下吧~"<<endl; } 注意: 哪些内容是显示在屏幕上的, 哪些内容是输出到文件中的。 好了!自己打开d:\data.txt文件看一下吧~
文件练习2 以下内容读自文件: 1 3.14 Hello, world! 键入下面程序,对照观察原有d:\data.txt文件中的内容和屏幕输出结果: #include <fstream.h> #include <stdlib.h> void main() { int x; double y; char str[100]; ifstream infile("d:\\data.txt"); if (! infile) { cout<<"无法打开文件,这个文件存在吗,还是你没有访问权限,或者是磁盘坏掉了?"<<endl; exit(1); } infile.getline(str,100); infile>>x>>y; cout<<"以下内容读自文件:"<<endl; cout<<x<<endl; cout<<y<<endl; cout<<str<<endl; infile.close(); 以下内容读自文件: 1 3.14 Hello, world!
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
P76.第3章习题. 2. 阅读下列程序并写出运行结果 (2) *[1024] *[1028] int *pb; pb=&bx[7]; [ 1000 ] 1000 bx[0] bx[1] bx[2] bx[3] bx[4] bx[5] bx[6] bx[7] 1 3 5 7 9 11 13 15 bx: 1000 1004 1008 1024 1028 pb: [ 1028 ] 2000 [1024] int *pb; pb=&bx[7]; int *pb=&bx[7]; [1024]>=[1000] [1028]>=[1000] 不是: *pb=&bx[7]; 15 15 13 11 9 7 5 3 1 15 13
堆 P76.第3章习题. 2. 阅读下列程序并写出运行结果 *p1 (4) new int (4) new double [3] 1.5 4字节 p1: [ 1000 ] 3000 4 1000 new int (4) 堆 ? 每元素8字节 p2: [ 2000 ] 4000 new double [3] 1.5 2.5 3.5 6 10 14 6 2000 2008 2016 ( ) :赋初值, [ ] :分配连续空间 p2[0] *(p2+0) *[2000] cout<<p2[n]*(*p1)<<endl; p2[0] * (*p1) = 1.5 * 4 = 6 p2[1] * (*p1) = 2.5 * 4 = 10 p2[2] * (*p1) = 3.5 * 4 = 14
P76. 第3章习题 3. 编写下列程序 (2)本题要求必须编写函数并传递数组参数完成,否则0分! 请将下面程序填空并将fun函数补充完整。 #include <iostream.h> void fun( float a[10], int n, int &n1, _______n2) { // a作为数组参数,实际传递的是一个地址 // fun中用a[i],就是main中的score[i];由n传递数组元素个数 // n1、n2为引用传递: fun中改变n1、n2的值,会同时改变main的实参 // 结果返回:从n1返回大于平均值的人数,从n2返回小于60分的人数 int i; float sum=0.0, ave; for (i=0; i<n; i++) sum+=a[i]; ave=sum/n; // 统计大于平均值的人数:结果值存入 n1 // 统计小于60分的人数:结果值存入 n2 n1=0; n2=0; for(i=0; i<n; i++) { if (a[i]>ave) n1++; if (a[i]<60) n2++; } #include <iostream.h> void fun( float a[10], int n, int &n1, _______n2) { // a作为数组参数,实际传递的是一个地址 // fun中用a[i],就是main中的score[i];由n传递数组元素个数 // n1、n2为引用传递: fun中改变n1、n2的值,会同时改变main的实参 // 结果返回:从n1返回大于平均值的人数,从n2返回小于60分的人数 int i; float sum=0.0, ave; for (i=0; i<n; i++) sum+=a[i]; // 先计算平均值 // 再统计大于平均值的人数:结果值存入 n1 // 及统计小于60分的人数:结果值存入 n2 _______________________________ } 请将下面程序填空并将fun函数补充完整。 int & float *a 不能写score[10] ① 没有score[10]这个元素; ② 形参是float *a,是一级; score[10]是零级。 void main() { float score[10]; int c1, c2; int i; cout<<"请输入10个学生的成绩:"<<endl; for (i=0; i<10; i++) cin>>score[i]; fun(_______, _______, c1, c2); // c1、c2的值是由fun函数改变的 cout<<"大于平均值的人数:"<<c1<<endl; cout<<"小于60分的人数:"<<c2<<endl; } score 10
P76. 第3章习题 3. 编写下列程序 (3) 参考程序见下: cin>>字符一级地址; cin>>一维数组名; 字符串输入 cin>>字符一级地址; cin>>一维数组名; cin>>一级指针变量; 字符串输出 cout<<字符一级地址; cout<<一维数组名; cout<<一级指针变量; cin>>s[100]; #include <iostream.h> main() { char s[100]; int ca=0, ci=0, i; cout<<"请输入字符串:"; cin>>s; for (i=0; s[i]; i++) if (s[i]=='a') ca++; if (s[i]=='i') ci++; } cout<<"字符串是:"<<s<<endl; cout<<"有"<<ca<<"个a,"<<ci<<"个i\n"; for (i=0; i<100; i++) cin>>s[i]; 必须输入100个字符长的字符串了
这里说s[0]就是指main中的str[0] ,但这里不能直接写str必须用s P115. 第4章习题 2. 看程序写结果 main的空间 (6) #include <iostream.h> #include <string.h> void function(char s[ ]); void main() { char str[10]="abcd"; cout<<str<<endl; int n1=1, n2=strlen(str); while ( n1++ <= n2) function(str); } void function(char s[ ]) static int n3=0; s[n3++] += 2; str[0] str[2] str[4] str[9] 'a' 'b' 'c' 'd' '\0' ... str: 'c' 'd' 'e' 'f' 1000 1001 1004 1009 n1: 1 2000 n2: 4 3000 2 3 4 5 6 function 的空间 function 的空间 function 的空间 4 2 1 5 3 function 的空间 abcd cdef abcd s: [ 1000 ] 4000 s: [ 1000 ] 5000 n3: 1 2 s: [ 1000 ] 7000 3 4 char *s s: [ 1000 ] 6000 这里说s[0]就是指main中的str[0] ,但这里不能直接写str必须用s 1 3 2
P117. 第4章习题 编程题 5. 5. 参考程序见下: cin.getline<<s; #include <iostream.h> #include <ctype.h> //字符函数头文件 #include <string.h> //字符串函数头文件 void main() { int digits, num; char s[80]; digits=0; //数字字符计数器 cout<<"输入一串字符(可含空格):"; cin.getline(s,80); //输入以回车作为结束的一行空符 num=strlen(s); //计算s中的字符个数 for ( int i=0; i<num; i++) if (isdigit(s[i])) digits++; //判断s[i]中的字符是否是数字字符 cout<<"数字字符占所有字符总数的百分比为:"<<(double)digits/num<<endl; }
P118. 第4章习题 编程题 15. 15. 请按下面程序填空完成此题。 *p = ch; find函数方法2: 15. 请按下面程序填空完成此题。 <iostream.h> #include ____________________ int find ( , char ch) // 找到时返回位置,没找到返回0 { char *p; p=a; while (_______________) { if (________) return ________; // 以上if语句没有else // 条件不成立时什么都不做,直接p++和下次循环 p++; } // 程序运行到此说明退出了while循环,说明while循环中途 // 没有执行if中的return,表示没有找到,故return 0 return 0; char a[ ] 或 char *a find函数方法2: int find (_____, char ch) { int i; for (i=0; ________; _______) if (a[i]==ch) return i+1; ________ } = 与==区别 考试必考! *p 或 *p!= '\0' *p = ch; char a[ ] 或 char *a *p==ch p-a+1 a[i]!='\0' 或 a[i] i++ return 0; void main() { int pos; _____ = find("Computer Language", 'u'); cout<<pos<<endl; // 输出结果位置(没找到输出0) } pos
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
MsgBox使用枚举 提示:单击文字任意处 按Ctrl+A键全选 按Ctrl+C键复制 #include <iostream.h> #include <windows.h> enum EMsgBoxBtn { mb_OK = 0, mb_OkCancel = 1, mb_AbortRetryIgnore = 2, mb_YesNoCancel = 3, mb_YesNo = 4, mb_RetryCancel = 5 }; enum EMsgBoxIcon mb_IconNone = 0, mb_IconError = 0x10, mb_IconQuestion = 0x20, mb_IconExclamation = 0x30, mb_IconAsterisk = 0x40, mb_UserIcon = 0x80 enum EDlgBoxDefBtn mb_DefButton1 = 0, mb_DefButton2 = 0x100, mb_DefButton3 = 0x200, mb_DefButton4 = 0x300 enum EDlgBoxCmdID NoValue = 0, idAbort = 3, // Abort button was selected. idCancel = 2, // Cancel button was selected. idIgnore = 5, // Ignore button was selected. idNo = 7, // No button was selected. idOk = 1, // OK button was selected. idRetry = 4, // Retry button was selected. idYes = 6 // Yes button was selected. EDlgBoxCmdID MsgBox(char * prompt, char * title = NULL, EMsgBoxBtn buttons = mb_OK, EMsgBoxIcon icon = mb_IconNone, EDlgBoxDefBtn defBtn = mb_DefButton1, bool bSystemModal = false, bool bHelpButton = false, bool bRightJustified = false, bool bRightToLeftReading = false); // 函数声明 // ************************************************************ // 请在此处编写main函数 main() } // 弹出消息框 char * title, EMsgBoxBtn buttons, EMsgBoxIcon icon, EDlgBoxDefBtn defBtn, bool bSystemModal, bool bHelpButton, bool bRightJustified, bool bRightToLeftReading) unsigned int uType; if (title == NULL) title="Message"; // 如果 title 为 NULL,就用"Message"作为标题 uType = buttons + icon + defBtn; uType += MB_TASKMODAL; // hWnd == 0 时,添加 MB_TASKMODAL // 以使当前线程所属的顶层窗口都被禁用 if (bSystemModal) // hWnd == 0 时,用 MB_TASKMODAL;否则用 MB_SYSTEMMODAL uType += MB_TOPMOST; if (bHelpButton) uType += MB_HELP; if (bRightJustified) uType += MB_RIGHT; if (bRightToLeftReading) uType += MB_RTLREADING; return (EDlgBoxCmdID)MessageBox(0, prompt, title, uType); MsgBox使用枚举 提示:单击文字任意处 按Ctrl+A键全选 按Ctrl+C键复制 我们自己编写了一个MsgBox函数用 于弹出消息框,为免去记忆整数所代 表功能的麻烦,使用枚举做参数类型 和返回值: 1. 新建程序; 2. 先不要编写任何代码,将右边所有文本 全选、复制,在你的程序中粘贴; 3. 观察枚举是如何定义的; 4. 在 “// 请在此处编写main函数” 处编写 你的main函数如下:
枚举实习2 提示:单击文字任意处 按Ctrl+A键全选 按Ctrl+C键复制 打开系统文件夹的程序: 使用枚举方便调用函数时设置实参 #include <iostream.h> #include <windows.h> // 系统文件夹枚举类型 enum ESESysFolder { sesfMyComputer, // 我的电脑 sesfMyDocuments, // 我的文档 sesfNetworkPlaces, // 网上邻居 sesfRecycleBin // 回收站 }; // 窗口显示方式枚举类型 enum EShowWindowCmd SW_ForceMinimize = 11, SW_Hide = 0, SW_Mazimize = 3, SW_Minimize = 6, SW_Restore = 9, SW_Show = 5, SW_ShowDefault = 10, SW_ShowMaximized = 3, SW_ShowMinimized = 2, SW_ShowMinNoactive = 7, SW_ShowNA = 8, SW_ShowNoActivate = 4, SW_ShowNormal = 1 // 函数声明 bool SEShellRun( const char * sFileOrURL, bool bWithParam=false, EShowWindowCmd winShowStyle=SW_ShowNormal ); bool SEOpenSysFolder( ESESysFolder sysFolder, EShowWindowCmd winShowStyle=SW_ShowNormal ); // 请在此处编写main函数 main() int a; cout<<"请输入您要打开哪个文件夹?"<<endl; cout<<"1. 我的电脑"<<endl; cout<<"2. 我的文档"<<endl; cout<<"3. 网上邻居"<<endl; cout<<"4. 回收站"<<endl; cout<<"请输入:"; cin>>a; switch (a) case 1: SEOpenSysFolder(sesfMyComputer, SW_ShowNormal); break; case 2: SEOpenSysFolder(sesfMyDocuments, SW_ShowNormal); // ************************************************************ // 你能自己继续完成实现打开“网上邻居”和“回收站”的功能吗? } // 打开一个系统文件夹 bool SEOpenSysFolder( ESESysFolder sysFolder, EShowWindowCmd winShowStyle/*=SW_ShowNormal*/ ) switch(sysFolder) case sesfRecycleBin: // 打开 回收站 return SEShellRun( "explorer.exe ::{645FF040-5081-101B-9F08-00AA002F954E}", true, winShowStyle); case sesfMyComputer: // 打开 我的电脑 "explorer.exe ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", case sesfNetworkPlaces: // 打开 网上邻居 return SEShellRun("explorer.exe ::{208D2C60-3AEA-1069-A2D7-08002B30309D}", case sesfMyDocuments: // 打开 我的文档 return SEShellRun("explorer.exe", true, winShowStyle); default: return 0; // 执行一个程序、打开一个文档或打开一个URL // 若bWithParam=true,则将 sFileOrURL 的第一个空格前看做程序的文件名, _ // 之后看作参数;否则都看作程序文件名,参数为空 // winShowStyle 表示窗口显示状态(最大化、最小化、隐藏等) // 用法举例: // 运行程序 SEShellRun("C:\\Windows\\System32\\mspaint.exe"); // 打开文件夹 SEShellRun("C:\\Windows"); // 自动启动关联程序打开文档 SEShellRun("E:\\my\\abc.txt"); // 打开网页:SEShellRun("http://www.163.com"); // 发送邮件:SEShellRun("mailto:zhni2011@163.com"); bool SEShellRun( const char * sFileOrURL, bool bWithParam/*=false*/, EShowWindowCmd winShowStyle/*=SW_ShowNormal*/ ) char * sFileOrExe = (char *)sFileOrURL; // 外部程序名的执行部分 char * sParam = 0; // 外部程序的参数 bool ret; // 返回值 if (bWithParam) // 分出 sFileOrURL 中的程序文件名和参数 char * sFileOrExe = new char[strlen(sFileOrURL)+1]; strcpy(sFileOrExe, sFileOrURL); char * ptrBlank=strchr(sFileOrExe, 32); // 找到第一个空格的位置 if (ptrBlank) // 找到了空格 *ptrBlank='\0'; sParam=(ptrBlank+1); ret= (INT)ShellExecute(0, "open", sFileOrExe, sParam, 0, (INT)winShowStyle) > 32; delete []sFileOrExe; else return ret; 枚举实习2 提示:单击文字任意处 按Ctrl+A键全选 按Ctrl+C键复制 打开系统文件夹的程序: 使用枚举方便调用函数时设置实参 1. 新建程序; 2. 先不要编写任何代码,将右边 所有文本全选、复制,在你的 程序中粘贴; 3. 观察枚举是如何定义的; 4. 直接编译运行程序,可实现打 开“我的电脑”和“我的文档”两 个功能; 5. 你能自己完善程序,继续实现 打开“网上邻居”和“回收站”的 功能吗?
课外体验—VC小助手Visual Assist(VA) Visual Assist是由Whole Tomato公司为Microsoft Visual Studio开发的一款插件。 它对Visual Studio的智能提示(Intellisense)功能和代码高亮功能进行了增强, 能自动识别各种关键字、系统函数、成员变量、自动给出输入提示、自动更正大小写 错误、自动标示错误等,能大大提高开发过程的自动化和开发效率。
本讲概要 1. 练习55——结构体变量的初始化和输入输出 2. 练习56——用结构体数组查找书库库存信息 3. 练习57——结构体数组(指针)做函数参数 4. 练习58——->、.与++、--、*的优先级(选作) 5. 练习59——用结构体实现书P118.习题17 6. 文件编程预练 7. 第3-4章指针部分作业答案 8. 课外体验 (选作) 1)枚举在Windows编程中的应用(选作) 2)结构体在Windows编程中的应用(选作)
课外体验—结构体在Windows编程中的应用 #include <iostream.h> #include <windows.h> #include <memory.h> void OsdOpenDlg( char *buff, int buffsize); main() { char s[1024]; OsdOpenDlg(s, 1024); // 由函数改变了数组 s 的值,函数调用后数组 s 的值(字符串)即为用户所选文件的全路径文件名 // 请思考:通过函数改变了数组 s[] 的值,是如何实现的? cout<<s<<endl; } // 打开【打开文件对话框】 ;用户所选文件将被存入 buff 的空间,出错此空间为空串 // 事先应提前开辟好 buff 的空间,buff为空间首地址,buffsize为空间大小(字节)(含'\0') void OsdOpenDlg( char *buff, int buffsize) OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); memset(buff, 0, buffsize); // 填充 ofn ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = buff; // 主调函数传递的 buff 地址赋值到结构体变量ofn的 lpstrFile 成员, // 将来会将此结构体变量ofn传递给GetOpenFileName函数,后者执行时系统就将在这个地址 // 的空间中保存用户在对话框中所选的文件名(含全路径) ofn.nMaxFile = buffsize; // 主调函数传递的 buff 空间的大小也需赋值到ofn的相应成员, // 将来将此结构体变量ofn传递给GetOpenFileName函数后,以便供系统获知 // *************************************************************************** // 可修改下面的内容,再次运行程序,观察对话框的外观或行为 ofn.lpstrInitialDir="C:\\windows"; ofn.lpstrTitle = "我的打开对话框"; // 设置对话框标题 ofn.lpstrFilter="所有文件(*.*)\0*.*\0哈哈—就是选择了txt的说\0*.txt\0电影文件(*.avi)\0*.avi\0\0"; // 文件类型框,\0分隔,最后有两个\0 ofn.nFilterIndex=1; // 默认选择文件类型的第几项,从1开始编号 ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY; // | OFN_ALLOWMULTISELECT // 打开【打开】文件对话框 // API 函数 GetOpenFileName 中执行了 *ofn.lpstrFile = 所选文件名(要用strcpy()) // 于是主调函数 main 中的 s[] 数组的内容被改写 GetOpenFileName(&ofn); 【打开文件对话框】的程序: 我们编写了函数 OsdOpenDlg 提示:单击文字任意处 按Ctrl+A键全选 按Ctrl+C键复制 1. 新建程序; 2. 先不要编写任何代码,将右边所有文本全选、 复制,在你的程序中粘贴; 3. 在OsdOpenDlg函数中,定义了结构体变量 ofn,它是结构体OPENFILENAME类型的 变量,观察在函数中是如何设置其中的各个 成员值的(未全部设置所有成员); 4. 直接编译运行程序,可实现【打开文件对 话框】的功能; 5. 尝试修改OsdOpenDlg函数中的代码,设置 ofn的不同成员为不同的值,再次运行程 序,观察对话框的外观和行为有何不同? 6. 可以改造main函数,仿照此程序对 OsdOpenDlg()函数的调用方法,自己编写 任意使用【打开文件对话框】的程序。 #include <iostream.h> #include <windows.h> #include <memory.h> void OsdOpenDlg( char *buff, int buffsize); main() { char s[1024]; OsdOpenDlg(s, 1024); // 由函数改变了数组 s 的值,函数调用后数组 s 的值(字符串)即为用户所选文件的全路径文件名 // 请思考:通过函数改变了数组 s[] 的值,是如何实现的? cout<<s<<endl; } // 打开【打开】文件对话框;用户所选文件将被存入 buff 的空间,出错此空间为空串 // 事先应提前开辟好 buff 的空间,buff为空间首地址,buffsize为空间大小(字节)(含'\0') void OsdOpenDlg( char *buff, int buffsize) OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); memset(buff, 0, buffsize); // 填充 ofn ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = buff; // 主调函数传递的 buff 地址赋值到结构体变量ofn的 lpstrFile 成员, // 将来会将此结构体变量ofn传递给GetOpenFileName函数,后者执行时系统就将在这个地址 // 的空间中保存用户在对话框中所选的文件名(含全路径) ofn.nMaxFile = buffsize; // 主调函数传递的 buff 空间的大小也需赋值到ofn的相应成员, // 将来将此结构体变量ofn传递给GetOpenFileName函数后,以便供系统获知 // *************************************************************************** // 可修改下面的内容,再次运行程序,观察对话框的外观或行为 ofn.lpstrInitialDir="C:\\windows"; ofn.lpstrTitle = "我的打开对话框"; // 设置对话框标题 ofn.lpstrFilter="所有文件(*.*)\0*.*\0哈哈—就是选择了txt的说\0*.txt\0电影文件(*.avi)\0*.avi\0\0"; // 文件类型框,\0分隔,最后有两个\0 ofn.nFilterIndex=1; // 默认选择文件类型的第几项,从1开始编号 ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_HIDEREADONLY; // | OFN_ALLOWMULTISELECT // 打开【打开】文件对话框 // API 函数 GetOpenFileName 中执行了 *ofn.lpstrFile = 所选文件名(要用strcpy()) // 于是主调函数 main 中的 s[] 数组的内容被改写 GetOpenFileName(&ofn);
OPENFILENAME结构体类型 typedef struct tagOFN {…} OPENFILENAME ; unsigned long lStructSize; // 本类型数据的大小(字节) HWND hwndOwner; // 对话框的父窗口句柄,可为0表示无父窗口 HINSTANCE hInstance; // 对话框模板句柄或模板的模块标识 char * lpstrFilter; // 文件类型筛选字符串 char * lpstrCustomFilter; // 系统保存的上次用户选择的筛选规则或用户自定义规则 unsigned long nMaxCustFilter; // lpstrCustomFilter 的长度 unsigned long nFilterIndex; // 用户在文件类型框中选择的筛选规则编号(从1开始编号) char * lpstrFile; // 对话框的默认文件名或用户选择的文件名(包含全路径) unsigned long nMaxFile; // lpstrFile 缓冲区的长度 char * lpstrFileTitle; // 用户选择的文件名(无路径) unsigned long nMaxFileTitle; // lpstrFileTitle 缓冲区的长度 char * lpstrInitialDir; // 对话框的初始路径 char * lpstrTitle; // 对话框标题(为NULL时默认使用"打开"、"另存为") unsigned long Flags; // 指定对话框初始选项和用户的输入情况 unsigned short nFileOffset; // 在全路径字符串中,文件名部分之前的长度 unsigned short nFileExtension; // 在全路径字符串中,表示扩展名的"."所在位置 char * lpstrDefExt; // 用户未输入扩展名时自动添加的扩展名 unsigned long lCustData; // 用于钩子程序的自定义数据 LPOFNHOOKPROC lpfnHook; // 钩子程序地址 char * lpTemplateName; // 在hInstance指定的模块中的对话框模板资源名称 } OPENFILENAME; typedef struct tagOFN {…} OPENFILENAME ;
感谢你的聆听!