1.指针占几个字节?
记得这道题是在腾讯实习生面试的第一道题,当时我脱口而出就是8个字节,但是人家接着又问为什么是8个字节呢,我觉得我就蒙了。其实以前学C语言的时候就搞懂了这个问题,时间长了又忘了。因为指针里面存放的事指向元素的地址,所以地址占几个字节,指针就占几个字节。地址占几个字节当然跟操作系统有关系了,想想为什么32位系统为什么用不了4G的内存,就是因为寻址空间不够嘛,人家地址只有32位,2的32次方还没4G大呢。所以应该是32位系统是4个字节,64位系统占8个字节。
2.分离式编译
最近就在看C++ Primer这本书,因为当初看这个就有点看不懂,最后看网上的资料才看的有点懂。
这是一个例子。
//---------------test.h-------------------//
void f();//
这里声明一个函数f
//---------------test.cpp--------------//
#include”test.h”
void f()
{
…//do something
}
//这里实现出test.h中声明的f函数
//---------------main.cpp--------------//
#include”test.h”
int main()
{
f(); //
调用
f,f具有外部连接类型
}
简单的说就是函数的声明,实现和调用分开来,这样每当别的文件要调用该函数,只要增加一个头文件就行了。对于函数本身来说,修改也只要修改实现函数的那段代码就行,其他什么都不用改。
3.直接初始化和拷贝初始化有什么区别。
直接初始化,就是使用构造函数,定义在申请了对象空间之后如何对各个子空间进行初始赋值,称他们为直接初始化是很贴切的,应为他就是最为普通的初始化,是构建一个完整对象的一个过程——先将空间申请好,然后给各个子空间(数据属性)进行相应的赋值。
复制初始化,特点特别之处在于“复制”二字,核心意义就是,我通过对一个已有对象的完全复制,来构建对象。它的过程可以理解成这样——先申请空间,然后将被复制的对象(空间一样大)的所有内容全部复制过去,就形成了这个对象。所以,要明确,两种初始化的方式,都是一构造函数的形式存在的。区别在于他们的参数方面,复制初始化,表达的就是对一个已有同类型的对象进行复制,那么这种构造函数就应该使用某个对象来进行复制,同时因为,C++参数的传递默认都是值传递,要声明使用引用的方式(要不然就又复制了一次了);并且是const类型的。
相当与两种初始化方式都是调用了构造函数,只不过直接初始化传递的是常量,字面值而拷贝初始化则传递的是对某个变量的一个常量引用。
(1)对于一般的内建类型,这两种初始化基本上没有区别。
int a(5);//直接初始化
int a=5;//复制初始化
int a=int (5);//直接初始化
(2)当用于类类型对象时,初始化的复制形式和直接形式有所不同:直接初始化直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始化首先使用指定构造函数创建一个临时对象,然后使用复制构造函数将那个临时对象复制到正在创建的对象。
比如string null_book = "9-999-99999-9 ";
就是拷贝初始化的一个例子。编译器先临时创建一个变量,然后使用复制构造函数将那个临时对象复制到正在创建的对象。
对于复制初始化,最显示的调用手段就是使用“=”符号(这个时候应该成为复制初始化符号)。那么还有许多地方是隐式的调用。如参数传递时,函数返回时,初始化容器时!
1)对于参数传递:我们知道除非是引用参数,否则就是一个使用上层对象复制初始化函数参数的过程。
2)对于函数返回值:我们知道除非是引用返回,否则在return的那个语句就是使用函数内的对象,复制初始化一个上层对象(通常是临时的,然后马上有被用于)
3)在某些容器初始化的过程中如:
vect<string> svec(5);
这里的过程就是,先使用string默认构造出一个实例对象,然后使用这个对象,复制初始化其它的元素。这个过程是容器的实现细节,其实从外面看,可以理解为直接初始化。
4)数组初始化,有时候使用这样的语法:
Sales_item primer_eds[]={ string("1231231"),
string("3123123")
}
可知这个过程,就是一个先调用直接初始化生成string,然后继续隐式调用直接初始化生成Sales_item。最后使用复制初始化,给那个数组的各个元素初始化。