为了准备找工作,复习了一段时间的c++,而且有些内容当时复习了得还比较细致,做的笔记是纸质的,为了不使自己的这部分资料遗失,把它一点点放到网上来吧,从今天开始,一点一点。
C++笔记——C++编程思想
第一章 对象导言
1. 面向对象三大特性:封装、继承、多态。
2. C ++中的多态(晚捆绑)是通过虚函数实现的,在父类函数声明前加上关键字Virtual
3. 把处理派生类型就如处理基类型一样的处理方式,称为向上转型,即你烦引用指向子类对象时,不需要知道具体子类对象的类型。
4. 不论做了多少分析,总有一些问题是直到设计时才暴露出来的,并且更多问题是直到编码甚至程序运行时才暴露出来,因此,晚编码多分析的原则需要遵循,但应避免止步不前。
5. 编码之前至少应该知道的信息:(1)什么是对象,有哪些对象(2)对象之间如何协作通信。因此将功能性需求转化为类对象模型,是设计阶段的重要工作。
6. 分阶段地开发软件(哪怕是很小的软件),是大有益处的,它利于通过阶段性的讨论与计划降低风险,还可以从阶段性的文档中,发现项目一些问题的根源,利于改进。
7. 用UML可描述类的静态、动态、协作等模型;用例图是描述功能、设计及需求分析多方沟通的好工具。
8. 在系统开发的过程中,改动是允许的,尤其是对外接口不变时的改动(这要求接口设计合理)。但应尽量保证系统完成之后的修改尽量少,而且方便。
9. 类设计应该从简单开始,因为扩展一个功能比删除一个功能容易。
10. 功能理解清楚的情况下,从测试用例开始工作是不错的选择。再细化到需要哪些类及方法,也即先搭出架子,然后填充,这样也利于与用户交流功能,控制风险。
11. XP(极限编程)的两个最重要原则:测试驱动;结对编程(两个协作,写测试用例与具体实现分开由两人完成),以保证接口定义的抽象高度,避免自画自改。
12. Windows API是Windows操作系统与应用程序之间的标准接口,它提供了很多标准函数、宏和数据结构定义,VC++、VB、Delphi都可以调用。这些Windows API以动态链接库dll的形式存在,其中最重要的是User32.dll、Gdi32.dll、Kernel32.dll。User32.dll主要包括窗口管理函数;Gdi32.dll定义了图形设备函数(GDI);Kernel32.dll定义了一些系统底层如内存管理进程调度等。
13. Windows SDK软件开发工具包是封装了Windows API函数的一个工具包,SDK开发程序需程序员手动去实现各个功能(调用API),因此结构相对清晰,但代码量大。
14. C语言数据类型长度在ANSI C中的规定为:(1)short和long长度不同(2)int类型常与机器物理字长相同(事实不然)(3)short通常是16位,int为16位或32位,long最少是32位,short比int和long短。
15. 32位的X86系统中,C语言基本类型的长为(字节):
enum 4; char 1; unsigned char 1; signed char 1; signed 4; unsigned 4; int 4; signed int 4;
unsigned int 4; short 2; long 4; unsigned long 4; float 4; double 8; long double 8; 指针类型4;
没有元素的结构体1。
16. A的ASCII码值是65,a为97,空格32. 字符‘0’为48。
第二三章 对象的创建和使用
1. 解释器(与编译器)的优缺特点:用解释器工作时需要提供全部程序源代码,解释器需要常驻内存,由此导致速度慢及内存不足等;优点是不需要中间编译,有问题易于修改源码等。编译器的编译过程步骤多,执行时速度快,编译时进行词法分析、语法分析、代码转换、类型检查等。一般的模块化设计还有一个连接过程,编译成了二进制代码之后平台相关。
2. extern关键字声明函数原型与变量时表示函数或变量的定义在其它文件中。
3. #include “” 表从当前项目中查找,#include <>表示从系统定义的路径中查找。
4. #include <…h>,在C++中用#include<…>代替,例如使用旧版本的C库与C++新库分别表示为#include <stdio.h>和#include <cstdio>,带.h是老的非模板化版本,不带.h的是新的模板化的版本,同时用两种形式有时会有某些问题。
5. 连接库进行加载时,以文件为单位,因此若想减少程序的长度,可一个文件只放一个类或函数。
6. cout,cin都是C++ std名称空间中的一个对象,预定义对象。
7. using namespace std;表示使std名称空间中的所有变量,在当前文件中均可用。
#include <iostream.h>等同于#include <iostream>; using namespace std;两条语句。
8. cout<<dec<<15;表示将15以10进制输出,同理oct表示8进制,hex表16进制。
9. C++中调用其它外部程序用system(“ ”);语句,需要#include <cstdlib>。
10. 函数调用约定一般用来解决函数调用时参数进栈顺序和栈清理任务由谁完成的问题,通常的约定有:_stdcall、_cdecl、_fastcall、_thiscall、_nakedcall。
_stdcall又称pascal规范,参数从右往左入栈,被调函数负责清栈,函数名自动加前加下划线,后加@符号及参数的字节数(VC++),如int _stdcall fun(int a)则名为_fun@8。
_cdecl调用约定又称C约定,参数从右往左入栈,由于从右到左入栈,故第一个参数是确定的,可以支持可变参数,调用者负责清理栈。如printf。
_fastcall函数参数左起第一二个DWORD类型参数(或是更小的size类型)通过ecx,edx传递,其它参数从右往左,被调用者负责清理栈。
_thiscall不能由程序员显式声明,不是关键字,仅应用于C++类成员函数,因为C++函数调用有一个this指针传递,需要作特殊处理:参数从右往左入栈;参数个数确定时this通过ecx传递给被调用者,否则this在所有参数入栈后入栈,参数个数确定时,被调者清理,否则调用者清理。
_nakedcall为实模式调用,编译器不会为之增加寄存器初始化与恢复等代码,其返回值不能用return实现,只能通过修改寄存器实现。
11. WINAPI与CALLBACK是vc++中的两个宏:
#define WINAPI _stdcall;
#define CALLBACK _stdcall;
采用stdcall不支持可变参数个数,一般用于windows编译中窗口函数、定时处理等CALLBACK是老叫法,现在叫WINAPI。
12. CALLBACK回调:调用某函数时,给其一个函数指针作参数,以供被调用者需要时调用,如排序算法除了提供排序内容,也提供一个函数指针,供比较大小时调用,这样的排序函数可以更通用。
13. C++中提供的丰富的模板库如string, vector等使得一行行处理文件很方便,甚至一个个地处理单词。C++标准库对单词分隔支持不如Java好,但c++ Boost扩展了它,支持多线程,正则表达式等。
14. C中默认返回值类型为整形,C++中不允许默认,必须指定。
15. 按指针传递的方法示例为:void change (int *p){*p++;}调用:int a=5; change(&a);
按引用传递的方法示例为:void change (int &a){a++;}调用:int a=5; change(a);
可以看到引用传递对于函数调用者而言,与值传递一样,不明显。
16. C变量声明必须在函数开始处,C++允许在任何地方。
17. register变量只是告诉编译器尽可能快地访问此变量,不能保证编译器一定这么做,最好少用。
18. static定义的全局变量无法在其它文件中访问,即使extern也找不到。
19. #define PI 3.14与float const PI=3.14的区别:#define只进行文本替换,不作类型检查,也无法获得地址,而const常量可以,故换句话说const常量更好,但实现机制复杂一些,const在C与C++中实现不一样,C++中实现得更好。
20. C/C++中0表示false,其它非零值表示true。
21. & | ~ ^与或非异或这些都是位运算符,>>,<<表移位操作。
22. 四种C++类型转换:(1)static_cast用于良性或适度良性的转换,以及一些默认转换等;(2)const_cast用来将const/volatile等转换为非const/volatile类型,或反之,实际它只是从原const中取值形成一个拷贝,原值仍不变(3)reinterpret重解释转换是最危险的,它按内存逐字节是解释为另一类型(4)dynamic_cast用于类型安全的向下转换。
23. typedef用于声明类型别名,好处在于修改容易,名称易懂。
24. 对象用“.”引用,指针用“->”引用其成员。
25. enum枚举类型所做的事,c++中可用类做,故c++中很少用enum,枚举成员在c++中不允许用++运算,因为enum实际对应一个整数,++运算可能会导致代表另一个enum值。
26. 调用c++程序时,命令行中的输入为字符串数组,若要改为其它类型,需要用atoi, atof等函数。
27. float与double内存中分为三段:符号位、指数和尾数。
28. 调试技巧中,设一调试标志位debug=true,通过设置debug=false来禁止调试相关动作,c++中可用另一方法来定义debug,用#define宏定义,且用#ifdef将调试代码包起来,可决定是否编译调试部分的代码。 这样代码量编译后更少。
29. assert()语句用于调试,需包含cassert头文件,在#include <cassert>之前插入#define NDEBUG可忽略掉所有的assert()语句。
30. 声明函数指针示例:void (* ptrfunc)();//最右的()表参数类型表,void表返回值类型。