牛客 C++刷题day24

1:include “X.h” 和include <<X.h>>的区别

双引号:搜索用户所在目录;如果找不到,搜系统指定的目录
尖括号:仅仅搜索系统指定目录
2:多态性总结
(编译时)静态:函数重载、运算符重载、模板实现
(运行时)动态:虚函数实现
3:局部静态变量的说明
static初始化一次,使得函数结束时局部变量x不被释放,下一次使用函数时x使用上次的值
此外局部变量会覆盖全局变量
4 auto和register
局部变量也叫自动变量 在函数里定义int a也就是auto int a a的作用域只在这个函数里 为了节省内存空间,优化性能,编译器通常会将一次性使用的变量分配在栈上(先进后出,生命周期结束就出栈)。这样执行不同的函数的时候就会在一个栈上进行出入栈操作,更高效的利用内存。 一个变量用register来修饰,就意味着该变量会作为一个寄存器变量,让该变量的访问速度达到最快。一个程序逻辑中有一个很大的循环,循环中有几个变量要频繁进行操作,这些变量可以声明为register类型。
5 虚函数表在编译阶段就确定了,而类对象的虚函数指针vptr是在运行阶段确定的,这是实现多态的关键。并且如果一个类不初始化,任何定义的虚函数是无效的。
6:dynamic_cast的说明
dynamic_cast<>用于C++类继承多态间的转换,分为:
1.子类向基类的向上转型(Up Cast)
2.基类向子类的向下转型(Down Cast)
其中向上转型不需要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,dynamic_cast向上转型其总是肯定成功的。
 
而向下转换时要特别注意:dynamic_cast操作符,将基类类型的指针或引用安全的转换为派生类的指针或引用。dynamic_cast将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理。这也是dynamic_cast与其他转换不同的地方,dynamic_cast涉及运行时类别检查,如果绑定到引用或指针的对象不是目标类型的对象,则dynamic_cast失败。如果是指针类型失败,则dynamic_cast的返回结果为0,如果是引用类型的失败,则抛出一个bad_cast错误。
注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。因为dynamic_cast运行时需要检查RTTI信息。只有带虚函数的类运行时才会检查RTTI。
7:转义字符的说明
'\0'转义字符空字符;'\xhh' 十六进制转义字符(h为0-F),如'\x41'表示字符'A',ASCII码65;'\ddd'八进制转义字符(d为0-7),如'\063'表示字符'3',ASCII码51;'\a'转义字符007;'\b'转义字符退格;'\c'非转义字符。以上为转义字符,告诉编译器需要用特殊的方式进行处理。——————————————————————C/C++规定,16进制数必须以 0x开头。比如 0x1表示一个16进制数,对应的十进制等于1。另外如:0xff,0xFF,0X102A,等,x不区分大小写(0x中的0是数字0,而不是字母O)。八进制以英文字母o开头,在c语言里不分大小写,即o与O等价。这两者为数字,用于表示十六进制数和八进制数。
8:关于用户标识符的定义

除了关键字以外的单词串都可以定义成标识符。define不是关键

字,所以可以把define定义成标识符,但if是关键字,所以不能定义成标识符。

9:STL灵魂大拷问
A:“很多程序员希望STL实现是完全线程安全的“。所以不安全。
B:vector的存在可以使开发者不必关心内存的申请和释放。但是,vector的一个缺点就是它的内存分配是按照2的倍数分配内存的。
C:错误。要知道 std::sort 不是稳定的排序算法,它不保证“相等”元素的相对位置,使用 std::stable_sort 来保证这一点
D:STL的容器可以分为以下几个大类: 
一:序列容器, 有vector, list, deque, string.
二 : 关联容器,     有set, multiset, map, mulmap, hash_set, hash_map, hash_multiset, hash_multimap
三: 其他的杂项: stack, queue, valarray, bitset
E:正确。堆栈是一个线性表,插入删除操作都在一端进行,deque是先进先出的,操作原理和stack是一样的
10.内存缺页指的是我们访问某页时却发现不在,需要从硬盘中调入的情况,而淘汰则指的是页面满了,而我们又需要调入一个新的页面的情况。
11.类的静态成员不属于类的对象,而是整个类共有的,并且类的大小是不计入静态变量的,毕竟static变量根本就不存在于类对象的体内。所以也就无从谈起占用空间了。
12.fork()给子进程返回一个零值,而给父进程返回一个非零值;
13.递归求全排列
void run(int n) {
  int i;
  if (N - 1 == n) {
    dump();
    count ++;
    return;
  }
  for (i = __n_; i < N; i++) {
    swap(__n_, i); //从n到N-1依次和n交换
    run(n + 1);   //递归求解从n+1到N的全排列
    swap(__n_, i);   //n和i又换回来 又是另一种排列
  }
}
14.非常量引用必须是左值


左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。
在标准C++语言中,临时量(术语为右值,因其出现在赋值表达式的右边)可以被传给函数,但只能被接受为const &类型。

函数形式参数是临时量,是右值。所以只能被接受为const &类型 。
15.C语言中数组越界不会报错卧槽。这语言也太坑了吧
16.
struct mybitfields
{
    unsigned short a : 4;
    unsigned short b : 5;
    unsigned short c : 7;
} test
形如这样的语句就是指分别给a,b,c赋予4,5,7位的空间。
这一点一定不要记错了
15.关于派生类的说明:
派生访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没什么影响。对基类成员的访问权限只与基类中的访问说明符有关。”“派生类访问说明符的目的是控制派生类用户对于基类成员的访问权限。”
可见,即使是private继承,派生类成员也是可以访问基类的public和protected成员的,只是这些成员在派生类里都为private性质的(就好像普通的类成员可以访问自己类里的私有成员一样),而派生类构造的对象不能访问(就好像在类外访问类中的私有成员)。
16.关于const的一些解释
const修饰的常量值具有不可变性,c++编译器通常会对该变量做优化处理,在编译时变量i的值为已知的,编译器直接将printf输出的变量i替换为0。尽管如此,编译器仍然会为变量i分配存储空间,通过修改内存的hack方式将变量i在内存中的值修改后并不影响printf的输出。
如果将i更改为volatile const int类型的,编译器就不会对变量i做优化,printf输出的结果就为1。
其实这也跟编译器有关,有的会直接把const当作宏定义来处理。
17.关于fclose函数的说明:
如果正常关例了文件,则函数返回值为0;否则,返回值为非0。
18.main函数的参数的说明
C编译器允许main()函数没有参数,或者有两个参数(有些实现允许更多的参数,但这只是对标准的扩展)。这两个参数,一个是int类型,一个是字符串类型。第一个参数是命令行中的字符串数。第二个参数是一个指向字符串的指针数组。
命令行中的每个字符串被存储到内存中,并且分配一个指针指向它。按照惯例,这个指针数组被称为argv(argument value)。系统使用空格把各个字符串格开。一般情况下,把程序本身的名字赋值给argv[0],接着,把参数第一个字符串赋给argv[1]
19.带参数的构造函数也可以是默认构造函数,只要所有参数都有默认值.函数声明和定义不能都有默认值。会报错的。
posted @ 2019-09-26 11:59  Tonarinototoro  阅读(122)  评论(0编辑  收藏  举报