谁能解释一下这段程序是什么意思,结果是什么?

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-31
谁能帮忙解释一下这段C程序是什么意思?求高手!!!

这个程序对输入的字节数组内容格式做了规定,按照这个格式规定在内部计算校验值并做出判断。
-------------------------------------------------
字节个数 | 字节1 | 字节2 | ...... | 校验和
--------------------------------------------------

程序按照如下运行:
a,取的要校验的字节个 数 n;
b, 然后计算校验和,计算公式为: chksum = n ^ 字节1 ^ 字节2 ^ 字节3 ^ 字节4 ^ ......
c, 将计算得到的校验和 chksum 与 字节数组中的保存的校验和进行比较,如果相当,则返回1;否则,将计算得到的 chksum 存入字节数组,并返回0 的结果。

C语言是挺有意思的一个东西,您若碰到其他问题,可以到 JulianTec 的邮件列表中像师兄师姐们求助。

小弟只有10年VC++经验,帮你解读一下哦: 满意的话麻烦给我分.

如下代码是为了实现: 接收串口过来的数据! 首先初始化一个泛型类型接受容器, 接收串口接口发来的数据,然后显示在界面上的edit控件上!

VARIANT variant_inp; 用VARIANT 泛型变量类型 定义一个数组变量variant_inp; 泛型就是任何类型都可以放进去的意思. 作为缓冲池使用很适合.

COleSafeArray safearray_inp; 用COleSafeArray用OLE安全数据容器类 定义一个对象名字是 safearray inp 因为VARIANT虽然可以放任何类型数据到这个数组中,但该类型没有丰富的处理成员函数,说白了他是结构体不是类, 所以 需要做个转换, 转为COleSafeArray类型的数组类即可. 他具有非常丰富的成员函数.

那么, 你会问为什么不直接让safearray_inp=m_ctrlComm.GetInput(); 读缓冲区,而要经过一个中间变量呢?
variant_inp=m_ctrlComm.GetInput(); 读缓冲区
safearray_inp=variant_inp; VARIANT转换成COleSafeArray型变量

VARIANT和COleSafeArray 是什么关系呢?

原因是:

这中间有调用不同的重载=运算符,m_ctrlComm.GetInput(); 的数据可以转化为variant_inp,有默认的转化方式,而safearray_inp=variant_inp则是另一个转化方式,如果直接转,可能数据不对。
VARIANT和COleSafeArray 一个是结构体,一个是类,各自的数据构造不一样。



long k=0; 初始化一个长整型变量 k=0;
int len; 定义长度len,整数型.

BYTE rxdata[2048]; 定义接受数据的数组,2k大小,2048字节. 为BYTE类型,也即unsigned char类型.
CString strtemp; 定义一个CString类型的字符串strtemp;
if(m_ctrlComm.GetCommEvent()) 如果控制通信对象m_ctlComm有get的事件发生,
{

------------------------
这里应该加switch(ret) , 将上面getcommevent赋值给ret.

case 2: 事件值为2表示接收缓冲区内有字符
{
variant_inp=m_ctrlComm.GetInput(); 控制通信器对象得到输入数据流. 如果GetCommEvent返回2,说明有字符到达了, 接收缓冲区内有字符
safearray_inp=variant_inp; 将variant inp转换为COleSafeArray 类型,付给safearry inp. 因为COleSafeArray提供了丰富的函数处理.符合我们的需要.

len=safearray_inp.GetOneDimSize(); 获取输入安全数组的长度len
for(k=0;k<len;k++) 做个循环,
{
safearray_inp.GetElement(&k,rxdata+k); 从输入的安全数组到rxdata进行数据拷贝. 一次一个字节拷贝.
}
for(k=0;k<len;k++) 做个循环. 读取len长度的所有字节.
{
BYTE bt=*(char*)(rxdata+k); 内存 rxdata 起始地址+k字节偏移的指针 取值,得到 一个字节.
strtemp.Format("%c",bt); strtemp赋值为bt,也就是一个字符.
m_strEditRXData+=strtemp; m_strEdit这个CEdit控件显示一直加长.
}
}
UpdateData(FALSE); 将内存变量数据更新到界面.


====================
参考:



VARIANT




  

C++、BASIC、Java、Pascal、Script......计算机语言多种多样,而它们各自又都有自己的数据类型,COM
产生目的,其中之一就是要跨语言(注3)。而 VARIANT
数据类型就具有跨语言的特性,同时它可以表示(存储)任意类型的数据。从C语言的角度来讲,VARIANT
其实是一个结构,结构中用一个域(vt)表示------该变量到底表示的是什么类型数据,同时真正的数据则存贮在 union
空间中。结构的定义太长了(虽然长,但其实很简单)大家去看 MSDN 的描述吧,这里给出如何使用的简单示例:

学生:我想用 VARIANT 表示一个4字节长的整数,如何做?
老师:VARIANT v; v.vt=VT_I4; v.lVal=100;

学生:我想用 VARIANT 表示布尔值“真”,如何做?
老师:VARIANT v; v.vt=VT_BOOL; v.boolVal=VARIANT_TRUE;
学生:这么麻烦?我能不能 v.boolVal=true; 这样写?
老师:不可以!因为
 

类型
字节长度
假值
真值

bool
1(char)
0(false)
1(true)

BOOL
4(int)
0(FALSE)
1(TRUE)

VT_BOOL
2(short int)
0(VARIANT_FALSE)
-1(VARIANT_TRUE)

  所以如果你 v.boolVal=true 这样赋值,那么将来 if(VARIANT_TRUE==v.boolVal)
的时候会出问题(-1 !=
1)。但是你注意观察,任何布尔类型的“假”都是0,因此作为一个好习惯,在做布尔判断的时候,不要和“真值”相比较,而要与“假值”做比较。
学生:谢谢老师,你太牛了。我对老师的敬仰如滔滔江水,连绵不绝......

学生:我想用 VARIANT 保存字符串,如何做?
老师:VARIANT v; v.vt=VT_BSTR; v.bstrVal=SysAllocString(L"Hello,你好");

学生:哦......我明白了。可是这么操作真够麻烦的,有没有简单一些的方法?
老师:有呀,你可以使用现成的包装类 CComVariant、COleVariant、_variant_t。比如上面三个问题就可以这样书写:CComVariant v1(100),v2(true),v3("Hello,你好"); 简单了吧?!(注4)

学生:老师,我再问最后一个问题,我如何用 VARIANT 保存一个数组?
老师:这个问题很复杂,我现在不能告诉你,我现在告诉你怕你印象不深......(注5)
学生:~!@#$%^&*()......晕!




VARIANT 数据类型在文件OAIDL.IDL中定义如下:

struct tagVARIANT {
  union {

  struct __tagVARIANT {

  VARTYPE vt;

  WORD wReserved1;

  WORD wReserved2;

  WORD wReserved3;

  union {

  ULONGLONG ullVal;

  LONGLONG llVal;

  LONG lVal;

  BYTE bVal;

  SHORT iVal;

  FLOAT fltVal;

  DOUBLE dblVal;

  VARIANT_BOOL boolVal;

  _VARIANT_BOOL bool;

  SCODE scode;

  CY cyVal;

  DATE date;

  BSTR bstrVal;

  IUnknown * punkVal;

  IDispatch * pdispVal;

  SAFEARRAY * parray;

  BYTE * pbVal;

  SHORT * piVal;

  LONG * plVal;

  LONGLONG * pllVal;

  FLOAT * pfltVal;

  DOUBLE * pdblVal;

  VARIANT_BOOL *pboolVal;

  _VARIANT_BOOL *pbool;

  SCODE * pscode;

  CY * pcyVal;

  DATE * pdate;

  BSTR * pbstrVal;

  IUnknown ** ppunkVal;

  IDispatch ** ppdispVal;

  SAFEARRAY ** pparray;

  VARIANT * pvarVal;

  PVOID byref;

  CHAR cVal;

  USHORT uiVal;

  ULONG ulVal;

  INT intVal;

  UINT uintVal;

  DECIMAL * pdecVal;

  CHAR * pcVal;

  USHORT * puiVal;

  ULONG * pulVal;

  ULONGLONG * pullVal;

  INT * pintVal;

  UINT * puintVal;

  struct __tagBRECORD {

  PVOID pvRecord;

  IRecordInfo * pRecInfo;

  } __VARIANT_NAME_4;

  } __VARIANT_NAME_3;

  } __VARIANT_NAME_2;

  DECIMAL decVal;

  } __VARIANT_NAME_1;
  };

//定义一个数组p,初始化i,j为0
int p[8]={11,12,13,14,15,16,17,18},i=0,j=0;
//循环,i=0 到6 共循环7次
while(i++<7)
//如果p[i] 也就是数组p的第i个数能被2整除,j=j+p[i];
if(p[i]%2) j+=p[i];
//循环结束,打印j
printf("%d\n",j);

这段程序用来选择此长度为8的数组的前七个元素中的偶数,并把这些偶数相加的和打印出来。

数组。
定义8个数,11,12,13,14,15,16,17,18
然后循环,6次,<7嘛,当然不能到7的。
如果数组中的数可以被二整除,那么就把得到的数负值给j,然后依次把j得到得数显示出来。

main()
{
//定义一个数组p,初始化i,j为0
int p[8]={11,12,13,14,15,16,17,18},i=0,j=0;
//循环,i=0 到6 共循环7次
while(i++<7)
//如果p[i] 也就是数组p的第i个数能被2整除,j=j+p[i];
if(p[i]%2) j+=p[i];
//循环结束,打印j
printf("%d\n",j);
}

因此,结果应该是所有偶数的和12+14+16+18 = 60

是i++ 不是++i循环7次只到第7个数
结果是:
42

  • ...人帮忙看一下这一段程序是什么意思啊 解释一下逻辑吧
    答:这个消息响应大致就是把收到的消息结构体中的参数传到函数中定义的一个消息结构体中。Scoll就是一般窗口中的滚动条,这个应该是滚动条操作响应消息。系统收到这个消息后,调用的DefWinDowProc()函数是关于窗口绘制的函数,也就是说收到滚动条操作,刷新窗口以显示其他信息。也就实现了内容的上下,左右调节...
  • 关于坐标的问题,谁能帮我解释一下这段程序的意思。
    答:这是求解(x,y)、坐标原点的连线与X轴夹角的程序 如果xoffset==0,点在X轴上,此时如果Y大于0,夹角=0;小于0,夹角180 同理yoffset==0,点在y轴上,此时如果X大于0,夹角=90;小于0,夹角270 如果xoffset、yoffse均不为0. 式 ”atan(xoffset/yoffset)*180/3.141593“是求解夹角,转换成...
  • 能高手解释下这段程序的意思
    答:很简单。/ 参数:data是输入数据流 databytes是输入数据流的长度(字节)current是当前读取的位置,读完还要更新它 / uint32_t Blowfish_stream2word(const uint8_t *data, uint16_t databytes, uint16_t *current){ uint8_t i;uint16_t j;uint32_t temp;temp = 0x00000000; /* 返回一个32...
  • 谁能帮我具体解释一下这段程序。这段程序是为了实现将二进制数转换成...
    答:1/2=0 ---1 除到零为止.书上有说:除到零.最后一位剩1 这样加起来就是1994了.参考资料:谭浩强(师范院校教科书)二进制转换十进制 例如:110110101 转为10进制的方法是1+0*2+1*4+0*8+1*16+1*32+0*64+1*128+1*256 就是依次往上递增2的次方 ...
  • 谁能解释一下这段C程序(新手求教)
    答:指针y指向空间也不断的依一个字符所占的空间大小在移动,空间的内容肯定也不停的在变化,当指针y指向空间没有内容时,退出while循环。4。return y-x-1,返回y-x-1,即为循环中所经过的空间的个数。因为字符型数据在存储时占一个内存空间。这个子函数能计算一下未知字符数组的大小 ...
  • 谁能帮我解释一下这段程序?最好是逐条的。
    答:详细解释:ORG 0030H; 定位程序在ROM中的开始存储地址为30H MOV R1, #30H; R1=30H MOV R2, #8H; R2=8 MOV TL0, #0H; 定时器0的低8位为0 MOV TH0, #0B8H;
  • 谁能帮我解读一下这段程序!
    答:超出了递归调用的次数。您可以试着增加允许的递归次数,例如: set(0,'RecursionLimit',1000) 看能否运行。导致这个问题的可能原因: 1、由于软件版本差异导致递归的出口条件得不到满足; 2、程序中有随机性因素,不同次的运行结果可能不同。具体要看代码才能判断。
  • 谁给解释一下这个程序。 char x:2是什么意思(急)
    答:这是位段的使用方法,说明x变量占2位,y变量占3位,z变量占3位,一共占一个字节,将100付给它,x=0,y=1,z=3
  • 谁帮忙解释下这个程序的详细意思
    答:public void m() {//这里定义一个公有的没有返回值的方法m()int i = 0;//这里定义一个整形变量i,并初始化其值为0 System.out.println(i);//这里是把i的值向控制台输出 } public static class void main(string[] args) {//这里是程序的main方法,是主要的方法,程序入口就在这里。(...
  • 谁能帮我解释一下这段程序啊:
    答://打印所求的结果,其中“1! + 2! + ... + 50! =”都是为了输出好看,可以不打, %g是代替后面出现的sum,\n是换行 return 0; //代表程序已正常执行 这样实际求得的和是:sum=1.0*1+(1.0*1)*2+…+(1.0*1*2*…*48)*49+(1.0*1*2*…*49)*50,也就是sum=1!+2!+…+...