C/C++常见面试知识点总结附面试真题

本文详细总结了C/C++编程中常见的面试知识点,包括内存类型、堆栈区别、程序编译过程、负数和浮点数存储、函数调用原理、左值与右值概念、内存管理和指针越界、C与C++差异、宏与内联函数对比、类型转换、静态成员特性和C++特性等。内容深入浅出,适合准备C/C++面试的开发者阅读。
摘要由CSDN通过智能技术生成

第一部分:计算机基础

  1. C/C++内存有哪几种类型?
    C中,内存分为5个区:堆(malloc)、栈(如局部变量、函数参数)、程序代码区(存放二进制代码)、全局/静态存储区(全局变量、static变量)和常量存储区(常量)。此外,C++中有自由存储区(new)一说。
    全局变量、static变量会初始化为零,而堆和栈上的变量是随机的,不确定的。

  2. 堆和栈的区别?
    1).堆存放动态分配的对象——即那些在程序运行时分配的对象,比如局部变量,其生存期由程序控制;
    2).栈用来保存定义在函数内的非static对象,仅在其定义的程序块运行时才存在;
    3).静态内存用来保存static对象,类static数据成员以及定义在任何函数外部的变量,static对象在使用之前分配,程序结束时销毁;
    4).栈和静态内存的对象由编译器自动创建和销毁。

  3. 堆和自由存储区的区别?
    总的来说,堆是C语言和操作系统的术语,是操作系统维护的一块动态分配内存;自由存储是C++中通过new与delete动态分配和释放对象的抽象概念。他们并不是完全一样。
    从技术上来说,堆(heap)是C语言和操作系统的术语。堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,稍后调用free可把内存交还。而自由存储是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区。基本上,所有的C++编译器默认使用堆来实现自由存储,也即是缺省的全局运算符new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确。

  4. 程序编译的过程?
    程序编译的过程中就是将用户的文本形式的源代码(c/c++)转化成计算机可以直接执行的机器代码的过程。主要经过四个过程:预处理、编译、汇编和链接。具体示例如下。
    一个hello.c的c语言程序如下。

#include <stdio.h>
int main()
{
printf(“happy new year!\n”);
return 0;
}
1
2
3
4
5
6
其编译过程如下:

  1. 计算机内部如何存储负数和浮点数?
    负数比较容易,就是通过一个标志位和补码来表示。
    对于浮点类型的数据采用单精度类型(float)和双精度类型(double)来存储,float数据占用32bit,double数据占用64bit,我们在声明一个变量float f= 2.25f的时候,是如何分配内存的呢?如果胡乱分配,那世界岂不是乱套了么,其实不论是float还是double在存储方式上都是遵从IEEE的规范的,float遵从的是IEEE R32.24 ,而double 遵从的是R64.53。更多可以参考浮点数表示。
    无论是单精度还是双精度在存储中都分为三个部分:

1). 符号位(Sign) : 0代表正,1代表为负
2). 指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储
3). 尾数部分(Mantissa):尾数部分
其中float的存储方式如下图所示:

而双精度的存储方式如下图:

  1. 函数调用的过程?
    如下结构的代码,

int main(void)
{

d = fun(a, b, c);
cout<<d<<endl;

return 0;
}
1
2
3
4
5
6
7
8
调用fun()的过程大致如下:

main()========
1).参数拷贝(压栈),注意顺序是从右到左,即c-b-a;
2).保存d = fun(a, b, c)的下一条指令,即cout<<d<<endl(实际上是这条语句对应的汇编指令的起始位置);
3).跳转到fun()函数,注意,到目前为止,这些都是在main()中进行的;
fun()=====
4).移动ebp、esp形成新的栈帧结构;
5).压栈(push)形成临时变量并执行相关操作;
6).return一个值;
7).出栈(pop);
8).恢复main函数的栈帧结构;
9).返回main函数;
main()========
。。。
7. 左值和右值
不是很严谨的来说,左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式)。举例来说我们定义的变量 a 就是一个左值,而malloc返回的就是一个右值。或者左值就是在程序中能够寻值的东西,右值就是一个具体的真实的值或者对象,没法取到它的地址的东西(不完全准确),因此没法对右值进行赋值,但是右值并非是不可修改的,比如自己定义的class, 可以通过它的成员函数来修改右值。

  1. 什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法?你通常采用哪些方法来避免和减少这类错误?
    用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元即为内存泄露。

1). 使用的时候要记得指针的长度.
2). malloc的时候得确定在那里free.
3). 对指针赋值的时候应该注意被赋值指针需要不需要释放.
4). 动态分配内存的指针最好不要再次赋值.
5). 在C++中应该优先考虑使用智能指针.
第二部分:C v.s. C++

  1. C和C++的区别?
    1). C++是C的超集;
    2). C是一个结构化语言,它的重点在于算
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值