2008年12月29日星期一

从无到有:LFS(LINUX FROM SCRATCH)成功

前一阵子为了装个CMS,在WIN上做了个APACHE+PHP+MYSQL的环境,用的PHPNOW,一点劲没费,轻松搞定,后来感觉用LINUX来实现更好,就装了个VM虚拟机,装了个RED HAT 9.0的环境,安装一次要用1个小时左右,安装下来1.5G,从无到有安装了APACHE,PHP,MYSQL,从网上找了几个教程参考,也没费什么劲也搞定了,成功用远程的方式安装了CMS,心里倍有成就感,可是就只用到APACHE,PHP,MYSQL这几个功能却装了有1.5G,心里很不甘心,基本上没用到什么功能,却占用了这么多空间,就有心想把这个系统安装成最小化的只运行这个CMS,然后就是重装最小化安装,不到500M,安装完后增加功能时发现包依赖程度太高,安装非常不顺利,就想用源码安装来做后来还是失败了,就在网上找最小化的LINUX,无意中发现了LFS,发现正是我需要的.于是非常兴奋,用了一晚上时间下载了LIVECD6.3,因为从网上看到,说建LFS最好是用最新的系统来做,RED HAT9太老,所以下了LIVECD.OK,虚拟机,ISO全部就位,准备安装.
说简单点,LFS就是从新做一个新的系统,要用一个成型的系统来做这个环境,因为全部是源码安装,所以需要编译环境,然后就是用宿主系统先编译一个能编译系统的环境再一步一步把系统搭建起来然后再自己编译自己

我的环境IBM THINKPAD T23 1.13gCPU 512M VM6.5,第一次做要做成功来提升下信心,所以全部按照孙海勇(冲天飞豹)的第二版 手把手教你做自己的LINUX系统,完全按照他的步骤来实现的,来想转来的,但原文的结构做的太好了,转了后会破坏了可读性,所以就做个链接,如有兴趣可按原文去实现一下.第一遍全部按步骤来做,后来做到做自己工具链时做测试太费时间,正好朋友有个IBM R50从那本上又做了一套,这个完全省略了测试步骤,全部时间大概12小时左右,比T23还早完成了,终于12小时完成自己的LFS的创建,从网上下了LYNX,和WGET两个软件,有了它两个就可以自给自足的扩展自己的LFS了,这样就从LFS到了BLFS阶段.

后记,T23上的系统不知什么原因在做最后内核编译的时候出现了错误,所以失败了,现在正准备做第二次LFS.希望这次的关键步骤尽量自己体会,按自己的理解来实现.

2008年12月18日星期四

xp下用VMWARE装 LINUX(安装篇)

早在98年就接触过LINUX了,那时是XTEAM1.0,也曾在自己的奔二300上装过,新鲜了一阵也就过去了,后来用LINUX给朋友网吧里做了个CS服务器,并在上面安装了个流媒体服务,用了一阵子后来我人去了沈阳,那服务器没人玩的了就换了.再后来兴ADSL了单线慢就用一台闲的机器用LINUX做了个双ADSL的负载服务器运行了好几个月,后来被双WAN口的交换机给替了,玩LINUX也有了点感情,自己也比较关注这方面的信息.现在又想来用LINUX来了,现在LINUX的发行版不计其数,现在好像是UBUNTU最火,不过我手头只有REDHAT的9.0,反正以前也用过,现在正好拿这个练练手,继续学习LINUX.


原来装LINUX就要把系统全干掉才能装,所以很多时候想用LINUX是不方便,但现在有了虚拟机这一切都成了现实,想用哪个就用哪个了.

安装环境:WINXP SP3 + VMWARE +REDHAT 9.0

装这个LINUX的目的主要是为了学编程,还有做网站服务器这两方面


废话不再说了,进入正题,安装LINUX

首先在要WINXP里安装虚拟机软件,这个不用再说了,就是VMWARE(官方下载页面),填个表就能得到一个序列号能用30天

安装VMWARE不再废话,安装LINUX我用的是三张ISO的RH9.0



在这里指明要用的ISO镜像

以下两步设置虚拟机的光驱启动




后面的就是安装LINUX的步骤了,这个就不用说了,根据自己需要选择,全中文的,别说看不懂

下面有一个要说的就是半路一张ISO装完后要第二个ISO的时候,开始我没弄明白白装了好几遍,后来上网找到了,这也是VM的功能如下图


2008年12月7日星期日

UML中所使用的图

--------摘自《面向对象分析与设计》(UML2.0版)
UML有13种类型的图。UML规范没有要求这些图应在什么方法学中使用,所以可以在合适的任何阶段使用。
  • 用例图对系统的使用方式分类。
  • 类图显示类和它们的相互关系(也可以显示对象)。
  • 对象图只显示对象和它们的相互关系。
  • 活动图显示人或对象的活动,其方式类似于流程图。
  • 状态机图显示生命周期比较有趣或复杂的对象的各种状态。
  • 通信图显示在某种情形下对象之间发送的消息。
  • 顺序图显示与通信图类似的信息,但强调的是顺序,而不是连接。
  • 包图显示相关的类如何组合,对开发人员有用。
  • 部署图显示安装已完成系统的机器、过程和部署制品。
  • 组件图显示可重用的组件(对象或子系统)及其接口。
  • 交互总图使用顺序图显示活动的各个步骤。
  • 时间图显示消息和对象状态的准确时间限制。
  • 复合结构图显示对象在聚合或复合中的相互关系,显示接口和协作的对象。

2008年12月1日星期一

C++良好编程习惯(二)

----摘自《C++编程金典》第二章--控制结构
  1. 在程序中合理进行缩进(缩排)处理,可显著增强程序的可读性--建议将每个缩进单位设为1/4英寸或3个空格字符。
  2. 在程序设计阶段,通常先用伪代码来“思考”程序,再将伪代码程序转换成真正的C++程序。
  3. if/else结构的两个主体语句都应缩进。
  4. 如同时有数级缩进,那么每级缩进都在上一级缩进的基础上增加相同数量的空格。
  5. 始终记得在if/else结构(或其他任何控制结构)中主置花括号,这样有助于避免它们不慎被遗忘,特别是在以后为if/esle从句添加语句时。
  6. 有的程序员在花括号内键入单独的语句之前,习惯于先输好复合语句的起始和结束花括号。这是一个很好的习惯,有助于避免不慎漏掉一个或两个花括号。
  7. 无论如何都要初始化计数器和总和。
  8. 单独用一行声明每个变量。
  9. 进行除法运算时,假如除数可能为零,请务必明确检测这一条件,并在程序中预先采取防范措施(比如打印一条出错提示信息等等),不要让潜在的问题引发严重错误!
  10. 每次需要键盘输入时都提醒用户。提醒时,应指出输入所采取的形式,以及任何特殊值(比如用户应输入哪个标记来中止循环)。
  11. 在标记控制的循环中,请在输入数据提示中,明确告诉用户哪一个是标记。
  12. 不要试图对比两个浮点数是否相等。相反,应测试两个浮点数的差值的绝对值是否小于指定的值。
  13. 声明变量时便对其初始化,有助于程序员避免以后忘记初始化数据的问题。
  14. 一元操作符应紧挨操作数,中间不含任何空格。
  15. 用整数值来控制计数循环。
  16. 每个控制结构主体中的语句都进行缩进处理。
  17. 在每个控制结构前后都留一个空行,将其同程序的其余部分区分开。
  18. 嵌套级别过多,会导致程序难于理解。通常应把嵌套控制在3级以内。
  19. 控制结构上下的垂直间距,以及在控制结构头部对控制结构主体的缩进,可为程序员营造一种二维外观,从而极大增强可读性。
  20. 在while或for结构的条件中使用终值,并使用关系操作符<=有助于避免产生值相差1错误。例如,对用于打印1到10的循环来说,循环继续条件应是counter〈=11(尽管仍然是正确的)。许多程序员仍然喜欢所谓的“零基计数”。也就是说为通过一个循环计数10次,先将counter初始化为零,再将循环继续检测条件高为counter〈10。
  21. 在for结构的初始化及自增部分,应昼只使用与控制变量有关的表达式。如还需对其他变量进行处理,不在循环之前进行(前提是它们只执行一次,比如初始化语句),就在循环主体内进行(前提是每次重复都要执行,比如自增或自减语句)。
  22. 尽管可在for循环主体中更改控制变量的值,但尽量避免这样做,因为可能导致不易察觉的逻辑错误。
  23. 尽管for之前的语句以及for之内的语句经常都可合并到for的头部,但尽量避免这样做,因为这会降低程序的可读性。
  24. 尽可能将任何控制结构的头部限制在一行之内。
  25. 不要用float或double类型的变量来执行财务计算。不精确的浮点数会造成错误,得到不正确的金额。在练习中,我们探讨了用整数执行金融计算的方法。注意:可选择由第三方厂商提供的C++类库,它们能正确地执行金融计算。
  26. 无论如何都在switch语句中提供一个default条件。在无default条件的switch语句中,那些没有明确进行检测的情况会被忽略。如包括default条件,会使程序员关注对例外情况的需求。某些情况下,不需要进行default处理。尽管switch结构中的case从句和default从句可按任意顺序排列,但作为一个良好的习惯,应将default从句列于最后。
  27. 在switch结构中,假如default从句列于最后,则不需要为它使用break语句。有的程序员包括这个break的原因是为了更有条理,以及与其他case对应。
  28. 有的程序员习惯在do/while结构中包含花括号--即使花括号并无实际用途。这样做有助于区分while结构和只包含了一条语句的do/while结构。
  29. 有的程序员觉得break和continue违背了结构化编程准则。由于这些语句的效果可通过结构化编程技术实现,所以他们不使用break和continue。

2008年11月30日星期日

C++良好编程习惯(一)

--------摘自《C++编程金典》

  1. C++程序应以简单和直接的方式编写。这有时也称为KIS(“keep it simple”的简称,即“尽量简单”)编程方法。千万不要去尝试一些古怪的用法,去“折磨”这种语言。
  2. 仔细阅读你所用的C++版本的用户手册。经常查阅这些手册,才能确保自己能了解并正确使用C++的丰富特性。
  3. 计算机和编译器是最好的老师。仔细阅读了C++语言手册之后,如果你不能确定一项C++的特性是如何工作的,不妨用一个短小的“测试程序”进行实验,看其效果。设置编译器选项,令其报告“最多的警告”。研究程序编译时出现的每一条错误消息,并对程序进行纠正,去除这些消息。
  4. 每个程序都应以注释开头,以描述该程序的用途。
  5. 许多程序员让函数打印的最后一个字符是换行符(\n)。这样可保证函数将屏幕光标定位在一个新行的起始处。这样一个自发的约定可促进软件的重用能力——此为软件开发环境的一个重要目标。
  6. 针对每个函数的主体,令其在定义函数主体的花括号内部,缩进一个级别的位置。这样可使程序的函数结构更清晰,增强其可读性。
  7. 先为你喜欢的缩进距离拟出一个约定,然后始终坚持这一约定。可考虑用制表位(按Tab键)生成缩进。但是,不同的系统其制表位的距离往往不同。因此,建议你要么使用1/4英寸制表位,要么(一种更好的做法)用三个空格构成一个缩进级别。
  8. 有的程序员喜欢行行声明一个变量。采用这种格式,可方便地在每个声明后插入说明性的注释内容。
  9. 每个逗号(,)后面都应插入一个空格,以增强程序的可读性。
  10. 挑选一个有意义的变量名,将有助于保障程序的“自编档能力”;也就是说,只需读一读程序,即可轻松理解它,而不是必须求助于手册,或使用过多的注释。
  11. 避免标识符以下划线和双下划线开头,因为C++编译器可能采用这种形式的名称为其内部的某些用途提供服务。这样,有助于避免你选择的名称同编译器选择的名称混淆。
  12. 可执行语句之间的声明之前,需插入一个空行。这样可在程序中突出声明语句,使程序更加清晰。
  13. 如果你喜欢在一个函数的起始处放置声明,请用一个空行,以区分声明与函数中的可执行语句,突出声明结束的位置和可执行语句的开始位置。
  14. 在二元操作符的两端,请分别添加一个空格。这样可突出显示操作符,增强程序可读性。
  15. 与代数运算一样,可在表达式中加上多余的括号,使其更清晰。这些括号叫做冗余括号。冗余括号通常用于组合大型表达式中的各个子表达式,使表达式更加清晰。将一条大型语句分割为一系列较短的、较简单的语句,叫做澄清。
  16. 对if结构的主体语句采用缩进,可突出结构主体,并可增强程序可读性。
  17. 在一个程序中,每一行只应有一条语句。
  18. 较长的语句可分割到向个行上。如必须像这样分割一条语句,请挑选最合适的断点。比如对 一个用逗号分隔的列表来说,可选择在某个逗号之后断开;对于较长的表达式,可考虑在一个操作符之后断开等等。一个语句分割成多行后,除第一行之外,其他所有行都进行缩进处理。
  19. 如果一个表达式里有需要包含多个操作符,请务必参考操作符优先级表,核实表达式中的操作符按自己希望的顺序执行。如表达式过于复杂,以至于无法确定顺序,不妨将表达式分割为几个小语句,或者干脆用括号强行规定顺序——这样的做法和代数中无异。其间,请留意某些操作符=)是按从右到左的顺序结合的,而非从左到右。

2008年11月22日星期六

C/C++ COMPILER OPTIONS

cl 编译器的选项:
微软C/C++ 编译器选项
-优化-
/O1 最小化空间 minimize space
/Op[-] 改善浮点数一致性 improve floating-pt consistency
/O2 最大化速度 maximize speed
/Os 优选代码空间 favor code space
/Oa 假设没有别名 assume no aliasing
/Ot 优选代码速度 favor code speed
/Ob 内联展开(默认 n=0) inline expansion (default n=0)
/Ow 假设交叉函数别名 assume cross-function aliasing
/Od 禁用优化(默认值) disable optimizations (default)
/Ox 最大化选项。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs)
/Og 启用全局优化 enable global optimization
/Oy[-] 启用框架指针省略 enable frame pointer omission
/Oi 启用内建函数 enable intrinsic functions
-代码生成-
/G3 为 80386 进行优化 optimize for 80386
/G4 为 80486 进行优化 optimize for 80486
/GR[-] 启用 C++ RTTI enable C++ RTTI
/G5 为 Pentium 进行优化 optimize for Pentium
/G6 为 Pentium Pro 进行优化 optimize for Pentium Pro
/GX[-] 启用 C++ 异常处理(与 /EHsc 相同) enable C++ EH (same as /EHsc)
/EHs 启用同步 C++ 异常处理 enable synchronous C++ EH
/GD 为 Windows DLL 进行优化 optimize for Windows DLL
/GB 为混合模型进行优化(默认) optimize for blended model (default)
/EHa 启用异步 C++ 异常处理 enable asynchronous C++ EH
/Gd __cdecl 调用约定 __cdecl calling convention
/EHc extern“C”默认为 nothrow extern "C" defaults to nothrow
/Gr __fastcall 调用约定 __fastcall calling convention
/Gi[-] 启用增量编译 enable incremental compilation
/Gz __stdcall 调用约定 __stdcall calling convention
/Gm[-] 启用最小重新生成 enable minimal rebuild
/GA 为 Windows 应用程序进行优化 optimize for Windows Application
/Gf 启用字符串池 enable string pooling
/QIfdiv[-] 启用 Pentium FDIV 修复 enable Pentium FDIV fix
/GF 启用只读字符串池 enable read-only string pooling
/QI0f[-] 启用 Pentium 0x0f 修复 enable Pentium 0x0f fix
/Gy 分隔链接器函数 separate functions for linker
/GZ 启用运行时调试检查 enable runtime debug checks
/Gh 启用钩子函数调用 enable hook function call
/Ge 对所有函数强制堆栈检查 force stack checking for all funcs
/Gs[num] 禁用堆栈检查调用 disable stack checking calls
-输出文件-
/Fa[file] 命名程序集列表文件 name assembly listing file
/Fo 命名对象文件 name object file
/FA[sc] 配置程序集列表 configure assembly listing
/Fp 命名预编译头文件 name precompiled header file
/Fd[file] 命名 .PDB 文件 name .PDB file
/Fr[file] 命名源浏览器文件 name source browser file
/Fe 命名可执行文件 name executable file
/FR[file] 命名扩展 .SBR 文件 name extended .SBR file
/Fm[file] 命名映射文件 name map file
-预处理器-
/FI 命名强制包含文件 name forced include file
/C 不吸取注释 don't strip comments
/U 移除预定义宏 remove predefined macro
/D{=#} 定义宏 define macro
/u 移除所有预定义宏 remove all predefined macros
/E 将预处理定向到标准输出 preprocess to stdout
/I 添加到包含文件的搜索路径 add to include search path
/EP 将预处理定向到标准输出,不要带行号 preprocess to stdout, no #line
/X 忽略“标准位置” ignore "standard places"
/P 预处理到文件 preprocess to file
-语言-
/Zi 启用调试信息 enable debugging information
/Zl 忽略 .OBJ 中的默认库名 omit default library name in .OBJ
/ZI 启用调试信息的“编辑并继续”功能 enable Edit and Continue debug info
/Zg 生成函数原型 generate function prototypes
/Z7 启用旧式调试信息 enable old-style debug info
/Zs 只进行语法检查 syntax check only
/Zd 仅要行号调试信息 line number debugging info only
/vd{01} 禁用/启用 vtordisp disable/enable vtordisp
/Zp[n] 在 n 字节边界上包装结构 pack structs on n-byte boundary
/vm 指向成员的指针类型 type of pointers to members
/Za 禁用扩展(暗指 /Op) disable extensions (implies /Op)
/noBool 禁用“bool”关键字 disable "bool" keyword
/Ze 启用扩展(默认) enable extensions (default)
- 杂项 -
/?, /help 打印此帮助消息 print this help message
/c 只编译,不链接 compile only, no link
/W 设置警告等级(默认 n=1) set warning level (default n=1)
/H 最大化外部名称长度 max external name length
/J 默认 char 类型是 unsigned default char type is unsigned
/nologo 取消显示版权消息 suppress copyright message
/WX 将警告视为错误 treat warnings as errors
/Tc 将文件编译为 .c compile file as .c
/Yc[file] 创建 .PCH 文件 create .PCH file
/Tp 将文件编译为 .cpp compile file as .cpp
/Yd 将调试信息放在每个 .OBJ 中 put debug info in every .OBJ
/TC 将所有文件编译为 .c compile all files as .c
/TP 将所有文件编译为 .cpp compile all files as .cpp
/Yu[file] 使用 .PCH 文件 use .PCH file
/V 设置版本字符串 set version string
/YX[file] 自动的 .PCH 文件 automatic .PCH
/w 禁用所有警告 disable all warnings
/Zm 最大内存分配(默认为 %) max memory alloc (% of default)
-链接-
/MD 与 MSVCRT.LIB 链接 link with MSVCRT.LIB
/MDd 与 MSVCRTD.LIB 调试库链接 link with MSVCRTD.LIB debug lib
/ML 与 LIBC.LIB 链接 link with LIBC.LIB
/MLd 与 LIBCD.LIB 调试库链接 link with LIBCD.LIB debug lib
/MT 与 LIBCMT.LIB 链接 link with LIBCMT.LIB
/MTd 与 LIBCMTD.LIB 调试库链接 link with LIBCMTD.LIB debug lib
/LD 创建 .DLL Create .DLL
/F 设置堆栈大小 set stack size
/LDd 创建 .DLL 调试库 Create .DLL debug libary
/link [链接器选项和库] [linker options and libraries]

名称空间及其前途

---------摘自《C++ Primer Plus》第五版中文版
  随着程序员逐渐熟悉名称空间,将出现统一个编程理念。下面是当前的一些指导原则:
  • 使用在已命名的名称空间中声明的变量,而不是使用外部全局变量。
  • 使用在已命名的名称空间中声明的变量,而不是使用静态全局变量。
  • 如果开发了一个函数库或类库,将其放在一个名称空间中。事实上,C++当前提倡将标准函数库放在名称空间std中,这种做法扩展到了来自C语言中的函数。例如,头文件math.h是与C语言兼容的没有使用名称空间,但c++头文件cmath应将各种数学库函数放在名称空间std中。实际上,并非所有的编译器都完成了这种过渡。
  • 仅将编译指令using作为一种将旧代码转换为使用名称空间的权宜之计。
  • 不要在头文件使用using编译指令。首先,这样做掩盖了要让哪些名称可用;另外,包含头文件的顺序可能影响程序的行为。如果非要使用编译指令using,应将其放在所有预处理器编译指令#include之后。
  • 导入名称时,首选使用作用域解析操作符或using声明的方法。
  • 对于using声明,首选将其作用域设置为局部而不是全局。

别忘了,使用名称空间的主旨是简化大型编程项目的管理工作。对于只有一个文件的简单程序,使用using编译指令并非什么大逆不道的事。

正如前面指出的,头文件名的变化反映了这些变化。老式头文件(如iostream.h)没有使用名称空间,但新头文件iostream使用了std名称空间.

2008年11月20日星期四

何时使用引用参数

-------摘自《c++ primer puls》第五版中文版
使用引用参数的主要原因有两个:
  • 程序员能够修改调用函数中的数据对象.
  • 通过传递引用而不是整个数据对象,可以提高程序的运行速度.

当数据对象较大时(如结构和类对象),第二个原因最重要.这些也是使用指针参数的原因.这是有道理的,因为引用参数实际上是基于指针的代码的另一个接口.那么,什么时候应使用引用、什么时候应使用指针呢?什么时候又应按值传递呢?下面是一些指导原则:

  • 如果数据对象很小,如内置数据类型或小型结构,则按传值传递。
  • 如果数据对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向CONST的指针。
  • 如果数据对象是较大的结构,则使用CONST指针或CONST引用,以提高程序的效率。这样可以节省复制结构所需的时间和空间。
  • 如果数据对象是类对象,则使用CONST引用。类设计的语义常常要求使用引用,这是C++新增这项特性的主要原因。因此,传递类对象参数的标准方式是按引用传递。

对于修改调用函数中数据的函数:

  • 如果数据对象是内置数据类型,则使用指针。如果看到诸如fixit(&x)这样的代码(其中x是int型),则很明显,该函数将修改x。
  • 如果数据对象是数组,则只能使用指针。
  • 如果数据对象是结构,则使用引用或指针。
  • 如果数据对象是类对象,则使用引用。

当然,这只是一些指导原则,很可能有充分的理由做出其他的选择。例如,对于基本类型,cin使用引用,因此可以使用cin》n,而不是cin》&n。

2008年11月19日星期三

郭德刚--《善恶图》,经典!

  前几天无聊在优酷看搞笑小视频,无意中看了一段郭德刚的单口相声:《善恶图》,听到最后感觉故事没完。今天又看到了,才发现是这个单口是8段。今天下载了MP3一口气听完,感慨啊,太有才了。。。
  这个单口说的是清朝道光年间北京城发生的一件涉及到22条人命的故事

  详细请找找这几个小段子来听听,不是一般的经典。
下面是一个优酷的专辑:
善恶图

2008年11月14日星期五

初学C++:冒泡排序的写法

  今天看《C++编程金典》数组这一章,后面有个习题:4-11
4-11:图4-16中的冒泡排序并不适合大型数组,。执行以下简单修改提高冒泡排序方法的性能:
A):第一遍排序后,大型数字总会成为数组中编号最大的元素;第二遍排序后,就有两个编号最大的数字,依此类推。这样一来,就不是第次进行9次比较,而是第二遍比较8次,第3遍比交7次,依此类推。
B):数组中的数据可能已经按正确或接近于正确的顺序进行排列,所以如果比较次数较少也能达到理想的效果时,为什么一定要比较9次呢?修改排序方法,查看每次比较后是否数据有无交换,如果没有,那么数据肯定已经采用了正确的排序。如果有交换,则说明至少还需要一次排序。
  4-16的冒泡排序如下


for(int i=0;i<len-1;i++)
{

for(int a=0;a<len-1;a++)
{
if(array[a]>array[a+1])
{
hold=array[a];
array[a]=array[a+1];
array[a+1]=hold;
}
}
}

这个算法,不管怎么样都要执行(len-1)*(len-1)次。

如果按A的算法优化一下就要执行(len-1)*(len-1-(1+len-2)/2)=(len-1)*(len-1)/2次,也就相当于少执行了一半。

如果再按B的算法优化下,如果本来就是一个有序数组的话,仅需执行len-1次,整个降低了一个数量级。当然如果是最糟情况将执行(len-1)*(len-1)次。

A的算法在内循环完成一次就把内循环的记数条件减1就能做到。

增加一个全局变量比如:b=len-1;

然后在外循环中循环条件增加一个b--;

把内循环的执行条件改为j<b;

B的算法,只要内循环中的if 语句条件一次也没有执行就跳出循环便可做到。
增加一个全局变量比如:c=0;
然后把 if语句改成if-else 语句,IF条件没有执行也就相当于else语句执行了b次;
在else语句中加入c++;
然后在外循环处比较c ==b;
如不等则继续循环。如相等就退出循环排序完成。

2008年11月11日星期二

自己动手写:FOURUP 小程序

  学习VC只看书不写代码是不行的,书看得越多代码却不知道怎么写了......
  要不就是一看就明白,可是自己写却什么也写不出来,离了书就不会写了.
  为了避免这种情况一再的发生,写代码就变得非常重要了.
  现在要有一个习惯,看到完整的例子,看懂它,然后用自己所理解的去重写它,要在纸上列出个大纲来,一步一步把这个小例子填写完整,并编译运行,直到没有错误,正确显示为止.但在这个过程中,不要看书,要一气呵成,看一点写一点跟没写一样.

  昨天实在不知道要干什么,找到本电子书随意看了下,发现了一个小例子,叫FOURUP,是<跟我学VC++6>这本书上的一个例子,从第三章到第五章才完全的讲完,例子很简单,算法也很明确,是个用来写代码的好例子.

  首先分析这个例子的需求:
  这人例子大体就是随机出现四幅图片,然后根据这四幅图片的排列,来确定得了多少分。仅此而已。然后就用给出的界面写出它框架来。









里面用的控件,大部分都是装饰,有用的有
1、显示积分数的CStatic,就是100这个东西,书上是把包括四个图标的组框的CAPTION做为重写的东西,我因为变的只有分数,所以只重写数把它们分开了。

2、中间组框中的四个图片控件

3、开始按钮和取消按钮。

界面就是这样,下面再来确定一下要用到的变量:

1、用来存储积分的变量,书上用的的double,但这个一次减2,只是一个测试,所以用int来存储。
2、因为这个程序是用图标资源来做为图片来用的,所有要有四个图标,里面这个是我自己用资源管理器画的,用什么都无所谓的

3、还要一个用来存储某个图标出现了几次的变量,这个用一个int的数组来存储。


下面就来看一下主程序的流程:

主要就是点了开始按钮,积分减2,四个图标随机选择,然后按下面规则来计算得多少分然后加到积分的变量上
用书上的过程来说就是把这些过程再分解:
1、变量减2,这个是开始的条件,应该加个判断,比2小了就不能再玩了,提示或退出
2、显示四个图标。
3、根据显示计算得了多少分
4、把得分显示在控件上。
看了一下上面,还真是够啰嗦了。具体代码就不写了。

2008年10月22日星期三

这个超级玛丽就是我的目标,太牛了

网上无意看到一BT游戏,看样像是自己做的,太逗了,这个程序编得太牛了,超整人游戏,哈哈


一个比较好听的电吉他单曲



没事的时候听听,是种享受

2008年10月16日星期四

Serializable 的必要条件

-----摘自JJHOU<深入浅出MFC>第二版
欲让一个对象有Serialize 能力,它必须衍生自一个Serializable 类别。一个类别意欲成为Serializable,必须有下列五大条件;至于其原因,前面的讨论已经全部交待过了。
1. 从CObject 衍生下来。如此一来可保有RTTI、Dynamic Creation 等机能。
2. 类别的声明部份必须有DECLARE_SERIAL 宏。此宏需要一个参数:类别名称。
3. 类别的实作部份必须有IMPLEMENT_SERIAL 宏。此宏需要三个参数:一是类别名称,二是父类别名称,三是schema no.。
4. 改写Serialize 虚拟函数,使它能够适当地把类别的成员变量写入文件中。
5. 为此类别加上一个default 构造式(也就是无参数之构造式)。这个条件常为人所忽略,但它是必要的,因为若一个对象来自文件,MFC 必须先动态生成它,而且在没有任何参数的情况下调用其构造式,然后才从文件中读出对象资料。

2008年10月13日星期一

VC6 this指针介绍及小技巧(MFC)

-----------摘自<孙鑫VC深入详解>第二章

1、this指针是一个隐含的指针,它是指向对象本身,代表了对象的地址
2、一个类所有的对象调用的成员函数都是同一代码段。那么成员函数又是怎么识别属于同一对象的数据成员呢?原来,在对象调用pt.output(10,10)时,成员函数除了接受2个实参外,还接受到了一个对象s的地址。这个地址被一个隐含的形参this指针所获取,它等同于执行this=&pt。所有对数据成员的访问都隐含地被加上前缀this->。例如:x=0; 等价于 this->x=0。


小技巧:在MFC编程中,如果在成员函数中想调用同类中的某个成员,可以使用VC++提供的自动列出成员函数功能,使用this->,VC++将列出该类中的所有成员,我们可以从列表中选择我们想调用的成员。
自动列出成员函数功能,可以提高编写速度,减少拼写错误。我们经常不能完全记住某个函数的完整拼写,但却能够从列表中辨别出该函数,自动列出成员函数的功能在这时就显得更加有用了。事实上,在各种IDE编程环境中,我们通常都不可能记住也没有必要记住所有的函数,只要将常用的函数记住,其他不常用的函数只要记住其大概的写法和功能,在调用该函数时可以从自动列出成员函数中选取,这样可以大大节省我们的学习时间。我们不用花费大量的时间去死记硬背许多函数,利用自动列出成员函数功能和帮助系统,就能够在编程时顺利地使用这些函数,等用的次数多了,也就在不知不觉中完全掌握了这些函数。

2008年10月11日星期六

从标题栏删除文档名称(MFC)

MFC会自动将文档名称加到标题栏中,但有时我们根本就用不着显示文档名称,因此,我们必须采取一些特殊措施以防止MFC将文档名称插入标题栏.
在框架窗口类中,我们会找到用于删除文档名称的代码.CMainFrame::PreCreateWindow包含语句:
cs.style &= ~FWS_ADDTOTITLE;
FWS_ADDTOTITLE是MFC特有的一种特殊的窗口样式,默认状态下包含在框架窗口中.只是具有此样式的窗口才会把文档名称添加给窗口标题栏.在PreCreateWindow内通过从窗口标题栏撤消FWS_ADDTOTITLE位就阻止了框架结构修改其窗口标题.我们可以使用此技术从任何文档/视图应用程序的标题栏中删除文档名称.

2008年8月21日星期四

C++中最简单的WINDOWS程序的组成

---摘自C/C++程序员实用大全-Kris Jamsa,Lars Klander 1273

学习任何一样事物,总要从最简单的开始,但最简单也是有规范的...

设计Windows程序时,必须保证Windows程序包括下面的所有构件:
  • 资源文件:虽然可以编写不使用资源文件的Windows程序,但这样的程序会引起附加的工作,同时也不是标准的Windows程序结构,每个Windows程序都应该包括资源文件.然而不必为每个程序创建多于一个的资源文件,记住资源文件可能包含许多程序的信息以及给定程序的内容,所以应该把每个程序的所有信息放到一个文件中.
  • windows.h头文件:所有的Windows程序都必须包含windows.h头文件,该文件依次包含所有必需的头文件,这些头文件包含Windows特定的类型、函数、以及类。
  • WinMain函数:和所有的DOS程序需要main函数一样,所有的Windows程序必须包含WinMain函数,记住必须为WinMain函数指定其需要的四个参数:HINSTANCE hInstance、HINSTANCE hPrevInstance、LPSTR lpCmdLine、以及int nCmdShow。
  • Windows消息循环:每个需要用户交互(几乎所有的Windows程序)的Windows程序在消息循环中处理消息,消息循环从系统消息队列中检索消息并在程序中处理这些消息。
  • 消息回调函数:创建窗口时,窗口的一个参数指定把消息传到哪里,即消息回调函数,消息循环也把消息发送给回调函数,每个Windows应用程序必须有一个消息回调函数,通常消息回调函数的名子都一致,如WinMain所做的那样,当然这不是必需的的同样也可能有多个消息回调函数,它们分别处理不同程序窗口的消息。

几乎所有的Windows程序都有这五个部分,如果设计的程序不含有这些所有的五个部分,则可能很难使程序在Windows里正确工作。