《c++程序调试实用手册》
开篇十个问题
- 问题1 作为一个c/c++程序员,你的所有子程序代码都封装在函数体内,你知道还有其他类型的子程序否(与c/c++不同,许多语言还有另外一种类型的子程序成为过程)?
- 问题2 你是否知道过程子程序和函数子程序之间的所有区别?
- 问题3 你是否学习过如何解析一个表达式,考虑到操作符的优先级?
- 问题4 你是否知道属于先行EOF(look-ahead EOF)和非先行EOF(non-look-ahead)的含义?
- 问题5 你是否知道预读(priming read)语句的含义
- 问题6 你是否知道标记循环指的是什么?
- 问题7 你是否知道 static(静态)键字在内层,外层以及作为一个(数据或方法)类成员的作用是什么?
- 问题8 你是否知道编译器在翻译一个其方法体正式地定义在拥有其类内部的方法和翻译一个其方法体定义在拥有其类之外的方法时的区别?
- 问题9 你是否知道什么时候sizeof()函数报告(明显)错误的值及其原因是什么?
- 问题10 你是否知道递归算法指的是什么 (关于递归的定义请详见递归<grin>)?
- 1. c/c++软件工程师对于头文件中的定义全部采用大写,对于源文件(.c/.cpp)中的声明全部采用大小写混合使用的方式.唯一例外的是函数原型,类定义及STL语法
- 2. 匈牙利命名法通过在每一个标识符名字前面防止一个数据类型助记符,为程序员提供了对标识符类型的即时识别
- 3. Microsoft使用的一般前缀命名规范:
前缀 类型
C 类或结构体
m_ 成员变量
ch char,TCHAR
b BOOL
n UNIT
w WORD(16位无符号整形)
l LONG(32为有符号整形)
dw DWORD(32位无符号整形)
p *
lp FAR*(远指针)
lpsz LPSTR(32位字符串指针)
lpsz LPCSTR(32位常量字符串指针)
lpsz LPCTSTR(如果_UNICODE定义,为32位常量字符串指针)
h handle(Windows对象句柄)
lpfn callback(指向CALLBACK函数的远指针)
MFC、句柄、控件及结构的命名规范
Windows类型 |
样本变量 |
MFC类 |
样本变量 |
HWND |
hWnd; |
CWnd* |
pWnd; |
HDLG |
hDlg; |
CDialog* |
pDlg; |
HDC |
hDC; |
CDC* |
pDC; |
HGDIOBJ |
hGdiObj; |
CGdiObject* |
pGdiObj; |
HPEN |
hPen; |
CPen* |
pPen; |
HBRUSH |
hBrush; |
CBrush* |
pBrush; |
HFONT |
hFont; |
CFont* |
pFont; |
HBITMAP |
hBitmap; |
CBitmap* |
pBitmap; |
HPALETTE |
hPaltte; |
CPalette* |
pPalette; |
HRGN |
hRgn; |
CRgn* |
pRgn; |
HMENU |
hMenu; |
CMenu* |
pMenu; |
HWND |
hCtl; |
CState* |
pState; |
HWND |
hCtl; |
CButton* |
pButton; |
HWND |
hCtl; |
CEdit* |
pEdit; |
HWND |
hCtl; |
CListBox* |
pListBox; |
HWND |
hCtl; |
CComboBox* |
pComboBox; |
HWND |
hCtl; |
CScrollBar* |
pScrollBar; |
HSZ |
hszStr; |
CString |
pStr; |
POINT |
pt; |
CPoint |
pt; |
SIZE |
size; |
CSize |
size; |
RECT |
rect; |
CRect |
rect; |
一般前缀命名规范
前缀 |
类型 |
实例 |
C |
类或结构 |
CDocument,CPrintInfo |
m_ |
成员变量 |
m_pDoc, |
变量命名规范
前缀 |
类型 |
描述 |
实例 |
ch |
char |
8位字符 |
chGrade |
ch |
TCHAR |
如果_UNICODE定义,则为16位字符 |
chName |
b |
BOOL |
布尔值 |
bEnable |
n |
int |
整型(其大小依赖于操作系统) |
nLength |
n |
UINT |
无符号值(其大小依赖于操作系统) |
nHeight |
w |
WORD |
16位无符号值 |
wPos |
l |
LONG |
32位有符号整型 |
lOffset |
dw |
DWORD |
32位无符号整型 |
dwRange |
p |
* |
指针 |
pDoc |
lp |
FAR* |
远指针 |
lpszName |
lpsz |
LPSTR |
32位字符串指针 |
lpszName |
lpsz |
LPCSTR |
32位常量字符串指针 |
lpszName |
lpsz |
LPCTSTR |
如果_UNICODE定义,则为32位常量字符串指针 |
lpszName |
h |
handle |
Windows对象句柄 |
hWnd |
lpfn |
callback |
指向CALLBACK函数的远指针 |
? |
应用程序符号命名规范
前缀 |
符号类型 |
实例 |
范围 |
IDR_ |
不同类型的多个资源共享标识 |
IDR_MAIINFRAME |
1~0x6FFF |
IDD_ |
对话框资源 |
IDD_SPELL_CHECK |
1~0x6FFF |
HIDD_ |
对话框资源的Help上下文 |
HIDD_SPELL_CHECK |
0x20001~0x26FF |
IDB_ |
位图资源 |
IDB_COMPANY_LOGO |
1~0x6FFF |
IDC_ |
光标资源 |
IDC_PENCIL |
1~0x6FFF |
IDI_ |
图标资源 |
IDI_NOTEPAD |
1~0x6FFF |
ID_ |
来自菜单项或工具栏的命令 |
ID_TOOLS_SPELLING |
0x8000~0xDFFF |
HID_ |
命令Help上下文 |
HID_TOOLS_SPELLING |
0x18000~0x1DFFF |
IDP_ |
消息框提示 |
IDP_INVALID_PARTNO |
8~0xDEEF |
HIDP_ |
消息框Help上下文 |
HIDP_INVALID_PARTNO |
0x30008~0x3DEFF |
IDS_ |
串资源 |
IDS_COPYRIGHT |
1~0x7EEF |
IDC_ |
对话框内的控件 |
IDC_RECALC |
8~0xDEEF |
Microsoft MFC宏命名规范
名称 |
类型 |
_AFXDLL |
唯一的动态连接库(Dynamic Link Library,DLL)版本 |
_ALPHA |
仅编译DEC Alpha处理器 |
_DEBUG |
包括诊断的调试版本 |
_MBCS |
编译多字节字符集 |
_UNICODE |
在一个应用程序中打开Unicode |
AFXAPI |
MFC提供的函数 |
CALLBACK |
通过指针回调的函数 |
库标识符命名法
标识符 |
值和含义 |
u |
ANSI(N)或Unicode(U) |
d |
调试或发行:D = 调试;忽略标识符为发行。 |
静态库版本命名规范
库 |
描述 |
NAFXCWD.LIB |
调试版本:MFC静态连接库 |
NAFXCW.LIB |
发行版本:MFC静态连接库 |
UAFXCWD.LIB |
调试版本:具有Unicode支持的MFC静态连接库 |
UAFXCW.LIB |
发行版本:具有Unicode支持的MFC静态连接库 |
动态连接库命名规范
名称 |
类型 |
_AFXDLL |
唯一的动态连接库(DLL)版本 |
WINAPI |
Windows所提供的函数 |
Windows.h中新的命名规范
类型 |
定义描述 |
WINAPI |
使用在API声明中的FAR PASCAL位置,如果正在编写一个具有导出API人口点的DLL,则可以在自己的API中使用该类型 |
CALLBACK |
使用在应用程序回叫例程,如窗口和对话框过程中的FAR PASCAL的位置 |
LPCSTR |
与LPSTR相同,只是LPCSTR用于只读串指针,其定义类似(const char FAR*) |
UINT |
可移植的无符号整型类型,其大小由主机环境决定(对于Windows NT和Windows 9x为32位);它是unsigned int的同义词 |
LRESULT |
窗口程序返回值的类型 |
LPARAM |
声明lParam所使用的类型,lParam是窗口程序的第四个参数 |
WPARAM |
声明wParam所使用的类型,wParam是窗口程序的第三个参数 |
LPVOID |
一般指针类型,与(void *)相同,可以用来代替 |
Edit and Continue不能处理的代码修改类型
更新资源文件.
修改只读文件中的代码.
修改使用/O1,O2,Og,Ox,/Ob1或/Ob2优化过的代码.
修改异常处理块.
修改数据类型,包括类,结构,联合或枚举的定义.
田间新数据类型.
删除函数或修改函数原型.
更新从另一台机器赋值而来并且未在本地建立的可执行程序.
调试版本和发行版本
Microsoft 将应用程序定义为与符号调试信息,或与调试库一起建立的程序的一个版本.其中包括了诊断帮助,并执行各种即成检查,以帮助调试一个程序.
Microsoft 将发行版本定义为程序的一个编译版本,其中不包括在调试模式中建立编译时所包含的调试和诊断特性.
产生映射文件(Mapfile)
Generate Mapfile选项
映射文件实际上是一个文本文件,其中包含了关于正在连接的程序的如下信息:
- 该文件的模块名称
- 该程序投文件的时间戳
- 程序组列表,每个组一segment:offset(段:偏移量)形式的其实地址,以及长度,组名和类构成.
- 公共符号列表,各地址均以segment:offset形式给出,包括符号的名字,浮动地址及定义符号的.obj文件.
- segment:offset形式的模块入口地址.
A mapfile is a text file (它是个文本格式的文件,你可以用notepad等打开)that contains the following information about the program being linked:
- The module name, which is the base name of the file
- The timestamp from the program file header (not from the file system)
- A list of groups in the program, with each group's start address (as section:offset), length, group name, and class
- A list of public symbols, with each address (as section:offset), symbol name, flat address, and .obj file where the symbol is defined
- The entry point (as section:offset)