111、程序在执行int main(int argc, char *argv[])时的内存结构,你了解吗?
参数的含义是:
- 程序在命令行下运行的时候,需要输入argc 个参数,每个参数是以char 类型输入的,依次存在数组里面,数组是 argv[];
- 所有的参数在指针char * 指向的内存中,数组的中元素的个数为 argc 个,第一个参数为程序的名称。
112、volatile关键字的作用?
- volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。
- 遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
- 声明时语法:
int volatile vInt;
当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。
volatile用在如下的几个地方:
- 中断服务程序中修改的供其它程序检测的变量需要加volatile;
- 多任务环境下各任务间共享的标志应该加volatile;
- 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
113、如果有一个空类,它会默认添加哪些函数?
1) Empty(); // 默认构造函数//
2) Empty( const Empty& ); // 拷贝构造函数//
3) ~Empty(); // 析构函数//
4) Empty& operator=( const Empty& ); // 赋值运算符//
114、C++中标准库是什么?
C++ 标准库可以分为两部分:
1、标准函数库: 这个库是由通用的、独立的、不属于任何类的函数组成的。函数库继承自 C 语言。
2、面向对象类库: 这个库是类及其相关函数的集合。
- 输入/输出 I/O、字符串和字符处理、数学、时间、日期和本地化、动态分配、其他、宽字符函数;
- 标准的 C++ I/O 类、String 类、数值类、STL 容器类、STL 算法、STL 函数对象、STL 迭代器、STL 分配器、本地化库、异常处理类、杂项支持库。
115、你知道const char* 与string之间的关系是什么吗?
1、string 是c++标准库里面其中一个,封装了对字符串的操作,实际操作过程我们可以用const char*给string类初始化。
三者的转化关系如下所示:
1、string转const char*
string s = “abc”;
const char* c_s = s.c_str();
2、const char * 转string,直接赋值即可
const char* c_s = “abc”;
string s(c_s);
3、string 转char*
string s = “abc”;
char* c;
const int len = s.length();
c = new char[len+1];
strcpy(c,s.c_str());
4、char * 转string
char* c = “abc”;
string s(c);
5、const char* 转char*
const char* cpc = “abc”;
char* pc = new char[strlen(cpc)+1];
strcpy(pc,cpc);
6、char* 转const char*,直接赋值即可
char* pc = “abc”;
const char* cpc = pc;
116、你什么情况用指针当参数,什么时候用引用,为什么?
使用引用参数的主要原因有两个:
- 程序员能修改调用函数中的数据对象;
- 通过传递引用而不是整个数据–对象,可以提高程序的运行速度
一般的原则:
对于使用引用的值而不做修改的函数:
- 如果数据对象很小,如内置数据类型或者小型结构,则按照值传递;
- 如果数据对象是数组,则使用指针(唯一的选择),并且指针声明为指向const的指针;
- 如果数据对象是较大的结构,则使用const指针或者引用,已提高程序的效率。
- 如果数据对象是类对象,则使用const引用(传递类对象参数的标准方式是按照引用传递);
对于修改函数中数据的函数:
- 如果数据是内置数据类型,则使用指针;
- 如果数据对象是结构,则使用引用或者指针;
- 如果数据是类对象,则使用引用
117、你知道静态绑定和动态绑定吗?讲讲?
对象的静态类型: 对象在声明时采用的类型。是在编译期确定的。
对象的动态类型: 目前所指对象的类型。是在运行期决定的。对象的动态类型可以更改,但是静态类型无法更改。
静态绑定: 绑定的是对象的静态类型,某特性(比如函数依赖于对象的静态类型,发生在编译期。)
动态绑定: 绑定的是对象的动态类型,某特性(比如函数依赖于对象的动态类型,发生在运行期。)
118、如何设计一个计算仅单个子类的对象个数?
- 为类设计一个static静态变量count作为计数器,类外初始化;
- 类定义结束后初始化count;
- 在构造函数中对count进行+1;
- 设计拷贝构造函数,在进行拷贝构造函数中进行count +1,操作;
- 在析构函数中对count进行-1;
//利用静态数据成员的数据共享这个性质
class Widget {
public:
Widget() { ++count; }
Widget(const Count&) { ++count; }
~Widget() { --count; }
static size_t getCount() { return count; }
private:
static size_t count;
};
//然后在main外写上
size_t Widget::count = 0;
//在main里写上
cout << Cylinder::getCount();
119、怎么快速定位错误出现的地方?
- 如果是简单的错误,可以直接双击错误列表里的错误项或者生成输出的错误信息中带行号的地方就可以让编辑窗口定位到错误的位置上;
- 对于复杂的模板错误,调试!
120、成员初始化列表会在什么时候用到?它的调用过程是什么?
成员初始化列表会在什么时候用到?
- 当初始化一个引用成员变量时;
- 初始化一个const成员变量时;
- 当调用一个基类的构造函数,而构造函数拥有一组参数时;
- 当调用一个成员类的构造函数,而他拥有一组参数;
调用过程:
- 编译器会一一操作初始化列表,以适当顺序在构造函数之内安插初始化操作,安插在用户代码前。
- 列表中的初始化顺序是由类中的成员声明顺序决定的,不是初始化列表中的排列顺序决定的。