所学2

1.mfc DEBUG调试可以加 TRACE("%d\n", __LINE__);  看问题

2.MoveMemory相当于内存数据的剪切再粘贴
  CopyMemory相当于内存数据的复制再粘贴

3.定义一个全局CCriticalSection g_lock;
线程函数中
g_lock.Lock();
。。。查看list
g_lock.UnLock();

清除list时
g_lock.Lock();
lst.clear();
g_lock.UnLock();
 
4.WPARAM 和 LPARAM 本质上没有什么区别:都是32位数;
但是区别也还是有的:除了上面的关于16位的的历史问题外,MICROSOFT在使用时两种参数分别代表不同的含义和内容,WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递,可以参考各种控件的通知消息:可以查看:EN_CHANGE (EDIT控件的一个通知消息),CBEM_INSERTITEM(可扩展组合框的可接受消息)等等来加以领会。
理论上在使用自定义消息时,WPARAM LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。

5.首先要清楚,如果没有try的话,出现异常会导致程序崩溃。
而try则可以保证程序的正常运行下去,比如说:
try{
int i = 1/0;
}catch(exception e){
........e.what();
}
一个计算的话,如果除数为0,则会报错,如果没有try的话,程序直接崩溃。用try的话,则可以让程序运行下去,并且输出为什么出错!
try的话,配合log使用会对程序的日后维护帮助很大。

6.cstring 不需要初始化! 已经实现了  cstring a = "";没有意义!

7.注册热键:RegisterHotKey(GetSafeHwnd(),1002,MOD_ALT,'K');
//实现热键
LRESULT CviewDlg::OnHotKey(WPARAM wParam,LPARAM lParam)
{
    if(wParam==1002)
    {
        if(theApp.IsQuickPrintCate)
        {
            FastInv fastInv;
            fastInv.DoModal();
        }
    }
    return 0;
}


8.    CRect testrect;
    GetClientRect(&testrect);//获取的是整个窗口的位置大小位置
    ClientToScreen(testrect);//会获取到(客户区,不含标题栏)在桌面的位置

9.movewindow()
 函数功能:该函数改变指定窗口的位置和尺寸。对于顶层窗口,位置和尺寸是相对于屏幕的左上角的:对于子窗口,位置和尺寸是相对于父窗口客户区的左上角坐标的。
  函数原型:BOOL MoveWindow(HWND hWnd,int x.int y,int nWidth,int nHeight,BOOL BRePaint);  参数:  hWnd:窗口句柄。
  x:指定窗口的新位置的左边界。
  Y:指定窗口的新位置的顶部边界。
  nWidth:指定窗口的新的宽度。
  nHaight:指定窗口的新的高度。
  bRepaint:确定窗口是否被刷新。如果该参数为TRUE,窗口接收一个WM_PAINT消息;如果参数为FALSE,不发生任何刷新动作。它适用于客户区,非客户区(包括标题栏和滚动条),及由于移动子窗口而露出的父窗口的区域。如果参数为FALSE,应用程序就必须明确地使窗口无效或重画该窗口和需要刷新的父窗口。
  返回值:如果函数成功,返回值为非零;如果函数失败,返回值为零。若想获得更多错误信息,请调用GetLastError函数。
  备注:如果bRepaint为TRUE,系统在窗口移动后立即给窗口过程发送WM_PAINT消息(即由MoveWindow函数调用UPdateWindow函数)。如果bRepaint 为FALSE,系统将WM_PAINT消息放在该窗口的消息队列中。消息循环只有在派遣完消息队列中的其他消息时才派遣WM_PAINT消息。

10. strcmp和stricmp的区别
stricmp比较时不区分大小写,strcmp区分大小写!

11.用format的时候 string记得强转一下子...UNICODE的
Cstring strTEST.Format(L"%s",Cstring(CStringA(string.c_str())));为啥要先转CStringA需要再查一下

12.动态库中的pretranslatemessage是不能响应的,原因在于:
因为DLL中窗口的创建是在一个导出函数中,并在调用CWnd::Create这前调用了
AFX_MANAGE_STATE(AfxGetStaticModuleState())来切换模块线程状态,导致该窗口所在的模块线程状态和MFC调用CWinApp::PreTranslateMessage时的不同,所以DLL中的窗口就无法响应PreTranslateMessage函数了。

解决方案:

1.dll导出一条函数 DllPreTranslateMessage

BOOL PASCAL DllPreTranslateMessage(MSG *pMsg)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    return theApp.PreTranslateMessage(pMsg);
}
2.在主程序的CWinApp的PreTranslateMessage中直接调用DLL的DllPreTranslateMessage函数。但记住要先调用DLL中的函数。

BOOL CMyApp::PreTranslateMessage(MSG* pMsg)
{
    // TODO: Add your specialized code here and/or call the base class
    if(DllPreTranslateMessage(pMsg))
        return TRUE;
    return CWinApp::PreTranslateMessage(pMsg);
}
经过以上两步,DLL中的窗口就可以响应PreTranslateMessage了。
鼠标右键屏蔽直接有他的消息 OnContextMenu...鼠标右键点击时走这~!


13.问题:FTP和HTTP有什么区别  

答: FTP(File Transfer Protocol,文件传输协议是Internet上使用非常广泛的一种通讯协议,它是为Internet用户进行文件传输(包括文件的上传和下载)而制定的。要想实现FTP文件传输,必须在相连的两端都装有支持FTP协议的软件,装在您的电脑上的叫FTP客户端软件,装在另一端服务器上的叫做FTP服务器端软件。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。


14.隐藏win32控制台程序的窗口
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

15.cstring 转 int
直接用CString str("1234");
int i= _ttoi(str);
在ANSI 和 UNICODE 都可以用的代码

16.下拉列表初始化显示和赋值
m_combobox.AddString(c);
   m_combobox.SetCurSel(2);//设置初始化显示
    GetCurSel//获取当前标签值


17.获取文件路径并显示在edit中:
    CString csFilePath;
    CFileDialog dlg(TRUE,
        NULL,
        NULL,
        OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
        L"Text File (*.txt)|*.txt|All Files (*.*)|*.*||",
        NULL);
    if(dlg.DoModal()==IDOK)
    {
        csFilePath = dlg.GetPathName();
        m_edtPayresult.SetWindowText(csFilePath);
    }

18.CTR缩写的意思为
The C Run-time Library (CRT) is the part of the C++ Standard Library that incorporates the ISO C99 standard library.

19.程序崩溃很大程度上取决于对该应用的诊断。但我们可以总结一下一些随机常见的崩溃原因:

1、不确定的变量:程序使用了随机的数字或变量组件,在程序执行时没有被很好的确定范围。如:用户输入,随机数,或时间。

2、内存泄漏:程序每次执行时都内存溢出。每次运行程序崩溃的罪魁祸首是随机的,因为它依赖于在特定时间运行的进程数。

3、包括堆溢出或者是栈异常。

4、程序依赖于其它外部应用也可能导致崩溃。如果我们的应用依赖于一个系统某些系统属性,他们被另一个程序修改,那么这个干扰可能会导致系统崩溃。与硬件交互的程序更容易出现这些错误。例如,一个Web服务器是更容易出现内存泄漏,而接近系统级运行的程序更容易崩溃,由于系统的依赖。


20.结构化异常处理(Structured Exception Handling, SEH)

21.        short high2Bytes=*((short*)(pCopyDataStruct->dwData));
        if (high2Bytes==BILL_MSG)
        {
            short low2Bytes=*((short*)(pCopyDataStruct->dwData+2));
        }

22.
1.(临界区)CS由于关键段的“线程所有权”特性所以关键段只能用于线程的互斥而不能用于同步
2.(事件)最后总结下事件Event
    1.事件是内核对象,事件分为手动置位事件和自动置位事件。事件Event内部它包含一个使用计数(所有内核对象都有),一个布尔值表示是手动置位事件还是自动置位事件,另一个布尔值用来表示事件有无触发。

    2.事件可以由SetEvent()来触发,由ResetEvent()来设成未触发。还可以由PulseEvent()来发出一个事件脉冲。

    3.事件可以解决线程间同步问题,因此也能解决互斥问题。
3.(互斥量)
最后总结下互斥量Mutex:

1.互斥量是内核对象,它与关键段都有“线程所有权”所以不能用于线程的同步。

2.互斥量能够用于多个进程之间线程互斥问题,并且能完美的解决某进程意外终止所造成的“遗弃”问题。

4.网上搜索了一下,感觉对理解信号量挺有帮助的:
以一个停车场的运作为例。简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆直接进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入外面的一辆进去,如果又离开两辆,则又可以放入两辆,如此往复。
在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。
 抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为零时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: Wait(等待) 和 Release(释放)。当一个线程调用Wait操作时,它要么得到资源然后将信号量减一,要么一直等下去(指放入阻塞队列),直到信号量大于等于一时。Release(释放)实际上是在信号量上执行加操作,对应于车辆离开停车场,该操作之所以叫做“释放”是因为释放了由信号量守护的资源。


23.寄存器和存储器的区别
从根本上讲,寄存器与RAM的物理结构不一样。
一般寄存器是指由基本的RS触发器结构衍生出来的D触发,
就是一些与非门构成的结构,这个在数电里面大家都看过;
而RAM则有自己的工艺,一般1Bit由六MOS管构成。所以,
这两者的物理结构不一样也导致了两者的性能不同。寄存器
访问速度快,但是所占面积大。而RAM相反,所占面积小,
功率低,可以做成大容量存储器,但访问速度相对慢一点。

1、
寄存器存在于CPU中,速度很快,数目有限;
存储器就是内存,速度稍慢,但数量很大;
计算机做运算时,必须将数据读入寄存器才能运算。

2、
存储器包括寄存器,
存储器有ROM和RAM
寄存器只是用来暂时存储,是临时分配出来的,断电,后,里面的内容就没了`````


24.遍历显示所有打印机名称
DWORD dwSize,dwPrinters;
    CString strName[10];//存储名称,可以自己设定
    ::EnumPrinters(PRINTER_ENUM_LOCAL,NULL,5,NULL,0,&dwSize,&dwPrinters);
    BYTE* pBuffer=new BYTE[dwSize];
    ::EnumPrinters(PRINTER_ENUM_LOCAL,NULL,5,pBuffer,dwSize,&dwSize,&dwPrinters);
    if (dwPrinters!=0)
    {
        PRINTER_INFO_5* pPrnInfo=(PRINTER_INFO_5*)pBuffer;
        for (UINT i=0;i<dwPrinters;i++)
        {
            strName[i]=pPrnInfo->pPrinterName;
            pPrnInfo++;
        }
    }
    delete[] pBuffer;

25.strlen 不算\0  sizeof算了!

26.如果函数定义很简单,那么不需要写到cpp中。仍在.h中使其成为inline函数即可编译通过。

27.两个\\一个字符   \后面加东西是转译字符

28.messagebox 非模态对话框

Unicode下函数声明为:
int
WINAPI
MessageBoxW(
    HWND hWnd ,
    LPCWSTR lpText,
    LPCWSTR lpCaption,
    UINT uType);

当第一个参数hWnd = NULL时,生成的对话则为非模态对话框。

29.& 和&&
&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。
&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str != null && !str.equals(“”))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33 & ++y>0) y会增长,If(x==33 && ++y>0)不会增长
&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31 & 0x0f的结果为0x01


30.第一范式:不可分离;第二范式:消除部分依赖;第三范式:在第二范式的基础上消除传递依赖

31.堆区栈区哪个效率高
栈分配的软件优势:
栈分配算法简单,所以高效;堆分配算法相对比较复杂。
栈分配的硬件优势:
主要两点,cache和内存映射。
如果在栈上分配小块内存,因为cache和内存映射已经建立
,则效率会非常高,远远优于堆分配。
如果在栈上分配大块内存,在不考虑爆栈的情况下,其实两者效率差不到哪去
。因为cache命中和内存映射总是在有限的大小进行的,其在栈中分配的大块内存照样cache不命中,而且映射未建立,所以这样的时间相差其实并不太多。2.
1.分配和释放,堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间(因为多次分配释放后会造成空洞),这些都会花费一定的时间,具体可以看看MALLOC和FREE的源代码,他们做了很多额外的工作,而栈却不需要这些。
2.访问时间,访问堆的一个具体单元,需要两次访问内存,第一次得取得指针,第二次才是真正得数据,而栈只需访问一次。另外,堆的内容被操作系统交换到外存的概率比栈大,栈一般是不会被交换出去的。
综上所述,站在操作系统以上的层面来看,栈的效率比堆高。3.
栈快,以下原因:
栈有专门的寄存器,压栈和出栈的指令效率很高,而堆需要由OS动态调度,堆内存可能被OS调度在非物理内存中,或是申请内存不连续,造成碎片过多等问题。
另外,分配方式上,堆都是动态分配的,栈是编译器完成的。栈的分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现4.
由于栈和堆使用的都是用户空间的虚拟内存,而且你说那个用法是作为函数参数,通过指针引用。非要说有区别,可能是第一次访问该内存的时候有可能更快些,理由是当你调用函数是,只想的栈内搜索存一定已经加载到物理内存里面了,页表也已经建好了(在该页没有被置换出去的情况下);指向堆的内存不一定已经映射到物理内存,因此需要处理缺页,建立页表。至于指向的内存都已经加载到物理内存的情况,应该没有区别。5.
栈内存更快,栈是和代码段一同被载入到CPU内存中的,用C写得程序在被编译成机器指令之后,同一个函数栈上的变量会被保存在寄存器中的,并且栈上的内存基本上都是在编译的时候就确定了得,由于CPU的运算原理明显依赖寄存器的,所以栈上的内存访问速度明显比堆上快,现在CPU的设计一、二级缓存的大小已经最后栈内存的使用,所以效率明显要高很多,而堆上的内存由于和函数栈不在同一个地址段,所以堆上的内存很有可能不在寄存器或者CUP缓存中,访问命中率就低,同时效率也就会低很多,因为要出发好多系统内核调用,内存需要从硬盘到内存到CUP缓存再到寄存器。6.
栈效率更高,因为堆分配分配了之后还要与存储器之间建立映射,而栈分配则是之前就建立好了。

32.3<<2左移运算  按照位移动,如最高位为1的话移动后补1 得到3*2的2次方       3>>右移运算  就是除2的N次方,不过得到小数的话省略小数    <<< 无符号左移运算,最高位为1的话  也是补0

33.STL的最主要的两个特点:数据结构和算法的分离,非面向对象本质。访问对象是通过象指针一样的迭代器实现的;容器是象链表,矢量之类的数据结构,并按模板方式提供;算法是函数模板,用于操作容器中的数据。由于STL以模板为基础,所以能用于任何数据类型和结构。

34.OutputDebugString格式化输出
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
void __cdecl odprintf(const char *format, ...)
{char buf[4096], *p = buf;
va_list args;
va_start(args, format);
p += _vsnprintf(p, sizeof buf - 1, format, args);
va_end(args);
while ( p > buf && isspace(p[-1]) )
{
*--p = '\0';
*p++ = '\r';
*p++ = '\n';*p = '\0';
}
OutputDebugString(buf)
;}
于是在代码中使用它就很简单:
...odprintf("Cannot open file %s [err=%ld]", fname, GetLastError());...我们已经这样使用多年了。//\n会崩溃 后期看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值