手机网站大全免费bing搜索引擎国际版
- 局部变量能否和全局变量重名?
- 可以,局部变量会屏蔽全局变量。在使用全局变量时需要使用 ":: "。
- 拷贝构造函数:参数为同类型的对象的常量引用的构造函数
- 函数指针:int (*f)(int,int) = & max;
- 虚函数:在基类中使用关键字 virtual 声明的函数。
- 虚函数依靠虚指针vptr和虚函数表vtable来处理。vptr是一个指针,在类的构造函数中创建生成,并且只能用this指针来访问它,因为它是类的一个成员,并且vptr指向保存虚函数地址的vtable。如果子类没有定义同名覆盖虚函数,那么他会继承父类的虚函数表(子类和父类共用同一张虚函数表)(共用存疑),子类的虚指针会指向父类的虚函数表。如果子类中只重载了一部分虚函数,没有重载的虚函数的地址也会保存在子类独有的虚函数表中,不过其地址与父类的虚函数表中对应函数的地址相同。
- 虚析构函数:在删除指向子类对象的基类指针时可以调用子类的析构函数而非父类的析构函数以达到释放子类中堆内存的目的,从而防止内存泄露。
- 静态成员函数没有this指针。
- 静态成员不能是虚函数。虚函数在程序运行时,根据实际对象的类型来调用相应的函数。而静态成员函数是不依赖于任何对象的,它不需要通过对象来访问。 静态成员函数没有this指针,所以无法访问vptr. 这就是为何static函数不能为virtual。对于子类中没有重载的虚寒性
- 静态成员不可以访问非静态成员。在类为实例化时,没有具体的对象,也就没有相应的非静态成员存在,
- 静态成员访问非静态成员方法。通过参数传入所在的类的对象。
- const成员函数:函数名前面使用const 表示返回值为const,后面加 const表示函数不可以修改class的成员。后面加 const,传入的this指针为常量指针,不可以通过指针改变其内容。
- 静态成员函数后不用const修饰:静态成员不访问成员变量,后加const修饰无意义。
- 动态多态:(虚函数)对于相关的对象类型,确定它们之间的一个共同功能集,然后在基类中,把这些共同的功能声明为多个公共的虚函数接口。各个子类重写这些虚函数,以完成具体的功能。编译期要执行的具体程序无法确定,要等运行时才能确定。
- 静态多态:模板。编译期执行的程序便被确定。
- 数组作为参数传递给函数或将其赋值给指针时,数组会退化成指针,此时 对其使用
sizeof
将返回指针的大小,而不是数组的大小。 - 字符串char[]的实际长度比其内容长度要+1,因为多一个'\0'。
- 类的声明,会调用默认构造函数。 类指针的声明,不会调用构造函数。
- FILE *fopen(const char *filename, const char *mode);mode:r+:如果文件不存在返回null。从文件头开始写,覆盖的文字最后不加eof,未覆盖的字符保留。w+:当文件不存在则创建文件。从文件头开始写,覆盖的文字最后加eof,原文件将会被清空。
- 方法覆盖:方法的覆盖对返回值的要求是:小于等于父类的返回值。方法的覆盖对访问要求是:大于等于父类的访问权限。
- 只有友元类才可以访问私有成员,别的类都不行(子类也不行)
- 当scanf的输入占用的内存大于参数所指向的内存时,会将地位存入内存。当scanf的输入占用的内存小鱼参数所指向的内存时无影响(高位补充0)。
- 当printf输出的占位符小于七参数所指向的内存时:???
- 32位/64位:CPU位宽(数据总线宽度)。
- 虚拟地址空间的大小由操作系统决定,32位的操作系统虚拟地址空间的大小为 2^32 字节,也就是 4G,64 系统的操作系统虚拟地址空间大小为 2^64 字节。
- int类型在32位和64位操作系统都是4个字节大小,指针在32位操作系统是4个字节,在64位操作系统是8个字节。
- 在虚拟地址模式下,一个程序可以使用的内存容量跟计算机的物理内存(也就是你的内存条)没有关系,它由虚拟地址的取值范围决定。
- 在32位操作系统中,程序能使用的最大内存是 4GB,也就是2的32次方。
- 在64位操作系统中,理论上能够访问的虚拟地址的范围是 2^64。这是一个很大的值,几乎是无限的,就目前的技术来讲,不但物理内存不可能做到这么大,CPU的寻址能力也没有这么大,实现64位长的虚拟地址只会增加系统的复杂度,带不来任何好处。Windows 和 Linux 都对虚拟地址进行了限制,仅使用虚拟地址的低48位(6个字节),总的虚拟地址大小为 2^48 = 256TB。
- 分段机制会把程序的虚拟地址分成 4 个段:段0:代码段。段1:数据段。段2:堆。段3:栈。
- 段页式内存管理:先将程序划分为多个有逻辑意义的段,接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页。地址结构=段号+段内页号+页内位移。每一个程序一张段表,每个段又建立一张页表,段表中的地址是页表的起始地址,而页表中的地址则为某页的物理页号,
- 段页式地址变换中要得到物理地址须经过三次内存访问: 第一次访问段表,得到页表起始地址; 第二次访问页表,得到物理页号; 第三次将物理页号与页内位移组合,得到物理地址。
- 虚拟地址在页表中找不到对应的页表项,计算机系统就不能工作了。所以页表一定要覆盖全部虚拟地址空间。
- 不分级的页表就需要有 100 多万个页表项来映射,而二级分页则只需要 1024 个页表项(此时一级页表覆盖到了全部虚拟地址空间,二级页表在需要时创建)。
- TLB(Translation Lookaside Buffer):通常称为页表缓存、转址旁路缓存、快表CPU 芯片中专门存放程序最常访问的页表项的 Cache。
- 逻辑地址和线性地址: 程序所使用的地址,通常是没被段式内存管理映射的地址,称为逻辑地址; 通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址;
- Linux 系统中的每个段都是从 0 地址开始的整个 4GB 虚拟空间(32 位环境下),也就是所有的段的起始地址都是一样的。这意味着,Linux 系统中的代码,包括操作系统本身的代码和应用程序代码,所面对的地址空间都是线性地址空间(虚拟地址),这种做法相当于屏蔽了处理器中的逻辑地址概念,段只被用于访问控制和内存保护。
- Linux每个进程都各自有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存。
- 用户空间内存,从低到高分别是 7 种不同的内存段: 程序文件段,包括二进制可执行代码; 已初始化数据段,包括静态常量; 未初始化数据段,包括未初始化的静态变量; 堆段,包括动态分配的内存,从低地址开始向上增长; 文件映射段,包括动态库、共享内存等,从低地址开始向上增长(跟硬件和内核版本有关); 栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。当然系统也提供了参数,以便我们自定义大小;
- 每个进程都有自己的虚拟空间,而物理内存只有一个,所以当启用了大量的进程,物理内存必然会很紧张,于是操作系统会通过内存交换技术,把不常使用的内存暂时存放到硬盘(换出),在需要的时候再装载回物理内存(换入)。
- C++不是类型安全的,java和C#是类型安全的
- 如果你只是声明一个空类,不做任何事情的话,编译器会自动为你生成一个默认构造函数、一个拷贝默认构造函数、一个默认拷贝赋值操作符和一个默认析构函数。这些函数只有在第一次被调用时,才会别编译器创建。所有这些函数都是inline和public的。
- inline 函数仅仅是一个对编译器的建议,所以最后能否真正内联,看编译器的意思,它如果认为函数不复杂,能在调用点展开,就会真正内联,并不是说声明了内联就会内联,声明内联只是一个建议而已。
- inline函数的实现:在任何调用内联函数的地方都内联函数的函数体,以避免频繁调用函数对栈内存重复开辟所带来的消耗。内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。 如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
- 关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。
- 析构函数不可以被重载,因为析构函数只能有一个,且不能带参数。
- 类的构造函数一般是共有的(public),但有时也把构造函数声明为私有的(private),其作用是限制其创建该类对象的范围,这时,只能在本类和友元中创建该类对象。
- 对于霍夫曼树来说,其叶结点权值越小,离根越远,叶结点权值越大,离根越近,此外其仅有叶结点的出度为0,其他结点出度均为2。
参考:
-
小林coding 链接:https://www.zhihu.com/question/290504400/answer/1964845950