社区
VB基础类
帖子详情
Dim i As Long i = 3600 * 10 居然溢出??!!
zhangweiqiang
2003-12-24 02:06:39
Dim i As Long
i = 3600 * 10
上述代码运行时居然溢出,而若直接改成
Dim i As Long
i = 36000
再运行便没有事,这真是一件怪事,有谁知道是什么原因吗?(环境VB6+SP5)如果你机器没事,请告诉我你的环境
...全文
353
11
打赏
收藏
Dim i As Long i = 3600 * 10 居然溢出??!!
Dim i As Long i = 3600 * 10 上述代码运行时居然溢出,而若直接改成 Dim i As Long i = 36000 再运行便没有事,这真是一件怪事,有谁知道是什么原因吗?(环境VB6+SP5)如果你机器没事,请告诉我你的环境
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
thriller
2003-12-24
打赏
举报
回复
msdn:
You attempt to use a number in a calculation, and that number is coerced into an integer, but the result is larger than an integer. For example:
Dim x As Long
x = 2000 * 365 ' Error: Overflow
hspring
2003-12-24
打赏
举报
回复
两个整型的相乘当然还是整型的,你把它付给长整型的当然溢出了
这样可以
i=clng(3600)*clng(10)
ahbbnimor
2003-12-24
打赏
举报
回复
up
高高兴兴的晶晶
2003-12-24
打赏
举报
回复
学学
flyingZFX
2003-12-24
打赏
举报
回复
To Greaitm(夜草) ::
你从哪本VB书上看到的,,介绍给我呀,?
Greaitm
2003-12-24
打赏
举报
回复
用& 而不要用CLng
因为你的参数中用了&,vb编译器就会使用长整的寄存器(vb会根据代码查找最长的变量,并设置寄存器),但如果你用Clng的话,就变成初始化时是整数,然后再转换成长整,这样不科学。
蜗牛20008
2003-12-24
打赏
举报
回复
Dim i As Long
i = 3600& * 10&
--------------------
&means long
tonyLonge
2003-12-24
打赏
举报
回复
很同意楼上的liuyanghe111(yang) 说法
将
Dim i As Long
i = 3600 * 10
改成
Dim i As Long
i = CLng(3600) * CLng(10) 就对了.
Greaitm
2003-12-24
打赏
举报
回复
i = 3600& * 10
就可以了
liuyanghe111
2003-12-24
打赏
举报
回复
因为在表达式中,3600和10都是默认为int型的,系统会将3600*10的结果填充到int型的内存空间中,而36000>32767,所以溢出
IT服务
2003-12-24
打赏
举报
回复
VB里不能在定意的时候给它付值啊.这样写不对吧.
标准MFC WinSock ActiveX控件开发实例(II)高级篇
主要利用VARIANT类型作参数进行的网络数据传送和接收,以及SAFEARRAY,BSTR的详细使用方法。 另外还提供该控件在VC,VB下的调用方式以及相关数据的处理。 关键字:ActiveX,Socket,VARIANT, SAFEARRAY,BSTR。 回顾:在上一篇文章《标准MFC WinSock ActiveX控件开发实例》中我们详细介绍了控件的开发过程,以及接口和事件的 添加和响应方法。现在我们将继续上次没有写完的控件继续进行开发,并完善作为一个WinSock控件应该具备的功能。 二、按照前一篇文章提到的知识,现在我们来添加两个新的接口分别是SendData()和GetData(),它们看起来如下: //网络数据发送,在指定的超时时间内进行发送然后返回,成功返回实际发送字节数,否则返回负数
long
CMFCWinSockCtrl::SendData(const VARIANT FAR& Data, const VARIANT FAR& DataType, const VARIANT FAR& DataLength, const VARIANT FAR& TimeOut) { // TODO: Add your dispatch handler code here return 0; } //获取数据,并指定获取数据的超时时间,返回实际获取到的数据长度,否则返回负数
long
CMFCWinSockCtrl::GetData(VARIANT FAR* Data, const VARIANT FAR& DataType, const VARIANT FAR& DataMaxLength, const VARIANT FAR& TimeOut) { // TODO: Add your dispatch handler code here return 0; } 两个接口的参数除了第一个参数外,其它都类似。SendData()是发送数据,不要求将数据带回,因此直接用 VARIANT,而GetData()则要求将数据带回来给调用者,因此定义为 VARIANT *类型,第二个参数DataType故名思义是定义所传送或接收数据的类型,第三个参数是传送或接收数据的长度,这里的长度以char作为一个长度,假如传入的类型是int类型,则长度为4,如果定义的是字符串,一个中文字符占用2个长度。最后一个参数,是网络发送或读取时的超时时间。 三、为Connect()接口添加源代码,看起来如下: //网络数据发送,在指定的超时时间内进行发送然后返回,成功返回实际发送字节数,否则返回负数
long
CMFCWinSockCtrl::SendData(const VARIANT FAR& Data, const VARIANT FAR& DataType, const VARIANT FAR& DataLength, const VARIANT FAR& TimeOut) { // TODO: Add your dispatch handler code here if(!OnlySock) return -1;//网络尚未开始建立连接 int gDataType = VariantTo
Long
(DataType);
long
gDataLength = VariantTo
Long
(DataLength); int gTimeOut = VariantTo
Long
(TimeOut); if(gDataType < 0) return -2; if(gDataLength <= 0) return -2; if(gTimeOut < 0) return -2; switch(gDataType) { case 0://默认形式,这时如果发现Data为整型数组,将不进行任何转换,直接把一个int传给一个char传送(数据可能
溢出
范围) case 1://当指定该值为1时,当Date为长整型数组时,将把一个
long
转换成四个char传送 case 2://当指定该值为2时,当Date为整型数组时,将把一个int转换成四个char传送 case 3://当指定该值为3时,当Date为无符号短整型数组时,将把一个unsigned short转换成两个char传送 case 4://当指定该值为4时,当Date为BYTE数组时,将把一个BYTE转换成一个char传送 case 5://当指定该值为5时,当Date为短整型数组时,将把一个short转换成两个char传送 case 6://当指定该值为6时,当Date为浮点型数组时,将把一个float转换成四个char传送 case 7://当指定该值为7时,当Date为双精度数组时,将把一个double转换成八个char传送 break; default://如果不在上面取值范围内,将按当前的Data相应类型进行传送 break; } timeval tv; fd_set fdwrite; int len = 0;
long
m = 0;
long
n = 0;
long
changetype = 0;//将浮点型数据进行类型转换,再进行传送 VARIANT gData; VariantInit(&gData); //送出信息至服务器 FD_ZERO(&fdwrite); tv.tv_sec = gTimeOut;//指定时间后返回 tv.tv_usec = 0; FD_SET(OnlySock,&fdwrite);//是否可以发送数据 select(0,NULL,&fdwrite,NULL,&tv); char *buffer = NULL; if(FD_ISSET(OnlySock,&fdwrite)) { switch(Data.vt) { case VT_BSTR://按字符串形式发送 buffer = _com_util::ConvertBSTRToString(Data.bstrVal); break; case VT_BYREF|VT_UI1: //按BYTE*形式发送 buffer = new char[gDataLength]; memcpy(buffer,Data.pbVal,gDataLength); break; case VT_BYREF|VT_I1://按 char * 发送 buffer = new char[gDataLength]; memcpy(buffer,Data.pcVal,gDataLength); break; case VT_ARRAY|VT_I4://以长整型数组发送 gData.vt = VT_I4; if(gDataType!=0)//
long
= char*4 { //sizeof(
long
),在这里一个长整型的长度为4个char buffer = new char[gDataLength]; for(m=0,n=0; n>24)&0xff; buffer[m++] = (gData.lVal>>16)&0xff; buffer[m++] = (gData.lVal>>8)&0xff; buffer[m++] = gData.lVal&0xff; } } else//
long
= char*1 //数据可能
溢出
{ buffer = new char[gDataLength]; for(m=0,n=0; n
24)&0xff; buffer[m++] = (gData.intVal>>16)&0xff; buffer[m++] = (gData.intVal>>8)&0xff; buffer[m++] = gData.intVal&0xff; } } else { buffer = new char[gDataLength]; for(n=0; n
24)&0xff; buffer[1] = (lData>>16)&0xff; buffer[2] = (lData>>8)&0xff; buffer[3] = lData&0xff; //4个char组成一个
long
lData_2 = ((buffer[0]&0xff)<<24) + ((buffer[1]&0xff)<<16) + ((buffer[2]&0xff)<<8) + (buffer[3]&0xff); 四、现在来看看GetData()的处理,具体实现,请看如下代码: // TODO: Add your dispatch handler code here if(!OnlySock) return -1;//网络尚未开始建立连接 int gDataType = VariantTo
Long
(DataType);
long
gDataMaxLength = VariantTo
Long
(DataMaxLength); int gTimeOut = VariantTo
Long
(TimeOut); if(gDataType < 0) return -2; if(gDataMaxLength <= 0) return -2; if(gTimeOut < 0) return -2; switch(gDataType) { case 0://默认形式,这时如果发现Data为整型数组,将不进行任何转换,直接把一个int传给一个char传送(数据可能
溢出
范围) case 1://当指定该值为1时,当Date为长整型数组时,将把一个
long
转换成四个char传送 case 2://当指定该值为2时,当Date为整型数组时,将把一个int转换成四个char传送 case 3://当指定该值为3时,当Date为无符号短整型数组时,将把一个unsigned short转换成两个char传送 case 4://当指定该值为4时,当Date为BYTE数组时,将把一个BYTE转换成一个char传送 case 5://当指定该值为5时,当Date为短整型数组时,将把一个short转换成两个char传送 case 6://当指定该值为6时,当Date为浮点型数组时,将把一个float转换成四个char传送 case 7://当指定该值为7时,当Date为双精度数组时,将把一个double转换成八个char传送 break; default://如果不在上面取值范围内,将按当前的Data相应类型进行传送 break; } timeval tv; fd_set fdread; int len = -3;//如果找不到该连接,则返回-3
long
n = 0;
long
m = 0;
long
changetype = 0; VARIANT gData; VariantInit(&gData); char *buffer=NULL; buffer = new char[gDataMaxLength+1]; memset(buffer, 0, gDataMaxLength+1); FD_ZERO(&fdread); tv.tv_sec = gTimeOut;//超过指定时间后返回 tv.tv_usec = 0; FD_SET(OnlySock,&fdread);//是否可以读取数据 select( 0,&fdread,NULL,NULL,&tv); if(FD_ISSET(OnlySock,&fdread)) { len = recv(OnlySock, buffer, gDataMaxLength, 0); if (len<=0) { delete[] buffer; return -
10
2;//无法读取数据,对方可能已断开连接 } if(lenvt) { case VT_BSTR://按字符串形式接收 buffer[gDataMaxLength] = '\0'; Data->bstrVal = _com_util::ConvertStringToBSTR(buffer); break; case VT_BYREF|VT_UI1: //按BYTE*形式接收 memcpy(Data->pbVal,buffer,gDataMaxLength); break; case VT_BYREF|VT_I1://按 char * 形式接收 memcpy(Data->pcVal,buffer,gDataMaxLength); break; case VT_BYREF|VT_I4://以长整型指针接收 buffer[gDataMaxLength]='\0'; for(n=0; nplVal[n] = buffer[n]; } break; case VT_ARRAY|VT_I4://以长整型数组接收 gData.vt = VT_I4; if(gDataType != 0) { for(m=0,n=0; n
100;//该一维数组最大接收
10
0个元素 VARIANT *data; data = new VARIANT; VariantInit(data); data->vt = VT_ARRAY|VT_I4;//指明为长整型数组 data->parray = SafeArrayCreate(VT_I4,1,Bound);//创建SAFEARRAY结构
long
l = m_sock.GetData(data, COleVariant((
long
)0), COleVariant((
long
)
10
0), COleVariant((
long
)3)); if(l<=0) { ;//在这里判断出错信息,并作相应处理,我就偷懒了. } char pData[
10
0]={0};//这里以字符数组显示结果
long
change = 0; for(
long
n=0; nparray,&n,&change); pData[n] = (char)change; } CString mess; mess.Format("%s",pData); AfxMessageBox(mess); SafeArrayDestroy(data->parray); delete data; } void CTestMFCWinSockDlg::OnCloseWinsockMfcwinsockctrl1() { // TODO: Add your control notification handler code here m_sock.DisConnect();//调用断开连接接口 AfxMessageBox("服务器断开了该次连接,请检查!"); } void CTestMFCWinSockDlg::OnConnect() { // TODO: Add your control notification handler code here UpdateData(TRUE); if(!m_sock.Connect(COleVariant(m_ip),COleVariant(m_port))) AfxMessageBox("与服务器建立连接失败,请确认服务器是否存在!"); } VB调用控件方式: VB时面调用要方便很多,这得益于VB的很多自动化功能,请看下图: 图三 VB调用控件方法 同样,双击我们的控件,然后添加控件事件,如下图: 图四 VB响应控件事件 然后,添加相关代码如下: Private Sub Command1_Click() MFCWinSock1.Connect CStr(ip), CLng(port) End Sub Private Sub Command2_Click() MFCWinSock1.SendData "SendData: 欢迎使用!", 0, 50, 3 End Sub Private Sub MFCWinSock1_CloseWinsock() MFCWinSock1.DisConnect MsgBox "服务器断开了连接,请检查!" End Sub Private Sub MFCWinSock1_RecvSockEvent()
Dim
data As Variant
Dim
data2(
10
0) As
Long
Dim
data3 As String
Dim
l As
Long
data = data2 '在VB里当把一个Variant变量data等于另一个确定变量data2时,data将被初始化为与data2相同的类型变量 'data = data3 '如果让data等于data3,那么data将变成字符串型的变量参数 l = MFCWinSock1.GetData(data, 0,
10
0, 3) '这时data里面已存放了接收到的数据 data3 = data(0) '这里只显示接收到的首字符编码 MsgBox data3 End Sub 大家可以看到,对于SAFEARRAY类型的数据进行相关处理也并不可怕,由于在源码里给出了具体代码和详细注解,在这里我就不再赘述了, 至于BSTR和char *类型的数据,相信不用我多说,大家也已经知道如何使用了。 结束语: 全文至此暂告一段落,本文向大家展示了MFC ActiveX控件的魅力,以及所用的VARIANT类型参数,还详细给出了WinSock的开发代码, 以用在VC,VB的调用方法,由于这段时间忙于一些新项目的开发,因此没办法花太多时间进行详细解释,所以很多地方都直接给出源代码 再加上注解,而没有进行通俗的讲解,还请各位读者仔细查看源代码。 本控件目前只能作为客户端,阁下还可以继续进行完善,比如进行端口的监听,实现服务器的相关处理等等,但这已经不是本文的目的, 授人以鱼,不如授人如渔,剩下的功能,就由各位读者去实现了,也欢迎与我进行交流,谢谢! 另外:本文的示例,需要一个服务器程序,大家可以在网上随便下载一下进行测试,我就不提供了。 声明: 部分资料来源于网络,本文所用的所有源代码仅供非商业用途,并请保留原版权,否则后果自负! 欢迎大家拍砖,指正错误或不足的地方,一起探导更好的方法。 欢迎访问www.59186618.com,感谢您的支持!
VB中容易出现的
溢出
错误
假设定义
Dim
i as
long
Dim
n as
long
i=n*
10
00我发现即使i和n定义为长整型,如果n*
10
00的乘积超过整型的范围,是长整型,虽然i是长整型变量,程序同样会报错,解决的方法有两种。1.把i=n*
10
00改成i=n*Clng(
10
00)2.定义一个新的长整型变量
Dim
j as
long
j=
10
00i=n*j
关键点检测实战:人体关键点检测
从零开始,讲解 数据标注、数据集制作、模型训练、模型测试、模型优化、环境搭建等方面内容,让学习者能够快速学到AI图像领域关键点技术,应用到实际的工作中去。
vb调用c语言程序,用VB编写程序,求S=A!+B!+C!,阶乘的计算分别用Sub过程和Function过程两种方法来实现...
sub实现:Private Sub Command1_Click()
Dim
a As
Long
, b As
Long
, c As
Long
a = Val(InputBox("请输入一个大于0的整数A:"))b = Val(InputBox("请输入一个大于0的整数B:"))c = Val(InputBox("请输入一个大于0的整数C:"))If a > 0 And b > 0 And ...
VBA学习笔记
一、 vba两个integer变量相乘可能会出现
溢出
,无论储存结果的变量数据类型是多大 例如:
Dim
a As
Long
a = 30000 * 2 (这里会发生
溢出
错误) 处理办法是在30000后面加&符号,将其声明为
long
类型 a = 30000**&** * 2 ...
VB基础类
7,763
社区成员
197,609
社区内容
发帖
与我相关
我的任务
VB基础类
VB 基础类
复制链接
扫一扫
分享
社区描述
VB 基础类
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章