谁能给我解释一下这段程序

kuaidi.ping-jia.net  作者:佚名   更新日期:2024-07-31
谁可以解释一下这段程序的意思

小弟只有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;
  };

确实,多看看基础内容吧。
Employee不是什么类型,这个应该用户自己创建的一个类
employee1.FirstName=""jife; 语法错误,应该是:employee1.FirstName="jife";
至于为什么加点,这个没得解释,就是对象的属性,或对象的方法 时用点。
基础太差

意思就是在字符串的后面加上一个'\0'啊,表示这个字符串结束了,因为strlen,strcpy等函数是以'\0'来判断字符串的结束的,如果不加,调用这些函数的时候就可能会出错。

请你仔细看看,当strchr找到第一个'.'号的时候,我们写了一句*p=0,就是把那个'.'号变成了'\0',然后我们用了strcpy(tp[i], q),这是,我们复制到tp[i]里的是刚才找到的那个'.'号之前的部分,为什么strcpy会知道只复制到这里呢?因为我们用'\0'替换了原来的'.'号,当strcpy复制到'\0'的时候,它就以为这个字符串结束了(实际上没有结束)。

后面我们用了q=++p,让q指向了第一个'.'号后的那个字符,也就是把前面已经复制好了的那部分给去掉了。

希望你仔细分析代码。

楼主态度很成问题!!!

原型:extern char *strchr(char *s,char c);
用法:#include <string.h>
功能:查找字符串s中首次出现字符c的位置

strchr()只是定位,并不会截取任何内容。
--------------------------------------------------------------------------

加*p=0;的目的就是为了下面这句
strcpy( tp[i] , q ); /* 楼主再回忆一下字符串,什么是字符串? */
__________________________________________________________________
第一次,
q := "192.168.1.1\0";
p=strchr(q, '.');*p=0;
这时
q := "192\0""168.1.1\0"
strcpy( tp[i] , q ); 这时就只复制"192",因为192后面有\0(字符串结束符)
q = ++p;
q := "168.1.1"
...
______________________________________________________________
将'.'替换为'\0',复制的时候才只复制'.'之前的部分
如果不替换,就会完全复制,结果楼主自己也知道

加上*p=0;结果是 192 168 1
不加*p=0;结果是 192.168.1.1 168.1.1 1.1

*p=0 是字符串结束的意思

这么写就是把p指向的地址里面的内容赋值为0啊

'\0'的ascii码的值是0

  • 谁能帮我解释一下这段程序?最好是逐条的。
    答:P2.0~P2.2为通道选择线,P2.6为IC选择线;P1.0为转换结束信号线;P0.0~P0.8为数据线;P2口被配置为第二功能,即地址线的高8位(低8位忽略),所以通道选择线的地址范围为C0FFH~C7FFH,采集的数据存放在30H开始的外部ram中。详细解释:ORG 0030H; 定位程序在ROM中的开始存储地址为...
  • 谁能解释一下这段C程序(新手求教)
    答:定义了一个子函数,在main中可以调用这个函数实现此函数所实现的功能。1。首先函数有个类型就是返回类型,int 型 函数名就是fun,fun函数中带有一个指向字符的指针型的形参x,在主函数main中调用时就要传入一个指向字符的指针型的实参。2。在函数体中,首先定义了一个向字符的指针型变量y,并将传过来...
  • 谁能告诉我这段matlab程序的详细意思,要求每一段都注释
    答:谁能告诉我这段matlab程序的详细意思,要求每一段都注释 30 clearall;clc;N_ofdm=2048;f_delta=15e3;N_block=1000;N_subcarrier=1320;N_CP=144;Symbol_number=14;conv_poly=[23,25];K=5;trel=poly2trellis(K,conv_poly);tail=zeros(1,K-1);mod_... clear all;clc;N_ofdm=2048;f_delta=15e3...
  • 请问谁能帮忙讲解一下这道程序吗!萌新想起来有点绕!谢谢!
    答:解答如下:注:解答中使用的形如a->a=5的语句,翻译为:指针a指向整型变量a,整型变量a=5 文字版如下:include<stdio.h> void fun(int *a, int *b, int *c){ //此处形参a,b,c就相当于指针p1,p2,p3 int *t;//⑤定义了一个指针变量t t = a; a = b; b = t;//⑥另说 t = ...
  • 谁能给我解释一下这段程序
    答:意思就是在字符串的后面加上一个'\0'啊,表示这个字符串结束了,因为strlen,strcpy等函数是以'\0'来判断字符串的结束的,如果不加,调用这些函数的时候就可能会出错。请你仔细看看,当strchr找到第一个'.'号的时候,我们写了一句*p=0,就是把那个'.'号变成了'\0',然后我们用了strcpy(tp[i],...
  • 请给我详细解释一下这段程序 谢谢了!!!C语言的!
    答:程序开始的时候首先让数组的第一个数和第二个数比较,如果第一个数较大,则交换它们,以此类推,把最大的一个数交换到最后,然后再找前面剩下的最大数放到倒数第二个位置,如此循环下去,直到循环完成,数组也就排序完成了。对问题补充的回答:楼主的这个算法还可以再优化一下,比如该数组一开始是:...
  • 帮我解释下这段程序
    答:SIGN13 NEXT12:JMP SIGN12 NEXT11:JMP SIGN11 NEXT10:JMP SIGN10 NEXT9:JMP SIGN9 NEXT8:JMP SIGN8 NEXT7:JMP SIGN7 NEXT6:JMP SIGN6 NEXT5:JMP SIGN5 NEXT4:JMP SIGN4 NEXT3:JMP SIGN3 NEXT2:JMP SIGN2 NEXT1:JMP SIGN1 NEXT0:JMP SIGN0 NEXT: CALL ERROR;CALL 调用字程序 ...
  • 谁能帮我解释一下这段程序的意思?最好每一句特别是开头那几句有什么...
    答:COleSafeArray safearray_inp; 用COleSafeArray用OLE安全数据容器类 定义一个对象名字是 safearray inp 因为VARIANT虽然可以放任何类型数据到这个数组中,但该类型没有丰富的处理成员函数,说白了他是结构体不是类, 所以 需要做个转换, 转为COleSafeArray类型的数组类即可. 他具有非常丰富的成员函数.那么...
  • 谁能帮我解释一下这段matlab程序是什么意思?
    答:你用f=-0.5:0.5 则系统会默认增量是1 所以系统不可能运行出来 3. f即是plot作图的横坐标 ,至于fftshift 你在matlab 里运行help fftshift fftshift函数就是一个交换函数:交换规则如下:如:x=[1 2 3 4 5 6 7 8];y=fftshift(x);then y=[5 6 7 8 1 2 3 4];其在fft运算里的...
  • 帮忙解释一下这段程序什么意思
    答:这段程序很简单啦!是一个VB程序中单击 工具栏Toolbar2上的一组Button控件其中之一时 执行事件函数;Button.Index 对应 Button 控件的索引 Button.Index ==1 、2、3、4、5时,分别对应 显示 frmHouse、frmYiBiao、frmCharge、frmTgYiBiao、frmTgFee窗体;Button.Index ==16时,弹出对话框"真的要对...