zoukankan      html  css  js  c++  java
  • C/C++ 答疑解问

    1. sizeof(string)的大小

    string属于类,类的大小就是类中成员变量(非静态)加上指向虚函数表的指针以及指向虚基类表的指针加起来的和。因为string是一个模板类,受具体的实现来决定其sizeof。实际上,到了C++中,对类的sizeof往往没有意义。这涉及到编译器在实现类对象时采用的数据结构。

    VC6.0:sizeof(string) = 16;
    VS2010:sizeof(string) = 32;

    可以发现std::string在VC6.0和VS2010里面的实现并不相同。


     2. new、delete与malloc、free的关系

    malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
    对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
    因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。

    参考:malloc/free和new/delete的区别


     3. 泛化、关联、组合、聚合以及依赖的区别

    依赖:用到了别人的方法或变量;关联:对称的,好比你是我的朋友,我也是你的朋友;聚合:非对称的,员工与公司就是聚合关系,还有一个重要特点就是生命周期可以不同,员工离开了公司还是可以活的;组合:生命周期一致,好比人与心脏,一个没了另一个也没了。强度:依赖<关联<聚合<组合。

    详见:关联、组合、聚合、依赖关系比较


     4. 分别写出BOOL,int,float,指针类型的变量与“零”的比较语句。

    BOOL: if (flag) or if (!flag)
    int:    if (n == 0) or if(n != 0)
    float:   const float EPSINON = 0.00001;
         if ((x >= - EPSINON) && (x <= EPSINON))
         其中EPSINON 是允许的误差(即精度),在允许误差内的就认为是相等的
    pointer: if (p == NULL) or if(p != NULL)

    参见:零值比较--BOOL,int,float,指针变量与零值比较的if语句


    5. (1)如何打印出当前源文件的文件名以及源文件的当前行号?

    cout << __FILE__;
    cout << __LINE__;

    __FILE__和__LINE__是系统预定义宏,这种宏并不是在某个文件中定义的,而是由编译器定义的。

      (2)如何判断一段程序是由C 编译程序还是由C++编译程序编译的?

    #ifdef __cplusplus//两个下划线
    cout<<"c++";
    #else
    cout<<"c";
    #endif
    

    6. 在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”?  

    详见:C++中extern “C”含义深层探索


    7. 写出Windows消息机制的流程。

    (1)操作系统接收到应用程序的窗口消息,将消息投递到该应用程序的消息队列中。
    (2)应用程序在消息循环中调用GetMessage函数从消息队列中取出一条条的消息。取出后,以对消息进行一些预处理,如放弃对某些消息的响应,或者调用TranslateMessage产生新的消息。
    (3)应用程序调用DispatchMessage,将消息回传给操作系统。
    (4)系统利用窗口过程函数调用窗口过程,对消息进行处理。

    通常我们编写的消息循环代码如下:

    while(GetMessage (&msg, NULL, 0, 0))
    {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
    }

    TranslateMessage函数将虚拟键消息转换为字符消息。DispatchMessage实际上是将消息回传给操作系统,由操作系统调用窗口过程函数对消息进行处理。
    从消息队列中获取消息还可以调用PeekMessage函数,发送消息可以使用SendMessage和PostMessage函数。


    8. 引用与指针有什么区别?

    (1)引用必须被初始化,指针不必。
    (2)引用初始化以后不能被改变,指针可以改变所指的对象。
    (3)不存在指向空值的引用,但是存在指向空值的指针。
    (4)从内存上来讲,系统为指针分配内存空间,而引用与绑定的对象共享内存空间,系统不为引用变量分配内存空间。所以引用访问对象是直接访问,指针访问对象是间接访问。


    9. 网络相关知识

    集线器Hub工作在OSI参考模型的(物理)层;交换机Switch工作在OSI参考模型的(数据链路)层;路由器Router工作在OSI参考模型的(网络)层;

    IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与之后才能区分哪些是网络位哪些是主机位。

    ARP(Address Resolution Protocol)地址解析协议将IP地址转化为主机物理地址(MAC地址),对应RARP协议。

    ICMP:Internet Control Message Protocol(网际控制报文协议)的缩写。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
    ICMP的一个重要应用就是分组网间探测PING(Packet InterNet Groper),用来测试两个主机之间的连通性。
    另一个非常有用的应用是traceroute(UNIX系统中名字,Windows对应的命令是tracert),它用来跟踪一个分组从源点到终点的路径。

    DHCP:(Dynamic Host Configuration Protocol)动态主机配置协议,是一种让系统得以连接到网络上,并获取所需要的配置参数手段。这种机制允许一台计算机加入新的网络和获取IP地址而不用手工参与。


     10. (1) 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)。

    #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL

    在C语言中,宏是产生内嵌代码的唯一方法。对于嵌入式系统而言,为了能达到性能要求,宏是一种很好的代替函数的方法。
    注意几点:
    1). #define 语法的基本知识(例如:不能以分号结束,最好将宏定义中的“参数”和整个宏用用括号括起来),函数宏被调用时只是进行简单的字符替换,而不是“值传递”。
    2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
    3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
    4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。

    (2) 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

    #define MIN(A,B) ((A)<=(B) ? (A):(B))

    而比如代码:least = MIN(*p++, b); 将被替换为:((*p++)<=(b) ? (*p++):(b)),发生的事情无法预料,因而不要给宏定义传入有副作用的"参数"。


    11. const 和 #define的区别

    (1) 编译器处理方式不同:define宏是在预处理阶段展开;const常量是编译运行阶段使用。
    (2) 类型和安全检查不同:define宏没有类型,不做任何类型检查,仅仅是字符替换,并且在字符替换可能会产生意料不到的错误(边际效应);const常量有具体的类型,在编译阶段会执行类型检查。有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
    (3) 存储方式不同:define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存;const常量会在内存中分配(可以是堆中也可以是栈中)

    在C++ 程序中只使用const常量而不使用宏常量,即const常量完全取代宏常量。


    12. 设计模式:工厂模式和单例模式介绍一下?

    单体模式 很简单,就是将构造函数变为私有,那么就不能通过new来创建对象。同时创建一个共有的静态的方法来获得实例,代码如下:C++

    //Singleton.h
    class Singleton  
    {
    public:
    	static Singleton* GetInstance();
    private:
    	Singleton() {}
    	static Singleton *singleton;
    };
    //Singleton.cpp
    Singleton* Singleton::singleton = NULL;
    Singleton* Singleton::GetInstance()
    {
    	if(singleton == NULL)
    		singleton = new Singleton();
    	return singleton;
    }

    工厂模式有三个参与者,抽象产品(Product)、工厂(Creator)和具体产品(ConcreteProduct)。客户只会看到工厂和抽象产品。

    public interface Product{ 
        public String getName(); 
    } 
    
    public class ConcreteProduct implements Product{ 
        public String getName(){ 
            return "产品1"; 
        } 
    } 
    
    public class Creator{ 
        public static Product create1(){ 
            return new ConcreteProduct(); 
        } 
    }
    

    工厂模式的作用在于将创建具体产品的方法由工厂类控制,客户只需要知道产品的抽象类型。比如具体产品可以是:香蕉、苹果、橘子等,只需要通知一声工厂,工厂就会调用相应的 生产香蕉、生产苹果、生产橘子等函数,而客户不需要知道生产这些水果的具体过程,坐着等吃就行。

  • 相关阅读:
    PAIRING WORKFLOW MANAGER 1.0 WITH SHAREPOINT 2013
    Education resources from Microsoft
    upgrade to sql server 2012
    ULSViewer sharepoint 2013 log viewer
    Top 10 Most Valuable Microsoft SharePoint 2010 Books
    讨论 Setsockopt选项
    使用 Alchemy 技术编译 C 语言程序为 Flex 可调用的 SWC
    Nagle's algorithm
    Nagle算法 TCP_NODELAY和TCP_CORK
    Design issues Sending small data segments over TCP with Winsock
  • 原文地址:https://www.cnblogs.com/li-chong/p/3261527.html
Copyright © 2011-2022 走看看