zoukankan      html  css  js  c++  java
  • MFC基本知识沉淀

           有一周多没有更新博客了,这段时间项目验收结尾,冲刺的时间比较多。还记得Fusion Chart的Demo吗,我们一起分析了 Fusion Chart Free,但功能更强大的当然是商业版。现在正在整理其Demo,项目结束与大家分享,敬请期待啊。请您先看张截图吧。

    对于这张图如果用过FC的人,应该很熟悉的吧。对了,您猜对了,就是它。因为公司要用到RDLC报表,回头打算把RDLC的使用也复习下吧。

    好了,项目快要结束了,做一下简单的技术沉淀,(当然正规的也要做的)。下面我们一起看一些基本的MFC的知识(学习MFC一定要有基础的)。

    一、_T()函数

    _T("")是一个宏,他的作用是让你的程序支持Unicode编码
    因为Windows使用两种字符集ANSI和UNICODE,
    前者就是通常使用的单字节方式,
    但这种方式处理象中文这样的双字节字符不方便,
    容易出现半个汉字的情况。
    而后者是双字节方式,方便处理双字节字符。

    Windows NT的所有与字符有关的函数都提供两种方式的版本,而Windows 9x只支持ANSI方式。
    如果你编译一个程序为ANSI方式,
    _T实际不起任何作用。
    而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串以UNICODE方式保存。_T和_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存。
     

    LPSTR:32bit指针指向一个字符串,每个字符占1字节

    LPCSTR:32-bit指针指向一个常字符串,每个字符占1字节
    LPCTSTR:32-bit指针指向一个常字符串,每字符可能占1字节或2字节,取决于Unicode是否定义
    LPTSTR:32-bit指针每字符可能占1字节或2字节,取决于Unicode是否定义

    L是表示字符串资源为Unicode的。

    比如
    wchar_t Str[] = L"Hello World!";
    这个就是双子节存储字符了。

    _T是一个适配的宏~


    #ifdef _UNICODE的时候
    _T就是L
    没有#ifdef _UNICODE的时候
    _T就是ANSI的。

    比如

    LPTSTR lpStr = new TCHAR[32];
    TCHAR* szBuf = _T("Hello");
    以上两句使得无论是在UNICODE编译条件下都是正确编译的。

    而且MS推荐你使用相匹配的字符串函数。
    比如处理LPTSTR或者LPCTSTR 的时候,不要用strlen ,而是要用_tcslen

    否则在UNICODE的编译条件下,strlen不能处理 wchar_t*的字符串。

    T是非常有意思的一个符号(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()...),它表示使用一种中间类型,既不明确表示使用 MBCS,也不明确表示使用 UNICODE。那到底使用哪种字符集?编译的时候才决定

    将char字符串转换成Unicode字符串。
    T是个宏,不是函数

    在需要双字节的函数,或COM里需要双字节的串.
    为了国际兼容。其实很简单。
    Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

    如果将来你不打算升级到unicode,那么也不需要_T,

    _t("hello world")
    在ansi的环境下,它是ansi的,如果在unicode下,那么它将自动解释为双字节字符串,既unicode编码。
    这样做的好处,不管是ansi环境,还是unicode环境,都适用。

    2\请问在vc++中的字符串_T("ABC")和一个普通的字符串“ABC”有什么区别。

    _T("ABC")
    表示如果定义了unicode
    它表示 L"ABC",每个字符为16位,宽字符字符串
    ---------------------------------------------------------
    if not UNICODE
    它就是ascii的"ABC",每个字符为8位
    "ABC"就是指ascii字符串"ABC"

    ----------------------------------------------------------

    相当于
    #ifdef _UNICODE
    #define _T("ABC") L"ABC"
    #else
    #define _T("ABC") "ABC"
    #endif

    ----------------------------------------------------------

    _T("ABC")中的一个字符和汉字一样,占两个字节,而在"ABC"中,英文字符占一个字节,汉字占两个字节

    二、堆和栈

         

    1、“堆”和“栈”在C++中主要是指存放数据或者说是变量、对象的在内存中的区域,如同现实中 美国和中国的区别,表面上是在内存中的位置不同,但是分配内存的方式却大不相同,如同美国和中国虽然表面上都是国家,但是社会制度、各种福利 各种机构都不同,一句话就是内存中的不同区域。

    2、c++中“堆”:在一个程序中 堆是一片内存,不是有堆内存之说,一般都是程序员手动分配,在C++中则是一般用new操作符(如果不使用C的malloc系列,好像只能用new)分配的内存,同样也只能程序员手动释放,不然会有内存泄露。当然了给什么分配内存,那只能给变量、类对象分配,所以存放的也是类对象和变量。
    c++中“栈”:是程序自动分配的内存,比如调用某个函数,传递参数时(值传递),那么这个参数的值是在“栈”内存上分配的,当这个函数退出后 占用的“栈”内存也就自己释放了。

    三、Windows Socket

    s Socket的实现方法:
               Socket是连接应用程序与网络驱动程序的桥梁。它在应用程序中创建,通过绑定操作与驱动程序建立关系。此后,应用程序送给Socket数据,由Socket交给驱动程序,驱动程序再把数据向网络上发送出去。计算机从网络上收到与该Socket绑定的IP地址和端口号相关的数据后,由驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据。网络应用程序就是这样运用Socket进行数据的发送与接收的。

    ISO/OSI七层参考模型(ISO:国际标准化组织   OSI:Open System Interconnection):
    物理层:提供二进制传输,确定在通信信道上如何传输比特流。
    数据链路层:提供介质访问,加强物理层的传输功能,建立一条无差错的传输线路。
    网络层:提供IP寻址和路由。因为在网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输路线。        
    传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,使得网络应用与下层协议无关。
    会话层:在两个相互通信的应用进程之间建立、组织和协调其相互之间的通信。     
    表示层:处理被传送数据的表示问题,即信息的语法和语义。  


    对等层通信的实质:
    对等层实体之间虚拟通信。
    下层向上层提供服务,实际通信在最底层完成。

    各层所使用的协议:
    应用层:远程登录协议Telnet、文件传输协议FTP、超文本传输协议HTTP、域名服务DNS、简单邮件传输协议SMTP、邮局协议POP3。
    传输层:传输控制协议TCP、用户数据报协议UDP。
    网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。

    TCP/IP模型:应用层、传输层、网络层、网络接口层。
    TCP/IP模型与OSI模型对照如下
     应用层:应用层、表示层、会话层。      传输层:传输层。     网络层:网络层。   网络接口层:数据链路层、物理层。


    端口:一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。

    套接字的类型:
    (1)流式套接字(SOCK_STREAM),基于TCP协议实现。
    (2)数据报套接字(SOCK_DGRAM),UDP协议实现。
    (3)原始套接字(SOCK_RAW)


    Windows Socket  “TCP”网络编程实例
    一些开发步骤:
    “TCP”服务器端
    1、加载套接字库。
    2、创建套接字。
    3、绑定地址信息。
    4、绑定套接字。
    5、监听套接字。
    6、“Accept”等待用户请求。
    7、“send”发送数据。
    8、"recv"接收数据。
    9、关闭“使用中的套接字”,继续循环等待。

    “TCP”客户端
    1、加载套接字库。
    2、创建套接字。
    3、绑定地址信息。
    4、绑定套接字。
    5、发出请求。
    6、接收数据。
    7、发送数据。
    8、关闭套接字。
    9、“WSACleanup”终止“套接字库”的使用。(服务器端一直循环运行,所有没有)。

    对于UDP通信,不需要建立连接,直接进行收/发就可以了。

    四、多线程

         

    1、程序和进程
             程序是计算机指令的集合,它以文件的形式存储在磁盘上。而进程是正在运行的程序的实例。比如,我们编译生成的“exe”文件是一个可执行程序,存储在磁盘上就是程序。点击运行后,就启动了该程序的一个实例,我们称之为进程。一个程序可以有多个进程,也就是一个程序可以产生多个实例。

    2、进程和线程
             进程从来不执行任何东西,它是线程的容器,真正完成代码执行的是线程。单个进程可能包含若干个线程,但至少包含一个主线程。

    3、进程的地址空间
             系统赋予每个进程独立的虚拟地址空间。对于32位操作系统,运行32位的进程,这个地址空间是4G。因为对于32位指针来说,它的寻址的范围是2的32次方,即4G。这就是为什么32位操作系统,内存条一般不超过4G的原因。

    4、虚拟内存。
            在磁盘上有一个“pagefile.sys”文件,它是页文件,页文件透明的为应用程序增加了内存,这一部分就是虚拟内存。

    5、线程。
            线程的内核对象:操作系统用来存放线程统计信息的小型的数据结构。
            线程栈:它用于维护线程在执行代码是所需要的所有函数参数和局部变量。
            同一个进程的不同线程运行在同一个进程环境下,它们共享资源,所以可以非常容易的实现相互之间的通信。
            线程运行在操作系统为其分配的CPU时间片上,对于单核CPU,就要多个线程来回切换。多核CPU就可以实现多个线程的并发执行。
            采用多线程而不是多进程,是因为线程只有一个内核对象和一个栈,占用内存少。而对于进程每一个都要分配4GB的虚拟地址空间,占用资源多。而且进程切换需要交换整个地址空间。线程之间的切换只是执行环境的改变。

           这些都是些基本的知识,希望您也能复习下。

          

            感谢您的支持。想整一个空间,帮忙点击一下,加一分吧。

          

  • 相关阅读:
    python生成xml文件
    gcc基本用法
    Java删除文件或目录及目录下所有文件
    QTimer在QThread环境中失效的问题
    fopen打开文件失败的问题
    利用枚举,简化多个标志位统计
    QTableView表格自动拉伸
    django1.11 启动错误:Generator expression must be parenthesized
    css选择器
    property使用
  • 原文地址:https://www.cnblogs.com/ssol/p/2284086.html
Copyright © 2011-2022 走看看