牛客网中c++题目及其知识点详解

来源:互联网 发布:tensorflow可视化界面 编辑:程序博客网 时间:2024/06/01 07:31

1.下面描述正确的是
1
2
int*p1 = newint[10]; 
int*p2 = newint[10]();
p1和p2申请的空间里面的值都是随机值
p1和p2申请的空间里的值都已经初始化
p1申请的空间里的值是随机值,p2申请的空间里的值已经初始化
p1申请的空间里的值已经初始化,p2申请的空间里的值是随机值
解析:c++ primier plus (第六版)104,320页的讨论: 使用new来创建动态数组,意味着数组是在程序运行时创建的,在程序运行时确定数组的长度,而不是在编写程序时指定数组的长度.。默认情况下,动态分配的对象是无名的未初始化的(即生成随机值,相当于调用默认构造函数):

int *pi=new int ;//pi指向一个未初始化的对象,对象类型为int 

int  pi=new int [10];//10个未初始化的对象

如果要为内置的标量类型(如int 或double)分配存储空间合并初始化,可在类型名后面加上初始值,并将其用括号括起:
int*pi=new int (6);//*pi初始化为6

int*pi=new int [10]();//10个值初始化为0的int型对象。

2.

enumstring{    
    x1,    
    x2,    
    x3=10,    
    x4,    
    x5,    
} x;
函数外部访问x等于什么?


解析:如果是函数外定义那么是0
如果是函数内定义,那么是随机值,因为没有初始化

3.

1
2
3
4
unsigned char*p1;
unsigned long*p2;
p1=(unsigned char*)0x801000;
p2=(unsigned long*)0x810000;
请问p1+5= 什么?
p2+5= 什么?

801005   810005
801010   810014
801005   810014
801010  810015
解析:注意是16进制,一个unsigned long占4个字节,指针是跳类型不是跳字节的,所以跳5就是偏移4*5=20个字节,16进制14,加上段地址0x810000就是0x810014.

4.在32位机器中,如下代码:

1
2
3
4
5
6
7
8
9
voidexample(characWelcome[]){
    printf("%d",sizeof(acWelcome));
    return;
}
voidmain(){
    characWelcome[]="Welcome to Huawei Test";
    example(acWelcome);
    return;
}
的输出是?

0
4
23
24
解析:32位机器上, 任何指针变量都只占4个字节。 64位机器则是8个字节。

一般情况下:int a[50];  //sizeof(a)=4*50=200; 求数组所占的空间大小

int *a = new int[50]; // sizeof(a)=4; a为一个指针,sizeof(a)是求指针的大小,在32位系统中,当然是占4个字节。
但是,数组名作为函数参数传递时,c++中不允许隐式的数组拷贝,数组名退化成指针,传递过去的其实是数组的首地址,因此正确答案为4
5.下面关于虚函数和函数重载的叙述不正确的是
虚函数不是类的成员函数
虚函数实现了C++的多态性
函数重载允许非成员函数,而虚函数则不行
函数重载的调用根据参数的个数、序列来确定,而虚函数依据对象确定
解析:虚函数必须是类的成员函数,但是重载不一定是类的成员函数。
6.下面程序运行后的结果为:
1
2
3
4
5
6
7
charstr[] = "glad to test something";
char*p = str;
p++;
int*p1 = reinterpret_cast<int*>(p);
p1++;
p = reinterpret_cast<char*>(p1); 
printf("result is %s\n", p);

result is glad to test something
result is ad to test something
result is test something
result is to test something
解析:我们现在大多电脑内存32位,指针是指向内存地址的,也就是所无论什么类型的指针sizeof()都是32位,4个字节。
但是不同类型的指针的作用是想着指向一个数据,如果++,指向下一个数据,那么此时地址的++肯定就是加相应类型的长度,所以这里有char的加的是一个字节,int的加的是4个字节。
开始p指向“ glad to test something”中的g,然后p++,指向l
int *p1 = static_cast(p); 把p赋值给int型了
p1++,即加了4个相应类型的长度。即p1指向“glad to test something”中的to 't'
p = static_cast(p1); 把p1的转回了p,p指向了“ glad to test something”中的to 't'
输出从to 't'开始
to test something
7.
设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?
1
2
3
4
5
6
7
8
C c;
voidmain()
{
    A*pa=newA();
    B b;
    staticD d;
    delete pa;
}
A B C D
A B D C
A C D B
A C B D
解析:这道题主要考察的知识点是 :全局变量,静态局部变量,局部变量空间的堆分配和栈分配
其中全局变量和静态局部变量是从静态存储区中划分的空间,二者的区别在于作用域的不同,全局变量作用域大于静态局部变量(只用于声明它的函数中),
而之所以是先释放 D 在释放 C的原因是, 程序中首先调用的是 C的构造函数,然后调用的是 D 的构造函数,析构函数的调用与构造函数的调用顺序刚好相反。
局部变量A 是通过 new 从系统的堆空间中分配的,程序运行结束之后,系统是不会自动回收分配给它的空间的,需要程序员手动调用 delete 来释放。
局部变量 B 对象的空间来自于系统的栈空间,在该方法执行结束就会由系统自动通过调用析构方法将其空间释放。
之所以是 先 A  后 B 是因为,B 是在函数执行到 结尾 "}" 的时候才调用析构函数, 而语句 delete a ; 位于函数结尾 "}" 之前。
8.
写出下列程序的运行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "stdio.h"
intsum(inta)
{
    auto intc = 0;
    staticintb = 3;
    c += 1;
    b += 2;
    return(a + b + c);
}
intmain()
{
    inti;
    inta = 2;
    for(i = 0; i < 5; i++) 
    
        printf("%d,", sum(a)); 
    
6,8,10,12,14,
8,10,12,14,16,
10,12,14,16,18
12,14,16,18,20

解析:变量b声明为static静态全局变量,所以它的作用域是全局作用域,每次调用sum函数都会累加2
9.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<iostream>
using namespace std;
classMyClass
{
public:
    MyClass(inti = 0)
    {
        cout << i;
    }
    MyClass(constMyClass &x)
    {
        cout << 2;
    }
    MyClass &operator=(constMyClass &x)
    {
        cout << 3;
        return*this;
    }
    ~MyClass()
    {
        cout << 4;
    }
};
intmain()
{
    MyClass obj1(1), obj2(2);
    MyClass obj3 = obj1;
    return0;
}
运行时的输出结果是()
11214444
11314444
122444
123444
解析:C MyClass obj3 = obj1;
obj3还不存在,所以调用拷贝构造函数输出2
如果obj3存在,obj3=obj,则调用复制运算符重载函数,输出3