1、解析下面含义
int *p1 = new int[10];
int *p2 = new int[10]();
答:p1申请的空间里的值是随机值,p2申请的空间里的值已经初始化
对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()
2、下面的程序可以从0....n-1中随机等概率的输出m个不重复的数。这里我们假设n远大于m
knuth(int n, int m)
{
srand((unsigned int)time(0));
for (int i = 0; i < n; i++) {
if ( ) {
cout << i << endl;
( );
}
}
}
答案:rand()%(n-i)<m m--
其实这道题,很有意思,我当时看了老长时间,没有看出来。脑子一直落地到 不重复的数。其中输出的不是m而是i,每一次i的值都是相同,所以这题本身就保证的题目输出不会重复,等概率,其实就和抽签一样,不管你是第几个抽,都是1/签总数。其中m--,控制输出m个数。
3、以下prim函数的功能是分解质因数。括号内的内容应该为?
void prim(int m, int n)
{
if (m >= n)
{
while ( ) n++;
( );
prim(m, n);
cout << n << endl;
}
}
答案: m%n m/=n 这道题想想就出来了
4、函数外部访问x等于什么?
enum string{
x1,
x2,
x3=10,
x4,
x5,
}
答:
如果是函数外定义那么是0
如果是函数内定义,那么是随机值,因为没有初始化
5、sizeof() 测量字节数的大小的方法。
#include<stdio.h>
void example(char acWelcome[]){
printf("acWelcome==%d\n",sizeof(acWelcome));
return;
}
int main(){
char acWelcome[]="Welcome to Huawei Test";
printf("acWelcome==%d\n",sizeof(acWelcome));
example(acWelcome);
char *ss = acWelcome;
printf("ss==%d\n",sizeof(ss));
return 0;
}
输出:
上方是在64位电脑上运行的结果,主函数中sizeof(数组名),测量的是数组中所占内存所有的字节数。char类型占一个字节,数组长度为23,所有主函数中输出acWelcome==23,当传数组名,传的就是一个指针类型,所以测量就是一个指针占的字节数,64机器上一个指针类型占8个字节(32位机器上一个指针类型占4个字节),所以调用函数中acWelcome==8。
6、看代码
unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;
请问p1+5= 什么? p2+5= 什么?
答:801005 810014
首先是先把这两个16进制 0x801000 0x810000,强制转为地址,指针类型,一个强制转化位 字符指针,一个转化为long型指针,解析一下为什么等于这个两个数:
1代表的是一个单位量
p1+5=p1+5*1=p1+5*sizeof(unsigned char)=p1+5*1=0x801000+ox5=0x801005
p2+5=p2+5*1=p2+5*sizeof(unsigned long)=p1+5*4=0x810000+20=0x810000+0x14=0x810014
最后要转换成16进制
{ char每次移动1个字节;short移动2个字节 ;int , long ,float移动4个字节 ;double移动8个字节}
7、虚函数:(1)虚函数是类的成员函数(2)虚函数实现了C++的多态性(3)函数重载允许非成员函数,而虚函数则不行
(4)函数重载的调用根据参数的个数、序列来确定,而虚函数依据对象确定.
多态性分为编译时多态性和运行时多态性,
编译时多态性通过静态编联完成,例如函数重载,运算符重载;
运行时多态性则是动态编联完成,主要通过虚函数来实现;
8、设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?
C c;
void main()
{
A*pa=new A();
B b;
static D d;
delete pa;
}
答案:A B D C
这道题主要考察:内存静态存储区、堆区、栈区。内存分配。
一、内存基本构成
可编程内存在基本上分为这样的几大部分:静态存储区、堆区和栈区。他们的功能不同,对他们使用方式也就不同。
静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。
栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限,如C语言的数组。
堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。
代码区:存放函数体的二进制代码
文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
函数指针指向Code区,是程序运行的指令代码,数据指针指向Data,Heap,Stack区,是程序依赖以运行的各种数据
在文件作用域声明inline函数默认为static存储类型,const常量默认为static存储,如果加上extern,则为外部存储类型。
对应这道题:首先一个个的分析:
对于类A, 是建立在堆上的对象指针pa, 手动释放
对于类B, 是建立在栈上的对象b,main函数结束就释放
对类C ,在静态存储区创建了一个对象c ,程序结束时候释放
对类D,也是在静态存储区建立对象d,但是局部变量,程序结束时候释放.
析构函数调用顺序:
先调用A的析构,因为delete pa . A
再释放栈上的对象b, B
关键看CD的顺序.
c是全局对象,对它的初始化是在main函数之前,所以析构时候要放在最后.
也就是先析构d ,然后再析构c
其实 析构函数的调用与构造函数的调用顺序刚好相反。
9、若char是一字节,int是4字节,指针类型是4字节,代码如下:
class CTest
{
public:
CTest():m_chData(‘\0’),m_nData(0)
{
}
virtual void mem_fun(){}
private:
char m_chData;
int m_nData;
static char s_chData;
};
char CTest::s_chData=’\0’;
问:
(1)若按4字节对齐sizeof(CTest)的值是多少?
(2)若按1字节对齐sizeof(CTest)的值是多少?
请选择正确的答案。
答案:12 9
解析:
10、如下代码输出结果是什么?
#include<stdio.h>
char *myString()
{
char buffer[6] = {0};
char *s = "Hello World!";
for (int i = 0; i < sizeof(buffer) - 1; i++)
{
buffer[i] = *(s + i);
}
return buffer;
}
int main(int argc, char **argv)
{
printf("%s\n", myString());
return 0;
}
输出的是乱码,因为buffer是局部变量,在栈内存中,在函数结束就把内存自动释放掉了,所以,输出的是乱码。
11、函数名赋值于指针的正确形式 void (*pf)(int n,char *s); pf = fun;
做这套题的感悟:我对类、虚函数、重写、重载等一些定理不熟。