程序设计实习讲义.ppt

上传人:枫** 文档编号:569461552 上传时间:2024-07-29 格式:PPT 页数:89 大小:488KB
返回 下载 相关 举报
程序设计实习讲义.ppt_第1页
第1页 / 共89页
程序设计实习讲义.ppt_第2页
第2页 / 共89页
程序设计实习讲义.ppt_第3页
第3页 / 共89页
程序设计实习讲义.ppt_第4页
第4页 / 共89页
程序设计实习讲义.ppt_第5页
第5页 / 共89页
点击查看更多>>
资源描述

《程序设计实习讲义.ppt》由会员分享,可在线阅读,更多相关《程序设计实习讲义.ppt(89页珍藏版)》请在金锄头文库上搜索。

1、程序设计实习程序设计实习 李文新 内容提要内容提要l课程简介l输入输出l位运算l函数指针l命令行参数l库函数l程序风格课程简介课程简介l课程定位l课程内容l授课方式l成绩评定l教材l进度安排l课程网页信息学院课程体系图信息学院课程体系图课程内容课程内容1. 掌握vc+编程环境能够使用该环境进行基于控制台输入输出及文件输入输出的C及C+程序的源代码编辑、编译连接、调试和运行2. 巩固和增强程序设计和代码实现能力高精度计算、日期的处理、字符串的处理、链表的概念、实现和应用、枚举和递归的求解方法。3. 学习用 C+ 语言编程 基本概念(类、对象、数据抽象、重载、继承、虚函数、多态等)及其语法实现。C

2、+程序基本构成、输入输出流及文件处理、模板、字符串处理、文件处理及标准模板库等。授课方式授课方式1.课上讲授、练习及测验2.复习、自学和书面作业3.上机实习并完成上机作业4.期中及期末考试成绩评定成绩评定1.期中考试 15% 上机考试2.期末考试 50% 有B卷,考试内容为作业3.平时成绩:作业和课堂表现 35% 平时作业成绩与B卷成绩加权作业包括课堂上留的,每周两个小时的到机房上机(期中考试前),以及期中考试后的Blocks 程序对战(不必到机房,按比赛成绩给分)教材教材 程序设计导引及在线实践 C+ 大学教程(第二版) Harvey M. Deitel Paul James Deitel

3、邱仲潘 等译 冯平 审校 电子工业出版社 2004进度安排(暂定)进度安排(暂定)l第一讲:C+ 基础知识巩固l第二讲:简单计算题和数制转换以及日期处理l第三讲:字符串处理l第四讲:高精度计算l第五讲:枚举l第六讲:递归l第七讲:搜索l第八讲: 动态规划l第九讲:链表和二叉树l第十讲:习题课进度安排(暂定)进度安排(暂定)l第十一讲:类和对象(一)l第十二讲:类和对象(二)l第十三讲:运算符重载l第十四讲:继承l第十五讲:多态l第十六讲:输入/输出流、文件操作l第十七讲:类模板、函数模板、string类l第十八讲:标准模板库(一)l第十九讲:标准模板库(二)l第二十讲:标准模板库(三)l第二十

4、一讲:标准模板库(四)l第二十二讲:习题课l第二十三讲:总结和答疑课程网页课程网页lhttp:/ scanf( ) 将输入读入变量 printf( ) 将变量内容输出scanf( ) 语句(函数)intint scanfscanf( const char * , .); ( const char * , .); 参数可变的函数参数可变的函数第一个参数是格式字符串,后面的参数是变量的地址,第一个参数是格式字符串,后面的参数是变量的地址,函数作用是按照第一个参数指定的格式,将数据读入函数作用是按照第一个参数指定的格式,将数据读入后面的变量后面的变量参数可变的函数的参考阅读参数可变的函数的参考阅读(

5、不要求掌握)不要求掌握)http:/ 返回值 0 成功读入的数据项个数; 0 没有项被赋值; EOF 第一个尝试输入的字符是EOF(结束) (对(对POJ上某些题,返回值为上某些题,返回值为EOF可以用来判可以用来判断输入数据已经全部读完)断输入数据已经全部读完)printf( ) 语句(函数)intint printfprintf( const char * , .); ( const char * , .); 参数可变的函数参数可变的函数第一个参数是格式字符串,后面的参数是待输出的变第一个参数是格式字符串,后面的参数是待输出的变量,函数作用是按照第一个参数指定的格式,将后面量,函数作用是按

6、照第一个参数指定的格式,将后面的变量在屏幕上输出的变量在屏幕上输出 返回值返回值:成功打印的字符数;成功打印的字符数; 返回负值为出错返回负值为出错%d %d 读入或输出读入或输出intint变量变量%c %c 读入或输出读入或输出charchar变量变量%f %f 读入或输出读入或输出floatfloat变量变量%s %s 读入或输出读入或输出char * char * 变量变量%lf %lf 读入或输出读入或输出double double 变量变量%e %e 以科学计数法格式输出数值以科学计数法格式输出数值%x %x 以十六进制读入或输出以十六进制读入或输出 intint 变量变量%I64

7、d %I64d 读入或输出读入或输出 _int64 _int64 变量变量(64(64位整数)位整数)%p %p 输出指针地址值输出指针地址值 %.5lf %.5lf 输出浮点数,精确到小数点后输出浮点数,精确到小数点后5 5位位格式字符串里的格式控制符号:#include int main() int a;char b;char c20;double d =0;float e = 0;int n = scanf(%d%c%s%lf%f,&a,&b,c,&d,&e);printf(%d %c %s %lf %e %f %d,a,b,c,d,e,e,n);return 0; int n = sc

8、anf(%d%c%s%lf%f,&a,&b,c,&d,&e);printf(%d %c %s %lf %e %f %d,a,b,c,d,e,e,n);input: 123a teststring 8.9 9.2output: 123 a teststring 8.900000 9.200000e+000 9.200000 5input: 123ateststring 8.9 9.2output: 123 a teststring 8.900000 9.200000e+000 9.200000 5input: 123 a teststring 8.9 9.2output: 123 a 0.000

9、000 0.000000e+000 0.000000 3#include int main() int a,b;char c;char s20;_int64 n = 9876543210001111;scanf(%d %c,%s%x%I64d,&a,&c,s,&b, &n);printf(%d %x %u %s %p %x %d %I64d,a,a,a,s,s,b,b,n);return 0; input: -28 K,test ffee 1234567890123456output: -28 ffffffe4 4294967268 test 0012FF60 ffee 65518 12345

10、67890123456main()main() char * s;char * s;scanfscanf( ( “% %s s”,s,s);); 错在何处?错在何处?常见错误:错在错在 s s 不知道指向何处,往其指向的地方写入数据,不知道指向何处,往其指向的地方写入数据,不安全不安全char * char * gets(chargets(char * s); * s);从标准输入读取一行到字符串从标准输入读取一行到字符串s s如果成功,返回值就是如果成功,返回值就是 s s 地址地址如果失败,返回值是如果失败,返回值是 NULLNULL可以根据返回值是可以根据返回值是 NULLNULL判定输

11、入数据已经读完判定输入数据已经读完调用时要确保调用时要确保 s s 指向的缓冲区足够大,否则可能发生指向的缓冲区足够大,否则可能发生内存访问错误内存访问错误读取一行:#include #include intint main() main() char s200;char s200;char * p = char * p = gets(sgets(s););printf(%s:%s,s,pprintf(%s:%s,s,p););return 0; return 0; input:input:Welcome to Beijing !Welcome to Beijing !output:outpu

12、t:Welcome to Beijing !:Welcome to Beijing !Welcome to Beijing !:Welcome to Beijing !读取一行:intint sscanf(constsscanf(const char * buffer, const char * char * buffer, const char * format, address, .);format, address, .);和和scanfscanf的区别在于,它是从的区别在于,它是从bufferbuffer里读取数据里读取数据intint sprintf(charsprintf(char

13、 *buffer, const char *format, *buffer, const char *format, argument, .);argument, .);和和printfprintf的区别在于,它是往的区别在于,它是往bufferbuffer里输出数据里输出数据sscanf 函数和 sprintf函数#include int main() int a,b; char c; char s20;char szSrc = -28 K,test ffee 1234567890123456;char szDest200;_int64 n = 9876543210001111;sscanf

14、(szSrc, %d %c,%s%x%I64d,&a,&c,s,&b, &n);sprintf(szDest, %d %x %u %s %p %x %d %I64d,a,a,a,s,s,b,b,n);printf(%s,szDest);return 0; output: -28 ffffffe4 4294967268 test 0012FF60 ffee 65518 1234567890123456五个函数五个函数, 一个概念一个概念lscanflprintflsscanflsprintflgetsl补码内容提要内容提要l课程简介l输入输出l位运算l函数指针l命令行参数l库函数l程序风格位运算

15、 有时我们需要对某个整数类型变量中的某一位(bit)进行操作,比如,判断某一位是否为1,或只改变其中某一位,而保持其他位都不变。C/C+语言提供了“位运算”的操作,能够做到类似的操作。 C/C+语言提供了六种位运算符来进行位运算操作: & 按位与 | 按位或 按位异或 取反 右移按位与 按位与运算符“&”是双目运算符。其功能是将参与运算的两操作数各对应的二进制位进行与操作,只有对应的两个二进位均为1时,结果的对应二进制位才为1,否则为0。例如:表达式“21 & 18 ”的计算结果是16(即二进制数10000),因为:21 用二进制表示就是: 0000 0000 0000 0000 0000 0

16、000 0001 0101 18 用二进制表示就是: 0000 0000 0000 0000 0000 0000 0001 0010二者按位与所得结果是: 0000 0000 0000 0000 0000 0000 0001 0000 按位与按位与运算通常用来将某变量中的某些位清0或保留某些位不变。例如,如果需要将int型变量n的低8位全置成0,而其余位不变,则可以执行:n = n & 0xffffff00; 也可以写成:n &= 0xffffff00;如果n是short类型的,则只需执行:n &= 0xff00;如何判断一个int型变量n的第7位(从右往左,从0开始数)是否是1 ?只需看表达

17、式 “n & 0x80”的值是否等于0x80即可。按位与 按位或运算符|是双目运算符。其功能是将参与运算的两操作数各对应的二进制位进行或操作,只有对应的两个二进位都为0时,结果的对应二进制位才是0,否则为1。 例如:表达式“21 | 18 ”的值是2321: 0000 0000 0000 0000 0000 0000 0001 0101 18: 0000 0000 0000 0000 0000 0000 0001 001021|18: 0000 0000 0000 0000 0000 0000 0001 0111 按位或运算通常用来将某变量中的某些位置1或保留某些位不变。 例如,如果需要将in

18、t型变量n的低8位全置成1,而其余位不变,则可以执行:按位或n |= 0xff; 按位异或运算符是双目运算符。其功能是将参与运算的两操作数各对应的二进制位进行异或操作,即只有对应的两个二进位不相同时,结果的对应二进制位才是1,否则为0。例如:表达式“21 18 ”的值是7(即二进制数111)。21: 0000 0000 0000 0000 0000 0000 0001 0101 18: 0000 0000 0000 0000 0000 0000 0001 00102118: 0000 0000 0000 0000 0000 0000 0000 0111 异或运算的特点是:如果 ab=c,那么就

19、有 cb = a以及ca=b。此规律可以用来进行最简单的加密和解密。按位异或 按位非运算符“”是单目运算符。其功能是将操作数中的二进制位0变成1,1变成0。 例如,表达式“21”的值是无符号整型数 0xffffffea21: 0000 0000 0000 0000 0000 0000 0001 0101 21: 1111 1111 1111 1111 1111 1111 1110 1010而下面的语句: printf(%d,%u,%x,21,21,21);输出结果就是: -22,4294967274,ffffffea按位非 左移运算符“”是双目运算符。其计算结果是将左操作数的各二进位全部左移若

20、干位后得到的值,右操作数指明了要左移的位数。左移时,高位丢弃,右边低位补0。左移运算符不会改变左操作数的值。左移运算符例如,常数9有32位,其二进制表示是:0000 0000 0000 0000 0000 0000 0000 1001因此,表达式“94”的值,就是将上面的二进制数左移4位,得:0000 0000 0000 0000 0000 0000 1001 0000即为十进制的144。 实际上,左移1位,就等于是乘以2,左移n位,就等于是乘以2n。而左移操作比乘法操作快得多。左移运算符#include main() int n1 = 15; short n2 = 15;unsigned s

21、hort n3 = 15;unsigned char c = 15;n1 = 15; n2 = 15;n3 = 15;c = 6; printf( n1=%x,n2=%d,n3=%d,c=%x,c4=%d,n1,n2,n3,c,c 4);上面程序的输出结果是:n1=78000,n2=-32768,n3=32768,c=c0,c4=3072n1: 0000 0000 0000 0000 0000 0000 0000 1111 n2: 0000 0000 0000 1111n3: 0000 0000 0000 1111c: 0000 1111n1 = 15: (变成78000) 0000 0000

22、 0000 0111 1000 0000 0000 0000 n2 = 15: ,(变成-32768) 1000 0000 0000 0000 n3 = 15: (变成 32768) 1000 0000 0000 0000c = 6; (变成 c0) 1100 0000 c 4 这个表达式是先将 c 转换成整型0000 0000 0000 0000 0000 0000 1100 0000 然后再左移。 c”是双目运算符。其计算结果是把“ ”的左操作数的各二进位全部右移若干位后得到的值,要移动的位数就是“”的右操作数。移出最右边的位就被丢弃。 对于有符号数,如long,int,short,cha

23、r类型变量,在右移时,符号位(即最高位)将一起移动,并且大多数C/C+编译器规定,如果原符号位为1,则右移时左边高位就补充1,原符号位为0,则右移时高位就补充0。右移运算符 对于无符号数,如unsigned long,unsigned int, unsigned short, unsigned char类型的变量,则右移时,高位总是补0。 右移运算符不会改变左操作数的值。 实际上,右移n位,就相当于左操作数除以2n,并且将结果向下取整。 -25 4 = -2 -2 4 = -1 18 4 = 1右移运算符#include main()int n1 = 15; short n2 = -15;un

24、signed short n3 = 0xffe0;unsigned char c = 15;n1 = n12; n2 = 3;n3 = 4;c = 3; printf( n1=%x,n2=%d,n3=%x,c=%x,n1,n2,n3,c);上面的程序输出结果是:n1=3,n2=-2,n3=ffe,c=1n1: 0000 0000 0000 0000 0000 0000 0000 1111 n2: 1111 1111 1111 0001n3: 1111 1111 1110 0000c: 0000 1111n1 = 2: 变成3 0000 0000 0000 0000 0000 0000 0000

25、 0011 n2 = 3: 变成-2 1111 1111 1111 1110 n3 = 4: 变成 ffe 0000 1111 1111 1110c = 3; 变成10000 0001思考题:思考题: 有两个int型的变量a和n(0 = n n ) & 1或: (a & (1 n 六个函数六个函数l& 按位与l | 按位或l 按位异或l 取反l 右移内容提要内容提要l课程简介l输入输出l位运算l函数指针l命令行参数l库函数l程序风格函数指针函数指针 程序运行期间,每个函数都会占用一段连续的内存空间。而函数名就是该函数所占内存区域的起始地址(也称“入口地址”)。我们可以将函数的入口地址赋给一个指

26、针变量,使该指针变量指向该函数。然后通过指针变量就可以调用这个函数。这种指向函数的指针变量称为“函数指针”。函数指针函数指针 函数指针定义的一般形式为:类型名 (* 指针变量名)(参数类型1, 参数类型2,); 其中“类型名”表示被指函数的返回值的类型。“(参数类型1, 参数类型2,)”中则依次列出了被指函数的所有参数的类型。例如:int (*pf)(int ,char); 表示pf是一个函数指针,它所指向的函数,返回值类型应是int,该函数应有两个参数,第一个是int 类型,第二个是char类型。函数指针函数指针 可以用一个原型匹配的函数的名字给一个函数指针赋值。要通过函数指针调用它所指向的

27、函数,写法为: 函数指针名(实参表);下面的程序说明了函数指针的用法#include void PrintMin(int a,int b)if( ab )printf(%d,a);elseprintf(%d,b);int main() void (* pf)(int ,int); int x = 4, y = 5; pf = PrintMin; pf(x,y); return 0;上面的程序输出结果是:4函数指针应用:快速排序库函数qsortvoid qsort(void *base, int nelem, unsigned int width, int ( * pfCompare)( con

28、st void *, const void *); base是待排序数组的起始地址, nelem是待排序数组的元素个数, width是待排序数组的每个元素的大小(以字节为单位) pfCompare是一个函数指针,它指向一个“比较函数”。该比较函数应是返回值为int,有两个参数为const void * 的函数int 函数名(const void * elem1, const void * elem2);快速排序库函数qsort 排序就是一个不断比较并交换位置的过程。qsort如何在连元素的类型是什么都不知道的情况下,比较两个元素并判断哪个应该在前呢?答案是,qsort函数在执行期间,会通过pf

29、Compare指针调用 “比较函数”,调用时将要比较的两个元素的地址传给“比较函数”,然后根据“比较函数”返回值判断两个元素哪个更应该排在前面。这个“比较函数”不是C/C+的库函数,而是由使用qsort的程序员编写的。在调用qsort时,将“比较函数”的名字作为实参传递给pfCompare。程序员当然清楚该按什么规则决定哪个元素应该在前,哪个元素应该在后,这个规则就体现在“比较函数”中。qsort函数的用法规定,“比较函数”的原型应是:int 函数名(const void * elem1, const void * elem2);该函数的两个参数,elem1和elem2,指向待比较的两个元素。

30、也就是说, * elem1和 * elem2就是待比较的两个元素。该函数必须具有以下行为:1) 如果 * elem1应该排在 * elem2前面,则函数返回值是负整数(任何负整数都行)。2) 如果 * elem1和* elem2哪个排在前面都行,那么函数返回03) 如果 * elem1应该排在 * elem2后面,则函数返回值是正整数(任何正整数都行)。快速排序库函数qsort#include #include int MyCompare( const void * elem1, const void * elem2 )unsigned int * p1, * p2;p1 = (unsigne

31、d int *) elem1; p2 = (unsigned int *) elem2; return (* p1 % 10) - (* p2 % 10 ); 下面的程序,功能是调用qsort库函数,将一个unsigned int数组按照个位数从小到大进行排序。比如 8,23,15三个数,按个位数从小到大排序,就应该是 23,15,8#define NUM 5int main()unsigned int anNUM = 8,123,11,10,4 ;qsort( an,NUM,sizeof(unsigned int),MyCompare); for( int i = 0;i NUM; i +

32、)printf(%d ,ani); return 0;上面程序的输出结果是:10 11 123 4 8 思考题思考题: : 如果要将an数组从大到小排序,那么MyCompare函数该如何编写?内容提要内容提要l课程简介l输入输出l位运算l函数指针l命令行参数l库函数l程序风格命令行参数 将用户在DOS窗口输入可执行文件名的方式启动程序时,跟在可执行文件名后面的那些字符串,称为“命令行参数”。命令行参数可以有多个,以空格分隔。比如,在Dos窗口敲: copy file1.txt file2.txt “copy”, “file1.txt”, “file2.txt” 就是命令行参数 如何在程序中获得

33、命令行参数呢? 命令行参数int main(int argc, char * argv) 参数argc就代表启动程序时,命令行参数的个数。C/C+语言规定,可执行程序程序本身的文件名,也算一个命令行参数,因此,argc的值至少是1。 argv是一个数组,其中的每个元素都是一个char* 类型的指针,该指针指向一个字符串,这个字符串里就存放着命令行参数。例如,argv0指向的字符串就是第一个命令行参数,即可执行程序的文件名,argv1指向第二个命令行参数,argv2指向第三个命令行参数。请看例子程序:#include int main(int argc, char * argv)for(int

34、i = 0;i =0?(x):-(x)推荐一种推荐一种C C程序标识符命名法程序标识符命名法4)函数名字中每个单词的头一个字母大写,其他字母小写。一般采用 动词+名词形式void PrintMessage();int WriteIdToFile( FILE * _fp, int _nId);5)结构定义加大写字母S作为前缀struct SPerson int nId;int nAge;推荐一种推荐一种C C程序标识符命名法程序标识符命名法6) 类定义加大写字母C作为前缀class CPerson int m_nId;7) 类型定义全部大写typedef struct SPerson PERSO

35、N;typedef struct SPerson * PPERSON; /指针加P标识符命名应注意的一些细节标识符命名应注意的一些细节1)标识符号应能提供足够信息,最好是可以发音的。2)为全局变量取长的,描述信息多的名字,为局部变量取短名字3)名字太长时可以适当采用单词的缩写。但要注意,缩写方式要一致。要缩写就全都缩写。比如 单词Number, 如果在某个变量里缩写成了:int nDoorNum;那么最好包含 Number单词的变量都缩写成 Num。4)注意使用单词的复数形式。如int nTotalStudents, nStudents ;容易让人理解成代表学生数目,而 nStudent 含义

36、就不十分明显标识符命名应注意的一些细节标识符命名应注意的一些细节5) 对于返回值为真或假的函数,加“Is”前缀如:int IsCanceled();intisalpha(); / C语言标准库函数BOOLIsButtonPushed();6) 对于获取某个数值的函数,加 “Get”前缀char * GetFileName();7) 对于设置某个数值的函数,加“Set”前缀void SetMaxVolume();8) 一般变量和结构名用名词,函数名用动词或动宾词组。程序书写格式注意事项程序书写格式注意事项1)正确使用缩进首先,一定要有缩进,否则代码的层次不明显。缩进应为4个空格较好。需要缩进时一

37、律按Tab键,或一律按空格键,不要有时用Tab键缩进,有时用空格键缩进。一般开发环境都能设置一个Tab键相当于多少个空格,此时就都用Tab键程序书写格式注意事项程序书写格式注意事项2) 行宽与折行。 一行不要太长,不能超过显示区域。以免阅读不便。太长则应折行。折行最好发生在运算符前面,不要发生在运算符后面如if( Condition1() & Condition2() & Condition3() ) 程序书写格式注意事项程序书写格式注意事项3) 注意 , 位置不可随意,要统一如果写了:if ( condition1() ) DoSomething(); 别处就不要写if( condition

38、2() DoSomething() ;程序书写格式注意事项程序书写格式注意事项4) 变量和运算符之间最好加1个空格int nAge = 5;nAge = 4;if( nAge = 4 ) printf( “%d”,nAge);for( i = 0; i 100; i + );一些好的编程习惯一些好的编程习惯1)尽量不要用立即数,而用const 定义成常量,以便以后修改const int MAX_STUDENTS = 20struct SStudent aStudents MAX_STUDENTS;比struct SStudent aStudents 20; 好#define TOTAL_ELE

39、MENTS 100for( i = 0; i TOTAL_ELEMENTS; i +) 一些好的编程习惯一些好的编程习惯2)使用sizeof()宏,不直接使用变量所占字节数的数值int nAge;for( j = 0; j 100; j+ )fwrite( fpFile,& nAge, 1, sizeof(int);比for( j = 0; j 100; j+ )fwrite( fpFile,& nAge, 1, 4);好一些好的编程习惯一些好的编程习惯4)稍复杂的表达式中要积极使用括号,以免优先级理解上的混乱n = k + j; /不好n = ( k + ) + j; /好一点5)不很容易理

40、解的表达式应分几行写:n = ( k + ) + j;应该写成: n = k + j; k +;一些好的编程习惯一些好的编程习惯6)不提倡在表达式中使用 ? : 形式,而用if . else语句替代xp = 2 * k ( n-m) ? ck+1 : dk-;if( 2*k m ) & !( s t) 就不如 if( ( m = n ) & ( t 陈世忠 编著摩托罗拉公司审校人民邮电出版社1. 用一条语句将整型变量n中的第 i 位,变成和整型变量 m 的第 i 位一样,而 n 的其他位保持不变2. 用一条语句将整型变量n中的第 i 位取反,而n的其他位保持不变3.用一条语句将整型变量n中的左边 i 位都取反,而n的其他位保持不变第一讲思考题第一讲思考题

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

最新文档


当前位置:首页 > 高等教育 > 研究生课件

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