【2014.11.19】程序员面试
- 编写代码时,注意考虑边界条件,特殊输入(比如空指针,空字符串等)及错误处理。
- 空类型。 空类型的实例中不包含任何信息,求sizeof应该是0,但是当我们声明该类型的实例的时候,它必须在内存中占有一定的空间,否则无法使用这些实例。占用多少内存由编译器决定。Visual Studio中,每个空类型的实例占用1字节的空间。调用构造函数和析构函数只需要知道函数的地址即可,而这些函数的地址只与类型相关,与类型的实例无关。编译器发现一个类型中含有虚函数,就会为该类型生成虚函数表,并在该类型的每一个实例中添加一个指向虚函数表的指针。32位机器上求sizeof得到4, 64位机器上求sizeof得到8.
- 四个与类型转换相关的关键字。
- const_cast:
- dynamic_cast:
- static_cast:
- reinterpret_cast:
- 复制构造函数传入的参数是一个实例的后果:如果是传值参数,把形参复制到实参会调用复制构造函数,因此,如果允许复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成永无休止的递归调用从而导致栈溢出。C++标准不允许复制构造函数传值参数。
以下三种对象需要调用复制构造函数:
1) 一个对象作为函数参数,以值传递的方式传入函数体
2) 一个对象作为函数返回值,以值传递的方式从函数返回
3) 一个对象用于给另外一个对象进行初始化。
- 赋值运算符函数
- 返回值的类型声明为该类型的引用,并在该函数结束前返回实例自身的引用(即*this)
- 传入的参数类型声明应为常量引用。如果是实例,那么从形参到实参会调用一次复制构造函数,降低了代码效率。
- 释放实例自身已有的内存,如果忘记在分配新内存之前释放自身已有的空间,程序将出现内存泄露。
- 需要判断传入的参数和当前的实例(*this)是不是同一个实例。如果是同一个,则不进行赋值操作,直接返回。
class CMyString
{
public:
CMyString(char* pData = NULL);
CMyString(const CMyString& str);
CMyString& operator= (const CMyString& str);
~CMyString();
void print();
private:
char* m_pData;
};CMyString::CMyString(char* pData)
{
if (pData == NULL)
{
m_pData = new char[1];
*m_pData = '\0';
}
else
{
m_pData = new char[strlen(pData) + 1];
strcpy_s(m_pData, strlen(pData) + 1, pData);
}}
CMyString::CMyString(const CMyString& str) //复制构造函数
{
m_pData = new char[strlen(str.m_pData) + 1];
strcpy_s(m_pData, strlen(str.m_pData) + 1, str.m_pData);
}CMyString& CMyString::operator=(const CMyString& str) //赋值运算符函数
{
if (this == &str)
return *this;
delete[] m_pData;
m_pData = NULL;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy_s(m_pData, strlen(str.m_pData) + 1, str.m_pData);return *this;
}CMyString::~CMyString()
{
delete[] m_pData;
}
- 数组和指针。
- int data1[] = {1,2,3,4,5}; sizeof(data1) = 20
- int* data2 = data1; sizeof(data2) = 4
- 当数组名作为函数参数进行传递时,数组自动退化为同类型的指针。
- 宽度优先遍历:先访问树的第一层结点,再访问树的第二层结点…一直到访问到最下面一层结点。
- 位运算
- 左移运算符:m<<n表示把m左移n位,最左边的n位将被丢弃,同时在最右边补上n个0。
- 右移运算符:m>>n表示把m右移n位,最右边的n位将被丢弃,如果数字是无符号的,则用0填补最左边的n位;如果是个有符号的数值,则用数字的符号位填补最左边的n位。
- 把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。(用于计算一个整数的二进制中含有多少个1)
- C++中,成员变量的初始化顺序只与他们在类中声明的顺序有关,而与在初始化列表中的顺序无关。
- 正整数的最大值0x7FFF FFFF,最小的负整数是0x8000 0000。
- 右移运算符可以代替除以2(num>>2)。位于运算符可以代替求余运算符(%)来判断一个数是奇数还是偶数。(num & 0x1 == 1)