windows程序设计:第二章:Unicode简介
2014-04-21 19:02
295 查看
本文是我学习《windows程序设计》(第5版)的笔记,方便以后查阅。如果被您看到并且对您有用的话,那再好不过了。本文不涉及具体的讲解,详细的讲解请看《windows程序设计》(第5版)这本书,它才是经典之作!
这本书是1998年出的,当时Unicode还没有成为国际标准,现在肯定是标准了。Unicode的作用:能够使计算机实现跨语言、跨平台的文本转换及处理。
先看代码:
运行结果如下:
![](http://img.blog.csdn.net/20140421190431062?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlxaWFuY2Fv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
函数声明:
int vsnprintf(char*str,size_tsize,constchar*format,va_listap);
参数说明:
1. char *str [out],把生成的格式化的字符串存放在这里.
2. size_t size [in],str可接受的最大字节数,防止产生数组越界.
3. const char *format[in], 指定输出格式的字符串,它决定了你需要提供的可变参数的类型、个数和顺序。
4. va_list ap [in],va_list变量.
函数功能:将可变参数格式化输出到一个字符数组。
用法类似于vsprintf,不过加了size的限制,防止了内存溢出(size为str所指的存储空间的大小)。
返回值:执行成功,返回写入到字符数组str中的字符个数(不包含终止符),最大不超过size;执行失败,返回负值,并置errno.
备注:
linux环境下是:vsnprintf
VC6环境下是:_vsnprintf
通过_vsnprintf()函数就把MessageBoxPrintf函数第二个参数的字符串值存入了第一的缓冲区szBuffer里
关于宏va_list,va_start,va_end:
这里要知道两个事情:
⑴在intel+windows的机器上,函数栈的方向是向下的,栈顶指针的内存地址低于栈底指针,所以先进栈的数据是存放在内存的高地址处。
(2)在VC等绝大多数C编译器中,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:最后一个固定参数的地址位于第一个可变参数之下,并且是连续存储的。
|-----------------------------------------|
|-------最后一个可变参数----------| ->高内存地址处
|-----------------------------------------|
|-----------------------------------------|
|--------第N个可变参数-------------|
|-----------------------------------------|
|-----------------------------------------|
|--------第一个可变参数------------| ->va_start(pArgList,szFormat)后pArgList所指的地方
|-----------------------------------------|
|--------最后一个固定参数---------|
|-----------------------------------------|
|-----------------------------------------|
|-----------------------------------------|
|---------第一个固定参数-----------| -> 低内存地址处
|-----------------------------------------|
|-----------------------------------------|
va_start,函数名称,读取可变参数的过程其实就是在堆栈中,使用指针,遍历堆栈段中的参数列表,从低地址到高地址一个一个地把参数内容读出来的过程·
在进程中,堆栈地址是从高到低分配的.当执行一个函数的时候,将参数列表入栈,压入堆栈的高地址部分,然后入栈函数的返回地址,接着入栈函数的执行代码,这个入栈过程,堆栈地址不断递减.
总之,函数在堆栈中的分布情况是:地址从高到低,依次是:函数参数列表,函数返回地址,函数执行代码段.
堆栈中,各个函数的分布情况是倒序的.即最后一个参数在列表中地址最高部分,第一个参数在列表地址的最低部分.
GetSystemMetrics ()函数:用于得到被定义的系统数据或者系统配置信息.
参数SM_CYSCREEN :以像素为单位计算的屏幕尺寸
(第4章中作者将具体讲解)
这本书是1998年出的,当时Unicode还没有成为国际标准,现在肯定是标准了。Unicode的作用:能够使计算机实现跨语言、跨平台的文本转换及处理。
先看代码:
#include <windows.h> #include <tchar.h> #include <stdio.h> int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...) { TCHAR szBuffer [1024] ; //定义缓冲区大小 va_list pArgList ;//定义一个va_list型的变量,这个变量是指向参数的指针 // The va_start macro (defined in STDARG.H) is usually equivalent to: // pArgList = (char *) &szFormat + sizeof (szFormat) ; va_start (pArgList, szFormat) ;//用va_start宏初始化变量,这个宏的第二个参数是第一个可变参数的前一个参数,是一个固定的参数. // The last argument to wvsprintf points to the arguments _vsntprintf (szBuffer, sizeof (szBuffer) / sizeof (TCHAR), szFormat, pArgList) ; // The va_end macro just zeroes out pArgList for no good reason va_end (pArgList) ;//用va_end宏结束可变参数的获取,将指针置为无效 return MessageBox (NULL, szBuffer, szCaption, 0) ;//把变量在消息框显示 } //windows入口函数 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { int cxScreen, cyScreen ; //获取屏幕的分辨率 cxScreen = GetSystemMetrics (SM_CXSCREEN) ;//横向 cyScreen = GetSystemMetrics (SM_CYSCREEN) ;//纵向 //调用MessageBoxPrintf,这里参数变成了四个 MessageBoxPrintf (TEXT ("ScreenSize"), TEXT ("The screen is %i pixels wide by %i pixels high."), cxScreen, cyScreen) ; return 0 ; }
运行结果如下:
本章的重点是如何实现MessageBoxPrintf函数,使用这个函数可以将变量在MessageBox中输出出来。并且程序中用到了C语言的变参技术(va_start, va_end)。首先看程序中的MessageBoxPrintf函数,如下:
intCDECLMessageBoxPrintf(TCHAR*szCaption,TCHAR*szFormat,...),可以看到这个函数的参数是变长的。类似于C语言中的print函数, int printf(constchar *format, ...);
那三个连续的点就代表大于或等于0个参数,再加上前面的format参数,所以printf函数至少要接受一个字符串,后面就随便了。
关于_vsnprintf()函数:函数声明:
int vsnprintf(char*str,size_tsize,constchar*format,va_listap);
参数说明:
1. char *str [out],把生成的格式化的字符串存放在这里.
2. size_t size [in],str可接受的最大字节数,防止产生数组越界.
3. const char *format[in], 指定输出格式的字符串,它决定了你需要提供的可变参数的类型、个数和顺序。
4. va_list ap [in],va_list变量.
函数功能:将可变参数格式化输出到一个字符数组。
用法类似于vsprintf,不过加了size的限制,防止了内存溢出(size为str所指的存储空间的大小)。
返回值:执行成功,返回写入到字符数组str中的字符个数(不包含终止符),最大不超过size;执行失败,返回负值,并置errno.
备注:
linux环境下是:vsnprintf
VC6环境下是:_vsnprintf
通过_vsnprintf()函数就把MessageBoxPrintf函数第二个参数的字符串值存入了第一的缓冲区szBuffer里
关于宏va_list,va_start,va_end:
这里要知道两个事情:
⑴在intel+windows的机器上,函数栈的方向是向下的,栈顶指针的内存地址低于栈底指针,所以先进栈的数据是存放在内存的高地址处。
(2)在VC等绝大多数C编译器中,默认情况下,参数进栈的顺序是由右向左的,因此,参数进栈以后的内存模型如下图所示:最后一个固定参数的地址位于第一个可变参数之下,并且是连续存储的。
|-----------------------------------------|
|-------最后一个可变参数----------| ->高内存地址处
|-----------------------------------------|
|-----------------------------------------|
|--------第N个可变参数-------------|
|-----------------------------------------|
|-----------------------------------------|
|--------第一个可变参数------------| ->va_start(pArgList,szFormat)后pArgList所指的地方
|-----------------------------------------|
|--------最后一个固定参数---------|
|-----------------------------------------|
|-----------------------------------------|
|-----------------------------------------|
|---------第一个固定参数-----------| -> 低内存地址处
|-----------------------------------------|
|-----------------------------------------|
va_start,函数名称,读取可变参数的过程其实就是在堆栈中,使用指针,遍历堆栈段中的参数列表,从低地址到高地址一个一个地把参数内容读出来的过程·
在进程中,堆栈地址是从高到低分配的.当执行一个函数的时候,将参数列表入栈,压入堆栈的高地址部分,然后入栈函数的返回地址,接着入栈函数的执行代码,这个入栈过程,堆栈地址不断递减.
总之,函数在堆栈中的分布情况是:地址从高到低,依次是:函数参数列表,函数返回地址,函数执行代码段.
堆栈中,各个函数的分布情况是倒序的.即最后一个参数在列表中地址最高部分,第一个参数在列表地址的最低部分.
GetSystemMetrics ()函数:用于得到被定义的系统数据或者系统配置信息.
参数SM_CYSCREEN :以像素为单位计算的屏幕尺寸
(第4章中作者将具体讲解)
相关文章推荐
- windows程序设计第二章-Unicode简介
- windows程序设计第二章-Unicode简介
- windows程序设计——开始、Unicode 简介
- windows程序设计 Unicode简介
- Windows程序设计[之]Unicode 简介
- [学习笔记]Windows程序设计:第二章 UNICODE
- windows程序设计之对话框简介1
- windows程序设计之编辑框简介
- windows 程序设计 第二章(下)
- Windows程序设计_Chap02_Unicode_学习笔记
- windows程序设计-第五版--读书笔记(2)--宽字符集和Unicode--文中内容摘取
- windows程序设计之编辑框简介
- windows程序设计学习笔记-Unicode,绘图基础
- windows程序设计第二章学习笔记
- MFC Windows 程序设计 第二章 在窗口中绘图
- 第二章 Unicode简介
- Windows 程序设计学习笔记二:Unicode
- windows 程序设计 第二章 (上)
- Programming Windows程式开发设计指南->第二章 Unicode简介
- windows程序设计之菜单简介