您的位置:首页 > 编程语言 > C语言/C++

查漏补缺(C++笔试)(更新中)

2012-09-17 16:05 183 查看
1.动态链接库与静态链接库的区别:

解:动态链接是指在生成可执行文件时不将所有程序乃至的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统中找。而静态链接就是把所有乃至的函数全部链接到.exe文件中。

动态链接是只建立一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入。而静态链接是把所有的代码和数据都复制到本模块中,运行是就不在需要库了。

静态链接库与动态链接库的相同点:(1)、共享代码;(2)、代码封装。静态链接库与动态链接库的区别:(1)、静态链接库被包含在宿主程序中,而动态链接库则是在需要时动态的装载和卸载DLL文件;(2)、静态链接库中不能再包含其它动态或者静态链接库,而动态链接库中则可再包含。

2. 指令 用途

# 空指令,无任何效果

#include 包含一个源代码文件

#define 定义宏

#undef 取消已定义的宏

#if 如果给定条件为真,则编译下面代码

#ifdef 如果宏已经定义,则编译下面代码

#ifndef 如果宏没有定义,则编译下面代码

#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码

#endif 结束一个#if……#else条件编译块

#error 停止编译并显示错误信息

3.const与#define相比有什么不同

解:C++语言可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的优点:

(1)、const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误。

(2)、有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。

4.mutable关键字:

mutable的中文意思是“可变的,易变的”,跟constant(既C++中的const)是反义词。在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。我们知道,如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,有些时候,我们需要在const的函数里面修改一些跟类状态无关的数据成员,那么这个数据成员就应该被mutalbe来修饰。

5.进程与线程的区别

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,它是系统进行资源分配和调度的一个独立单位。例如,用户运行自己的程序,系统就创建一个进程,并为它分配资源,包括各种表格、内存空间、磁盘空间、I/O设备等,然后,该进程被放入到进程的就绪队列,进程调度程序选中它,为它分配CPU及其它相关资源,该进程就被运行起来。

线程是进程的一个实体,是CPU调度和分派的基本单位,线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器、一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。

在没有实现线程的操作系统中,进程既是资源分配的基本单位,又是调度的基本单位,它是系统中并发执行的单元。而在实现了线程的操作系统中,进程是资源分配的基本单位,但线程是调度的基本单位,线程是系统中并发执行的单元。

具体而言,引入线程,主要有以下4个方面的优点:

(1)易于调度。

(2)提高并发性。通过线程可以方便有效地实现并发。

(3)开销小。创建线程比创建进程要快,所需要的开销也更少。

(4)有利于发挥多处理器的功能。通过创建多线程,每个线程都在一个处理器上运行,从而实现应用程序的并行,使每个处理器都得到充分运行。

需要注意的是,尽管线程与进程二者很相似,但也存在着很大的不同,区别如下:

(1)一个线程必定属于也只能属于一个进程;而一个进程可以拥有多个线程并且至少拥有一个线程。

(2)属于一个进程的所有线程共享该线程的所有资源,包括打开的文件、创建的Socket等。不同的进程互相独立。

(3)线程又被称为轻量级进程。进程有进程控制块,线程也有线程控制块。但线程控制块比进程控制块小得多。线程间切换代价小,进程间切换代价大。

(4)进程是程序的一次执行,线程可以理解为程序中一段程序片段的执行。

(5)每个进程都有独立的内存空间,而线程共享其所属进程的内存空间。

6.const的作用

(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;

(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;

(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。

7.static的作用

(1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

(2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

(3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

(4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。

8.编写类String的构造函数、析构函数和赋值函数,已知类String的原型为:

class String
{
 public:
  String(constchar*str= NULL); // 普通构造函数
  String(constString &other); // 拷贝构造函数
  ~String(void); // 析构函数
  String &operate =(const String &other); // 赋值函数
 private:
  char*m_data;// 用于保存字符串
};
  解答:
//普通构造函数
String::String(constchar*str)
{
 if(str==NULL)
 {
  m_data=newchar[1]; // 得分点:对空字符串自动申请存放结束标志'\0'的空
  //加分点:对m_data加NULL 判断
  *m_data='\0';
 }
 else
 {
  int length =strlen(str);
  m_data=newchar[length+1]; // 若能加 NULL 判断则更好
  strcpy(m_data,str);
 }
}
// String的析构函数
String::~String(void)
{
 delete []m_data; // 或deletem_data;
}
//拷贝构造函数
String::String(const String &other)    // 得分点:输入参数为const型
{
 int length =strlen(other.m_data);
 m_data=newchar[length+1];     //加分点:对m_data加NULL 判断
 strcpy(m_data,other.m_data);
}
//赋值函数
String & String::operate =(const String&other) // 得分点:输入参数为const型
{
 if(this==&other)  //得分点:检查自赋值
  return*this;
 delete []m_data;     //得分点:释放原有的内存资源
 int length =strlen( other.m_data );
 m_data=newchar[length+1];  //加分点:对m_data加NULL 判断
 strcpy( m_data,other.m_data );
 return*this;         //得分点:返回本对象的引用
}

9.关于volatile关键字:

volatile的本意是“易变的”,volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

下面是volatile变量的几个例子:

(1). 并行设备的硬件寄存器(如:状态寄存器)

(2). 一个中断服务子程序中会访问到的非自动变量(Non-automaticvariables)

(3). 多线程应用中被几个任务共享的变量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: