当前位置:文档之家› VC数据类型详解

VC数据类型详解

VC数据类型详解
VC数据类型详解

VC++常用数据类型及其操作详解

-------西安邮电学院计算机系

徐兆元(FLxyzsby@https://www.doczj.com/doc/dc18544894.html, FLxyzsby@https://www.doczj.com/doc/dc18544894.html,)

2004/08/03 目录

一.VC常用数据类型列表

二.常用数据类型转化

2.1数学类型变量与字符串相互转换

2.2CString及string,char *与其他数据类型的转换和操作

●CString,string,char*的综合比较

●数学类型与CString相互转化

●CString与char*相互转换举例

●CString 与BSTR 型转换

●V ARIANT 型转化成CString 型

2.3 BSTR、_bstr_t与CComBSTR

2.4 V ARIANT 、_variant_t 与COleVariant

附录CString及字符串转及操作详解

参考书籍:CSDN,<>

一.VC常用数据类型列表

说明:

(1)-------表示省略

(2)1Byte=8Bit,

字与机器有关,在8位系统中:字=1字节,16位系统中,1字=2字节,32位中:1字=4字节, 64位中1字=8字节.不要搞混这些概念.

二.常用数据类型转化及操作

2.1 数学类型变量与字符串相互转换(这些函数都在STDLIB.H里)

(1)将数学类型转换为字符串可以用以下一些函数:

举例: _CRTIMP char * __cdecl _itoa(int, char *, int);//这是一个将数字转换为一个字符串类型的函数,最后一个int表示转换的进制

如以下程序:

int iTyep=3;

char *szChar;

itoa(iType,szChar,2);

cout<

类似函数列表:

_CRTIMP char * __cdecl _itoa(int, char *, int);//为了完整性,也列在其中

_CRTIMP char * __cdecl _ultoa(unsigned long, char *, int);

_CRTIMP char * __cdecl _ltoa(long, char *, int);

_CRTIMP char * __cdecl _i64toa(__int64, char *, int);

_CRTIMP char * __cdecl _ui64toa(unsigned __int64, char *, int);

_CRTIMP wchar_t * __cdecl _i64tow(__int64, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _ui64tow(unsigned __int64, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _itow (int, wchar_t *, int);//转换为长字符串类型

_CRTIMP wchar_t * __cdecl _ltow (long, wchar_t *, int);

_CRTIMP wchar_t * __cdecl _ultow (unsigned long, wchar_t *, int);

还有很多,请自行研究

(2)将字符串类型转换为数学类型变量可以用以下一些函数:

举例: _CRTIMP int __cdecl atoi(const char *);//参数一看就很明了

char *szChar=”88”;

int temp(0);

temp=atoi(szChar);

cout<

类似的函数列表:

_CRTIMP int __cdecl atoi(const char *);

_CRTIMP double __cdecl atof(const char *);

_CRTIMP long __cdecl atol(const char *);

_CRTIMP long double __cdecl _atold(const char *);

_CRTIMP __int64 __cdecl _atoi64(const char *);

_CRTIMP double __cdecl strtod(const char *, char **);//

_CRTIMP long __cdecl strtol(const char *, char **, int);//

_CRTIMP long double __cdecl _strtold(const char *, char **);

_CRTIMP unsigned long __cdecl strtoul(const char *, char **, int);

_CRTIMP double __cdecl wcstod(const wchar_t *, wchar_t **);//长字符串类型转换为数学类型_CRTIMP long __cdecl wcstol(const wchar_t *, wchar_t **, int);

_CRTIMP unsigned long __cdecl wcstoul(const wchar_t *, wchar_t **, int);

_CRTIMP int __cdecl _wtoi(const wchar_t *);

_CRTIMP long __cdecl _wtol(const wchar_t *);

_CRTIMP __int64 __cdecl _wtoi64(const wchar_t *);

还有很多,请自行研究

2.2.CString及string,char *与其他数据类型的转换和操作

(1)CString,string,char*的综合比较(这部分CSDN上的作者joise的文章

<< CString,string,char*的综合比较>>写的很详细,请大家在仔细阅读他的文章.

地址: https://www.doczj.com/doc/dc18544894.html,/joise/

或参考附录:

(2)转换:

●数学类型与CString相互转化

数学类型转化为CString

可用Format函数,举例:

CString s;

int i = 64;

s.Format("%d", i)

CString转换为数学类型:举例

CString strValue("1.234");

double dblValue;

dblValue = atof((LPCTSTR)strValue);

●CString与char*相互转换举例

CString strValue(“Hello”);

char *szValue;

szValue=strValue.GetBuffer(szValue);

也可用(LPSTR)(LPCTSTR)对CString// 进行强制转换.

szValue=(LPSTR)(LPCTSTR)strValue;

反过来可直接赋值:

char *szChar=NULL;

CString strValue;

szChar=new char[10];

memset(szChar,0,10);

strcpy(szChar,”Hello”);

strValue=szChar;

●CString 与BSTR 型转换

CString 型转化成BSTR 型

当我们使用ActiveX 控件编程时,经常需要用到将某个值表示成BSTR 类型.BSTR 是一种记数字符串,Intel平台上的宽字符串(Unicode),并且可以包含嵌入的NULL 字符。

可以调用CString 对象的AllocSysString 方法将CString 转化成BSTR:

CString str;

str = .....; // whatever

BSTR bStr = str.AllocSysString();

BSTR型转换为CString

如果你在UNICODE 模式下编译代码,你可以简单地写成:

CString convert(BSTR bStr)

{

if(bStr == NULL)

return CString(_T(""));

CString s(bStr); // in UNICODE mode

return s;

}

如果是ANSI 模式

CString convert(BSTR b)

{

CString s;

if(b == NULL)

return s; // empty for NULL BSTR

#ifdef UNICODE

s = b;

#else

LPSTR p = s.GetBuffer(SysStringLen(b) + 1);

::WideCharToMultiByte(CP_ACP, // ANSI Code Page

0, // no flags

b, // source widechar string

-1, // assume NUL-terminated

p, // target buffer

SysStringLen(b)+1, // target buffer length

NULL, // use system default char

NULL); // don''t care if default used s.ReleaseBuffer();

#endif

return s;

}

●V ARIANT 型转化成CString 型

V ARIANT 类型经常用来给COM 对象传递参数,或者接收从COM 对象返回的值。你也能自己编写返回V ARIANT 类型的方法,函数返回什么类型依赖可能(并且常

常)方法的输入参数(比如,在自动化操作中,依赖与你调用哪个方法。IDispatch::Invoke 可能返回(通过其一个参数)一个包含有BYTE、WORD、float、double、date、BSTR 等等V ARIANT 类型的结果,(详见MSDN 上的V ARIANT 结构的定义)。在下面的例子中,假设类型是一个BSTR的变体,也就是说在串中的值是通过bsrtVal 来引用,其优点是在ANSI 应用中,有一个构造函数会把LPCWCHAR 引用的值转换为一个CString(见BSTR-to-CString 部分)。在Unicode 模式中,将成为标准的CString 构造函数,参见对缺省::WideCharToMultiByte 转换的告诫,以及你觉得是否可以接受(大多数情况下,你会满意的)。V ARIANT vaData;

vaData = m_com.YourMethodHere();

ASSERT(vaData.vt == VT_BSTR);

CString strData(vaData.bstrVal);

你还可以根据vt 域的不同来建立更通用的转换例程。为此你可能会考虑:CString VariantToString(V ARIANT * va)

{

CString s;

switch(va->vt)

{ /* vt */

case VT_BSTR:

return CString(vaData->bstrVal);

case VT_BSTR | VT_BYREF:

return CString(*vaData->pbstrVal);

case VT_I4:

s.Format(_T("%d"), va->lVal);

return s;

case VT_I4 | VT_BYREF:

s.Format(_T("%d"), *va->plVal);

case VT_R8:

s.Format(_T("%f"), va->dblVal);

return s;

... 剩下的类型转换由读者自己完成

default:

ASSERT(FALSE); // unknown V ARIANT type (this ASSERT is optional)

return CString("");

} /* vt */

}

2.3 BSTR、_bstr_t与CComBSTR

CComBSTR、_bstr_t是对BSTR的封装,BSTR是指向字符串的32位指针。

char *转换到BSTR可以这样:

BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上头文件comutil.h 反之可以使用char *p=_com_util::ConvertBSTRToString(b);

2.4(引)V ARIANT 、_variant_t 与COleVariant

V ARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagV ARIANT 的定义。

对于V ARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:

V ARIANT va;

int a=2001;

va.vt=VT_I4;///指明整型数据

va.lVal=a; ///赋值

对于不马上赋值的V ARIANT,最好先用V oid VariantInit(V ARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系: unsigned char bVal; VT_UI1

short iVal; VT_I2

long lVal; VT_I4

float fltVal; VT_R4

double dblVal; VT_R8

V ARIANT_BOOL boolVal; VT_BOOL

SCODE scode; VT_ERROR

CY cyVal; VT_CY

DATE date; VT_DA TE

BSTR bstrVal; VT_BSTR

IUnknown FAR* punkVal; VT_UNKNOWN

IDispatch FAR* pdispVal; VT_DISPATCH

SAFEARRAY FAR* parray; VT_ARRAY|*

unsigned char FAR* pbVal; VT_BYREF|VT_UI1

short FAR* piVal; VT_BYREF|VT_I2

long FAR* plVal; VT_BYREF|VT_I4

float FAR* pfltVal; VT_BYREF|VT_R4

double FAR* pdblVal; VT_BYREF|VT_R8

V ARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL

SCODE FAR* pscode; VT_BYREF|VT_ERROR

CY FAR* pcyVal; VT_BYREF|VT_CY

DATE FAR* pdate; VT_BYREF|VT_DATE

BSTR FAR* pbstrVal; VT_BYREF|VT_BSTR

IUnknown FAR* FAR* ppunkVal; VT_BYREF|VT_UNKNOWN

IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH

SAFEARRAY FAR* FAR* pparray; VT_ARRAY|*

V ARIANT FAR* pvarVal; VT_BYREF|VT_V ARIANT

void FAR* byref; VT_BYREF

_variant_t是V ARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。

例如:

long l=222;

ing i=100;

_variant_t lVal(l);

lVal = (long)i;

COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:

COleVariant v3 = "字符串", v4 = (long)1999;

CString str =(BSTR)v3.pbstrVal;

long i = v4.lVal;

附录

CString,string,char*的综合比较

(一)概述

string和CString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中;

CString(typedef CStringT> CString)为Visual C++中最常用的字符串类,继承自CSimpleStringT类,主要应用在MFC和ATL编程中,主要数据类型有char(应用于ANSI),wchar_t(unicode),TCHAR(ANSI与unicode均可);

char*为C编程中最常用的字符串指针,一般以’\0’为结束标志;

(二)构造

?string是方便的,可以从几乎所有的字符串构造而来,包括CString和char*;

?CString次之,可以从基本的一些字符串变量构造而来,包括char*等;

?char*没有构造函数,仅可以赋值;

?举例:

char* psz = “joise”;

CString cstr( psz );

string str( cstr );

(三)运算符重载

a)operator=

?string是最方便的,几乎可以直接用所有的字符串赋值,包括CString和char*;

?CString次之,可以直接用些基本的字符串赋值,包括char*等;

?char*只能由指针赋值,并且是极危险的操作,建议使用strcpy或者memcpy,而且char*在声

明的时候如未赋初值建议先设为NULL,以避免野指针,令你抓狂;

?举例:

char *psz = NULL;

psz = new char[10]; //当然,以上的直接写成char *psz = new char[10];也是一样

memset( psz, 0, 10 );

strcpy( psz, “joise” );

CString cstr;

cstr = psz;

string str;

str = psz;

str = cstr;

delete []psz;

b)operator+

?string与CString差不多,可以直接与char*进行加法,但不可以相互使用+运算符,即string

str = str + cstr是非法的,须转换成char*;

?char*没有+运算,只能使用strcat把两个指针连在一起;

?举例:

char* psz = “joise”;

CString cstr = psz;

cstr = cstr + psz;

string str = psz;

str = str + str + psz;

strcat( psz, psz );

strcat( psz, cstr );//合法

strcat( psz, str );//非法,由此可见,CString可自动转换为const char*,而string不行

c)operator +=

?string是最强大的,几乎可以与所有的字符串变量+=,包括CString和char*;

?CString次之,可以与基本的一些字符串变量进行+=而来,包括char*等;

?char*没有+=运算符,只能使用strcat把两个指针连在一起;

d)operator[]

?CString最好,当越界时会抛出断言异常;

?string与char*下标越界结果未定义;

?举例:

char* psz = “joise”;

CString cstr = psz;

cout << cstr[8];

string str = psz;

cout << str[8];

cout << psz[8];

e)operator== 、operator!=、operator> 、operator< 、operator>= 、perator<=

?CString与string之间不可以进行比较,但均可以与char*进行比较,并且比较的是值,而不

是地址;

cout << ( psz == cstr );

cout << ( psz == str );

cout << ( str == psz );

cout << ( cstr == psz );//以上代码返回均为1

(四) 常用算法

a) 查找

注:find_if 中是把范围内的值挨个代入匹配函数直至返回true

b) 比较

注:返回值如果<0则前面的值小于后面的值,反之亦然 c) 替换

d)

插入 e) 增加

f)截取

g)移除

h)转换大小写

i)与其他类型转换

j)格式化

k)得到长度

l)判断为空

m)重定义大小

n)释放资源

(五)安全性

CString > string > char*;

(六)灵活性

CString > string >char*;

(七)可移植性

char* = string > CString

(八)MFC中常用字符串结构图(此非比较,但为了方便查阅就一并算在这儿了)

(九)总结

综上所述,我个人认为,在MFC、ATL中使用字符串尽量使用CString,毕竟都是微软的孩子,各方面都比其它更有优势,而在非微软平台上或对移植性要求较高的场合推荐使用string,标准模板库提供了那么强大的泛型算法,没必要再自己去造车轮。

(十)参考文献

主要参考的是MSDN,就不一一列出了。

相关主题
文本预览
相关文档 最新文档