首页 > 代码库 > 牛客网刷题知识汇总2

牛客网刷题知识汇总2

构造函数不能声明为虚函数,析构函数可以声明为虚函数,且有时候必须声明为虚函数。构造函数和析构函数都不能调用虚函数。
先析构子类再析构父类,如果父类析构函数有虚函数,会导致调用子类的已经析构的内容。
先构造父亲类再构造子类,如果父类构造函数有虚函数,会导致调用子类还没构造的内容。
A:构造函数不能声明为虚函数的原因是: 

1 构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功。编译器无法知道对象 的实际类型,是该类本身,还是该类的一个派生类,或是更深层次的派生类。无法确定。。。

2 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化工作,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表还没有被初 始化,将无法进行。
 
new int(12)是生成了一个值为12的int变量,new int[12]才是生成一个大小为12的数组。对基本类型数组来说,delete a和delete []a的效果是一样的。如果,a是一个自定义对象的数组,那么只能用delete []a。
 
 
1) malloc 函数: void *malloc(unsigned int size)

     在内存的动态分配区域中分配一个长度为size的连续空间,如果分配成功,则返回所分配内存空间的首地址,否则返回NULL,申请的内存不会进行初始化。

2)calloc 函数: void *calloc(unsigned int num, unsigned int size)

     按照所给的数据个数和数据类型所占字节数,分配一个 num * size 连续的空间。

    calloc申请内存空间后,会自动初始化内存空间为 0,但是malloc不会进行初始化,其内存空间存储的是一些随机数据。 
 3)realloc 函数: void *realloc(void *ptr, unsigned int size)

    动态分配一个长度为size的内存空间,并把内存空间的首地址赋值给ptr,把ptr内存空间调整为size。

    申请的内存空间不会进行初始化。
4)new是动态分配内存的运算符,自动计算需要分配的空间,在分配类类型的内存空间时,同时调用类的构造函数,对内存空间进行初始化,即完成类的初始化工作。动态分配内置类型是否自动初始化取决于变量定义的位置,在函数体外定义的变量都初始化为0,在函数体内定义的内置类型变量都不进行初始化。
 
假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?
#include <stdio.h>
int main(){
  long long a = 1, b = 2, c = 3; 
  printf("%d %d %d\n", a, b, c);  
 return 0;
}1,0,2

技术分享
 
注:
1 printf()是一个库函数,C,C++中函数的参数是从右往左入栈的;
2 栈的生长方向是从高往低的(important)
3 小端模式是低位存储在低字节
4 %d格式输出的是4个字节大小,而long long为8个字节
 
Linux crontab中* * * * * /usr/local/run.sh这句话5个*号分别代表什么?
*  *  *  *  *  command 
分  时  日 月  周    命令 
第1列表示分钟1~59 每分钟用*或者 */1表示 
第2列表示小时1~23(0表示0点) 
第3列表示日期1~31 
第4列表示月份1~12 
第5列标识号星期0~6(0表示星期天) 
第6列要运行的命令 


不算main这个进程自身,到底创建了多少个进程啊?

int main(int argc, char* argv[])

{
   fork();
   fork() && fork() || fork();
   fork();
}19
fork()是一个分叉函数, 返回值: 若成功调用一次则返回两个值,子进程返回0,父进程   返回子进程标记;否则,出错返回-1
每一次fork()就翻倍;
第一条和第三条分别X2;关键在第二条语句。第二条有 5个分支;
A&&B||C
   A为假,跳过B,判断C----------------------1
   A为真,判断B,若B为真,跳过C-----------2
                          若B为假,判断C  ------------2
故总数为2*(2+1+2)*2=10;减去自己就是19.
 
Linux下多少个"-"将被打印:
int main(void){
  int i;
  for(i=0;i<4;i++){
  fork();
  printf("-\n");
 }
 return 0;
}30
fork的题可以按以下公式来算。
主进程1分为2,每个子进程1分为2,构成一个二叉树,树高等于循环的次数n。最后一层是最后得到的子进程数,它是偶数,等于2^n,本题应该是求fork次数的2倍。子结点中没有执行fork,但执行了一次打印。每个进程每次循环中只会打印一次。另外,这个树的层次是4,最后一层的结点数等于上面所有层的节点数+1
 
SUBSEP为数组下标的分隔符,预设值为“\034”,awk中的数组只接受字串当它的数组下标,awk在接受Arr[2,79]之前,就已将其下标转成字串“2\03479”,之后变便以Arr["2\03479"]代替Arr[2,79]。
 
挂载设备使用mount,卸载设备使用umount,有三种方式,通过设备名,挂载点或者设备名和挂载点
如题目所示:
umount /dev/hdc
umount /mnt/cdrom
umount /mnt/cdrom /dev/hdc
 要创建一个 tar 文件,键入:tar -cvf filename.tar directory/file
(1)从静态存储区域分配:
内存在程序编译时就已经分配好,这块内存在程序的整个运行期间都存在。速度快、不容易出错,因为有系统会善后。例如全局变量,static变量等。
(2)在栈上分配:
在执行函数时,函数内局部变量的存储单元都在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3)从堆上分配:
即动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活。如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,另外频繁地分配和释放不同大小的堆空间将会产生堆内碎块。
 
局部变量存放在栈中,堆中存放的是new和malloc开辟出的,而程序中定义的常量存放在只读存储区
 
自由时差,简称FF(Free Float),指一项工作在不影响其紧后工作最早开始时间的条件下,本工作可以利用的机动时间。
总时差TF(Total Float )指一项工作在不影响总工期的前提下所具有的机动时间,即用最迟完成时间与最早完成时间之差
 
纯虚函数是在基类声明的虚函数,它在基类中没有定义,但是要求派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后面添加“=0” 
比如 virtual void f()=0;
而c++中包含纯虚函数的类称为抽象类,由于抽象类中包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
总结:1.抽象类只能用作其他类的基类,不能定义抽象类的对象。
2.抽象类不能用于参数类型、函数返回值或显示转换的类型
3.抽象类可以定义抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性
 
int main()
{
    bool first=true;
    int sum=0;
    int value;
    unsigned short i=0xFFFF;
    for (;i>=0;--i)
    {
        if (first)
        {
            value=http://www.mamicode.com/65536;
            sum+=value%3;
            first=false;
        }
        else{
            sum+=--value%3;
            if (value<=0)
            {
                cout<<sum<<","<<i;
                break;
            }
        }
    }
    return 0;
65536,65535
由于i是无符号数,因此 i>=0恒成立,代码停止条件为value<=0。另外注意,--的优先级高于%。
 
char* s1 = "Hello world";
char s2[] = "Hello world";
s1[2] = ‘E‘;     // 1
s2[2] = ‘E‘;     // 2
*(s1 + 2) = ‘E‘;  // 3
*(s2 + 2) = ‘E‘;  // 4
1,3非法。
dynamic_cast将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 即会作一定的判断。 对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针; 对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 
reinterpret_cast这个转换是最“不安全”的,两个没有任何关系的类指针之间转换都可以用这个转换实现。
static_cast静态转换是最接近于C风格转换,很多时候都需要程序员自身去判断转换是否安全。
const_cast这个转换好理解,可以将常量转成非常量。

牛客网刷题知识汇总2