习题
一、选择题
static int hot=200;
int &rad=hot;
hot = hot + 100;
cout<< rad << endl;
A、100 B、200 C、300 D、400
1.C
二、
1.const关键字与宏定义的区别是什么?
区别 | 宏定义 | const关键字 |
---|---|---|
发生阶段不一样 | 预处理 | 编译阶段 |
做的事情不一样 | 字符串替换 | 类型安全检查 |
是否分配内存 | 不分配内存 | 分配内存 |
2.malloc的底层实现是怎样的?free是怎么回收内存的?
1)C标准库malloc的底层实现
①使用原理是分离适配
②当要分配一个块时,确定了要分配的块大小时,对适当的空闲链表做首次适配
③当没找到足够大的,就向操作系统请求额外的堆储存器分配一个合适的块(当释放一个块时,我们执行合并,讲空闲块放在空闲链表中)
2)free是怎么回收内存:free(stat)
①若stat为NULL,则不会有任何事情发生
②stat所指的内存将会被回收
③若stat所指向的内存空间已被回收,会发生错误
3.new/delete与malloc/free的区别与联系是什么?
类型 | new/delete | malloc/free |
---|---|---|
区别 | ①newh/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理成员) ②new/delete是C++操作符 ③new/delete等的方式管理内存失败会抛出异常 | ①malloc只能申请原始的堆空间 ②malloc/free只是C/C++里面的标准库函数 ③ malloc/free管理内存失败会返回0 |
联系 | 都是用来申请堆空间,都要成对使用,否则会有内存泄漏,都是动态管理内存的入口 |
4.(面试常考)区分以下概念:内存泄漏、内存溢出、内存踩踏、野指针?
①内存泄漏:分配了内存而没有释放,逐渐耗尽内存资源,导致系统崩溃
②内存越界:向系统申请一块内存,使用的时候超出了申请的范围
③内存踩踏:也是内存重叠,一般在拷贝过程中覆盖了不属于该空间的内容
④内存溢出:想要的内存超出了系统能够提供的
⑤野指针:指向被释放内存或是访问受限内存的指针
5.(面试常考)引用与指针的区别是什么?并且将"引用"作为函数参数有哪些特点?在什么时候需要使用"常引用"?
1)
引用 | 指针 | |
---|---|---|
区别 | ①即变量本身,只是变量的别名,没有分配的内存空间 ②引用在定义时就被初始化,之后无法改变 ③引用可以直接使用 ④对引用使用“sizeof”得到的是变量的大小,对指针使用“sizeof”得到的是变量的地址的大小 ⑤++引用与++指针的效果不一样,例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容 | ①自己有独立的内存空间,存储指针指向的地址 ②指针可以有多级,引用只有一级 ③指针使用时要在前加 * ④指针的对象可以改变 ⑤没有空引用,但有空指针 |
2)讲引用作为函数参数的特点:
对形参操作就是对实参操作,引用作为形参不占额外的内存空间,清晰明了
3)什么时候需要使用“常引用”?
当不想自己传入的实参被改变时
三、写出下面程序的运行结果。
#include <iostream>
using std::cout;
using std::endl;
void f2(int &x, int &y)
{
int z = x;
x = y;
y = z;
}
void f3(int *x, int *y)
{
int z = *x;
*x = *y;
*y = z;
}
int main()
{
int x, y;
x = 10; y = 26;
cout << "x, y = " << x << ", " << y << endl;
f2(x, y);
cout << "x, y = " << x << ", " << y << endl;
f3(&x, &y);
cout << "x, y = " << x << ", " << y << endl;
x++;
y--;
f2(y, x);
cout << "x, y = " << x << ", " << y << endl;
return 0;
}
x,y=10,26
x,y=26,10
x,y=10,26
x,y=25,11
2.以下代码输出的是__?27
int foo(int x,int y)
{
if(x <= 0 ||y <= 0)
return 1;
return 3 * foo(x-1, y/2);
}
cout << foo(3,5) << endl;
输出为27
3.若执行下面的程序时,从键盘上输入5,则输出是(6)
int main(int argc, char** argv)
{
int x;
cin >> x;
if(x++ > 5)
{
cout << x << endl;
}
else
{
cout << x-- << endl;//走的这条路,先曾1为6后打印出来,打印后自减1
}
return 0;
}
4.写出下面程序的结果:5
int main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1); //这里1表示一整个a的数组
printf("%d,%d",*(a+1),*(ptr-1)); //这里1表示减去一个Int类型大小的字节,减一表示往前移位一个int字节
}
四、有段代码写成了下边这样,如果在只修改一个字符的前提下,使代码输出20个hello?
for(int i = 0; i < 20; i--)
cout << "hello" << endl;
for(int i = 0; -i < 20; i--)
cout << "hello" << endl;