November 25
最近喜欢上了打羽毛球,报了个羽毛球选修课,买了个羽毛球拍。而且实验室从十月份开始,每周二晚上集体到体育馆打羽毛球。昨天举行的信息学院羽毛球比赛中,我还去客串了一回裁判。今天下午又看了一下午的中国羽毛球公开赛,看得有点热血沸腾。
最近打球也算很频繁了,所以我这个从零开始的新手也进步很大。但是一开始光瞎打也不行。这不上周二打球的时候把手腕弄伤了,到现在一活动,还能感到隐隐约约的疼。于是我就到网上找了一些羽毛球的教学视频来看,才知道原来是我的握拍方法不对,用力不正确,所以才弄伤了手腕。
其实无论学习东西,如果一开始有一个好的教师指导,固然是好。但是如果没有,就得自己摸索。当然自己摸索肯定会走很多弯路。像羽毛球这样的运动,如果一开始就养成错误的姿势和习惯,以后就很难改正了。幸亏从网上能下载到大师们的视频,使我能够找到自己的缺陷。
最后,给大家推荐几个个人认为比较不错的羽毛球视频:
1.李玲蔚羽毛球(3CD-轻松入门、快速提高、实战技巧)
2.肖杰的羽毛球技术讲解
3.熊国宝的国宝献技
November 15
今天晚上和ZX去三楼实验室玩,和他们几个研三的聊了聊天。今年实验室的毕业生找工作都找得很顺利,虽然第一个学期才刚过了一半,他们就都找到工作了。四个人,一个去了上海IBM,一个去了青岛朗讯,两个去了南京华为。这么快就找到了工作,他们以后也没有什么压力了。谈吐中大家都很高兴,希望明年我们也能顺利找到一份工作!
November 09
[读书笔记]<The C++: Complete Reference>第四版 Herbert Schildt著 周志荣 朱德芳 于秀山 等译
和基于C的I/O一样,C++的I/O系统是一个完全集成的系统,该系统的不同方面(例如,控制台I/O和磁盘I/O)实际上只是从不同角度看待同一种机制。
一、C++输入/输出系统基础
1.C++的流
像基于C的I/O系统一样,C++I/O系统通过流进行操作。我们可以把流归纳如下:一个流是一种既可以产生信息又可以消耗信息的逻辑设备,它通过I/O系统与一个物理设备相连。尽管流所产生连接的设备可以完全不同,但是所有的流以同样的方式运作。因为所有流的运作方式相同,所以实际上可以利用同样的I/O函数操作所有类型的物理设备。例如,可以利用同样的函数把信息写到文件或写到打印机和屏幕。采用这种方法的优点是只需要掌握一种I/O系统。
2.C++的流类
标准C++在头文件<iostream>中提供了对I/O系统的支持,在这个头文件中定义了一套相当复杂的层次结构以支持I/O操作。标准C++I/O类以一个模板类开始,创建了两种I/O模板类的说明:一个针对8位字符,另一个针对宽字符。
C++I/O系统建立在两 个既相关又不同的模板类层次结构之上。第一个类层次结构是从低级I/O类派生而来,称为basic_streambuf。这个类提供基本的输入/输出操作,而且还对可个C++I/O系统提供底层支持。除非你正在进行高级的I/O编程,否则不必直接使用basic_streambuf。最常使用的类层次是从basic_ios派生而来的,这是一个高级I/O类,可以提供格式化、错误检查和与I/O相关的状态信息(一个basic_iso的基类称为ios_base,它定义了几个为basic_ios所用的非模板特性)。basic_ios用作几个派生类的基类,这些派生类包括basic_istream,basic_ostream和basic_iostream,利用这些类可以分别创建输入流、输出流和输入/输出流。要说明的一点是:ios类包含许多成员函数和变量,它们可以监控基本的流操作,而且将被频繁地引用。
3.C++的预定义流
一个C++程序开始执行时将自动打开四个内置流,这些内置流是:
| 流
| 含义
| 默认设备
|
| cin
| 标准输入
| 键盘
|
| cout
| 标准输出
| 屏幕
|
| cerr
| 标准错误输出
| 屏幕
|
| clog
| cerr的缓冲版本
| 屏幕 |
cin,cout和cerr流与C的stdin,stdout和stderr相对应。
默认情况下,标准流用来与控制台通信。然而,在支持I/O重定向的环境中(例如,DOS,Unix,OS/2和Windows),标准流可以被重定向到其他设备或文件。标准C++还定义了四个附加的流:win,wout,werr和wlog,它们都是宽字符版本的标准流。宽字符的类型是wchar_t,一般为16位。宽字符用于存放与一些自然语言有关的大型字符集。
4.格式化的I/O
C++I/O系统允许你对I/O操作进行格式化。例如,可以设置域宽度、指定数字基数以及决定显示小数点后面的数字位数。有两种相互关联但概念上不同的格式化数据的方式。第一种方式可以直接访问ios类的成员,确切的说,可以设置ios类内定义的各种格式化状态标记或调用各种ios成员函数;第二种方式可以使用称之为操纵算子(manipulator)的特殊函数,该函数是I/O表达式的一部分。
5.插入器和析取器
<<和>>运算符在C++中被重载,从而可以对C++的内置类型执行I/O操作。你还可以对这些运算符重载,以使其对你所创建的类型执行I/O操作。
在C++中,因为<<可以把字符插入到一个流中,所以该输出运算符被称为插入运算符。同样,>>输入运算符被称为析取运算符,因为该运算符可以从 一个流中提取字符。重载插入和析取运算符的函数通常被称为插入器(inserter)和析取器(extractor)。
通常将插入器<<和析取器>>定义为类的友员函数,此举既可以满足将插入或析取器的第一个参数作为流的一个要求,又可以保证该函数可访问重载它的类的私有成员。
二、C++文件的输入/输出
尽管C++的I/O形成了一个完整的系统,但是文件I/O却十分特殊,以至于被普遍看做是一种特例,它们有自己的约束和特点。之所以会这样,部分是因为最常用的文件是磁盘文件,而磁盘文件有一些其他设备所有具备的性能和功能。然而要记住磁盘文件的I/O只是一般I/O系统的一个特例。
为了执行文件的I/O,必须在程序中包括头文件<fstream>。该头文件定义了一些类,其中包括ifstream,ofstream和fstream,这些类分别从istream,ostream和iostream派生而来。记住,因为istream,ostream和iostream是从ios派生而来的,所以ifstream,ofstream和fstream同样可以访问ios定义的所有操作。文件系统使用的另一个类是filebuf,这个类提供用于管理文件流的低级功能程序,通常情况下,我们不直接使用filebuf,而是将其作为其他文件类的一部分。
[读书笔记]<The C++: Complete Reference>第四版 Herbert Schildt著 周志荣 朱德芳 于秀山 等译
C++支持两种I/O系统。第一种是从C中继承来的,第二种是由C++定义的面向对象的I/O系统。本文上篇讨论C语言的I/O子系统,下篇将讨论C++的I/O系统。
在C语言中,输入和输出是通过库函数来完成的。既有控制台函数,也有文件I/O函数。从技术上讲,控制台I/O和文件I/O之间只有很小的差别。然而,从概念上讲,它们是两个截然不同的范畴。标准CI/O函数都是使用头文件stdio.h。C++程序也可以使用C++风格的头文件<cstdio>。
一、C风格的控制台I/O
控制台I/O函数从键盘输入并输出到屏幕上。然而,这些函数实际上让系统的标准输入和标准输出作为它们的I/O操作的目的和源。此外,标准输入和标准输出也可重定向到其他设备。
1.最简单的控制台I/O函数是getchar()和putchar()
其原型如下:
int getchar(void);
int putchar(int c);
2.gets()和puts()是控制台I/O中更复杂、更高效率的函数,它们使你能够读写字符串。
其原型如下:
char *gets(char *str);
int puts(const char *str);
3.格式化的控制台I/O
printf()和scanf()是两个实现格式化输入输出的函数。它们在用户的控制下以不同的格式读写数据。两者都可以操作包括字符、字符串和数字在内的任何内嵌数据类型。其原型如下:
int prinf(const char *control_string,...);
int scanf(const char *control_string,...);
二、C风格的文件I/O
在开始讨论C语言的文件系统之前,了解流和文件这两个概念之间的差别是很重要的。C的I/O系统给程序员提供了一个独立于设备进行信息访问的友好界面。即,C的I/O系统在程序员和实际设备之间提供了一级抽象,这个抽象称为流,而物理设备称为文件。
1.流
C文件系统可在包括终端、磁盘驱动器和磁带驱动器等众多设备上工作。不管设备有多大差异,文件系统都把它们转换成“流”的逻辑设备,且所有流的行为是类似的。因为流具有极大的设备无关性,所以向一个磁盘文件进行写操作的同一个函数也可以完成向另一种设备(如控制台)的写操作。有两种类型的流:文本流和二进制流。
文本流由一系列字符组成,标准C允许(但不要求)一个文本被组织成多行,以换行符终止一行。然而,在最后一行上换行符是可选的(实际上,大多数C/C++编译器都不需要使用换行符终止文本流)。在文本中,特定字符的转换是由主机环境要求的,例如,新行可以被转换成回车/换行符对。因而,被写(或读)的字符与存储在外设中的字符之间并无一一对应的关系。同样,由于可能的转换,被写(或读)的字符的数量可能与外设中存储的字符不一致。
二进制流是指一系列字节,这一系列字节与外设中存储的字节有一对一的头关系,也就是说,不存在字符转换。此外,写(或读)字节的数量与外设中存储的字节数相同。然而,根据实现决定的空字节数可以追加到一个二进制流中。例如,这些空字节有时用来补充信息以填满磁盘的某个扇区。
2.文件
在C/C++中文件可以是从磁盘文件到终端或打印机的任何东西。流通过执行打开操作与某个文件联系起来。文件一旦打开,里面的信息就可能在程序与该文件之间交换。
并非所有文件都有相同的功能。例如,磁盘文件支持随机访问,但某些打印机却不行。这就说明了C语言中I/O系统的一个重要特征:所有的流都是相同的,但文件却不同。
如果文件支持定位请求,那么打开文件也使文件位置指针初始化到文件的开始处。当字符从某个文件中读出或写到某个文件中时,文件位置指针加1,从而确保可以遍历整个文件。
文件通过关闭操作与特定流断开连接。当关闭一个为输出而打开的文件时,与它相关的流的内容(如果存在的话)被写到外设中。这一过程通常称为“清空”流,它保证了在磁盘缓冲区中不留下任何信息。当程序正常终止时所有文件都自动关闭,其关闭方式是要么通过返回到操作系统的main(),要么通过调用exit()。如果程序员因故障崩溃或调用abort()而终止,则文件不关闭。
与文件相关的流都有一个类型为FILE的文件控制结构。永远都不要对它进行任何修改操作。
3.标准流
虽然与C文件系统有关,程序一旦开始执行,就有三种流被自动打开。它们是标准输入(stdin)、标准输出(stdout)及标准错误(stderr)。通常,它们对应于控制台、但也可以通过操作系统重定向到支持可以重定向I/O环境(如Windows,Unix,OS/2和Dos)的其它设备中。
通常,stdin用于从控制台读,stdout用于从控制台写,stderr也用于从控制台写。可以在使用FILE*类型变量的任何函数中,把stdin,stdout和stderr当作文件指针使用。
例如,putchar()可以定义如下:
int putchar(char c)
{
return putc(c, stdout);
}
再例如,可以使用fgets()从控制台输入一个字符口串,按如下方式调用:
char str[255];
fgets(str, 80, stdin);
事实上,按这种方式使用fgets()是相当有用的。因为,当使用gets()时,可能越出数组的边界(现在正使用该数组来接收由用户键入的字符),因为gets()为提供边界检查。当和stdin一起使用时,fgets()提供了一个有用的替代物,因为它能限制所读的字符数,因而防止数组越界。惟一的麻烦是fgets()没有删除换行符而gets()删除了,所有你不得不手工删除它,如下面的程序所示:
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[80];
int i;
printf("Enter a string: ");
fgets(str, 10, stdin);
/*remove newline, if present*/
i = strlen(str)-1;
if(str[i] == '\n') str[i] = '\0';
printf("This is your string: s", str);
return 0;
}
记住,stdin,stdout和stderr不是普通变量,也不能通过fopen()进行赋值。还有,像这些文件指针在程序执行时自动创建一样,它们在结束时自动关闭,用户无法随意关闭它们。
4.控制台I/O连接
实际上,控制台I/O和文件I/O之间的区别很小。控制台I/O函数通过stdin或stdout完成I/O操作。实际上,控制台I/O函数只是一些并行文件函数的特例,它们的存在只是为了方便程序员。
正如上面3中所描述的那样,可以利用任何文件系统函数来完成控制台I/O。然而,最令人惊奇的是还可以使用控制台I/O函数来操作文件,如prinf()来完成磁盘文件I/O。这是因为所有的控制台I/O函数都操作于stdin和stdout。在允许I/O重定向的环境中,这意味着stdin和stdout可对应于包括键盘和屏幕的其他设备。例如,考虑如下程序:
#include <stdio.h>
int main(void)
{
char str[80];
printf("Enter a string: ");
gets(str);
printf(str);
return 0;
}
假定这个程序称为TEST,如果正常执行TEST,则在屏幕上显示提示,从键盘中读一个串,然后将该串显示在屏幕上。然而,在支持I/O重定向的环境中,stdin,stdout或两者都能被重定向到一个文件中。例如,在DOS或Windows环境中,执行TEST如下:
TEST > OUTPUT
于是TEST的输出结果写到了OUTPUT文件中。若执行如下:
TEST < INPUT > OUTPUT
stdin被导向INPUT文件中,并发送输出到OUTPUT文件中。
当程序终止时,任何重定向流都复位到它们的默认状态。
5.使用freopen()来重定向标准流
使用freopen()可以重定向标准流。这个函数用于将某一现存流与一个新文件联系起来。因此,可以用它将一个标准流与一个新文件联系起来。它的原型是:
FILE *freopen(const char *filename, const char *mode, FILE *stream);
其中,filename是一个指向你希望与stream指向的流相关联的文件名的指针。该文件以mode值方式打开,与fopen()相同。如果成功则返回流,否则,返回NULL指针。
下面的程序使用freopen()来重定向stdout到OUTPUT文件。
#include <stdio.h>
int mai(void)
{
char str[80];
freopen("OUTPU", "w", stdout);
printf("Enter a string: ");
gets(str);
printf(str);
return 0;
}
通常,用freopen()重定向标准流在一些特殊情况下(例如调试)是很有用的。然而,通过重定向stdin和stdout来完成磁盘I/O不一定与用fread()和fwrite()函数一样有效。
November 08
花了接近一周的时间把Herbert Schildt著的<The C++: Complete Reference>中译名<C++参考大全>看完了,感觉收获不小。
这本书是按标准C和标准C++分开来介绍的,内容全面,全书组织系统合理。在看这本书的过程中,澄清了不少以前模糊不清的概念,且学到了许多C和C++入门级读物中所没有的东西。由其对于C和C++编程一些细节上的区别和需要统一的地方讲得比较好。
个人认为这本书虽然是工具书级的,但仍然值得把它仔细的读完(指前两部分),然后对于第三部分(标准库函数)和第四部分(标准C++类库)可以现用现查。
不知道这本书什么时候能出最新版,如果出了的话一定要买一本收藏。
November 03
今天终于考完软设了,感觉上午的题目不难,75个选择题我用了四十来分钟就做完了,然后又检查了一个多小时。可是下午的考试却考得一塌糊涂。5个大题,有两个感觉做得还可以,其他的都拿不太准。不知道这次能不能考过了。
回来以后,晚上去看学院里的乒乓球比赛,还当了一会裁判,最后又打了一会球,感觉心情稍稍放松了一些。
终于又可以静下心来做一些事情了。
November 02
最近一周一直瞎忙,项目没了头绪,看了几天的VTK编程,打了几次的乒乓球和羽毛球,其余的时间都在准备软件设计师的考试。
明天就要考试了,不知道会怎样。感觉这次考试没能系统的复习,胜算不大。即使如此,也要认真去面对,要努力去争取!
本想参加明天晚上的乒乓球比赛的,可是看这个情况,等考完试也赶不回来了。
另外,考完试以后,一定要抓紧时间把项目搞定,否则仍然不能安心学习其他的东西~