C++面试题总结1

本文详细探讨了C++及嵌入式系统的关键概念和技术细节,包括static关键字的用途、引用与指针的区别、实时系统特性、平衡二叉树的概念、堆栈溢出的原因等,还涉及到了网络编程的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内容摘要:

1.static有什么用途?(请至少说明两种)
    1)
在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
    2)
在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
    3)
在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用

2.引用与指针有什么区别?
    1)
引用必须被初始化,指针不必。
    2)
引用初始化以后不能被改变,指针可以改变所指的对象。
    3)
不存在指向空值的引用,但是存在指向空值的指针。

3.描述实时系统的基本特性
      
在特定时间内完成特定的任务,实时性与可靠性。

4.全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
     
全局变量储存在静态数据库,局部变量在堆栈。

5.什么是平衡二叉树?
     
左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于1

6.堆栈溢出一般是由什么原因导致的?
     
没有回收垃圾资源。

7.什么函数不能声明为虚函数?
     
构造函数不能声明为虚函数。

8.冒泡排序算法的时间复杂度是什么?
     
时间复杂度是O(n^2)

9.写出float x零值比较的if语句。
      if(x>0.000001&&x<-0.000001)

10.Internet采用哪种网络协议?该协议的主要层次结构?
      Tcp/Ip
协议
     
主要层次结构为:应用层/传输层/网络层/数据链路层/物理层。

11.Internet物理地址和IP地址转换采用什么协议?
      ARP (Address Resolution Protocol)
(地址解析協議)

12.IP地址的编码分为哪俩部分?
     IP
地址由两部分组成,网络号和主机号。不过是要和子网掩码按位与上之后才能区分哪些是网络位哪些是主机位。

13.用户输入M,N值,从1N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。
    
循环链表,用取余操作做


14.
不能做switch()的参数类型是:
     switch
的参数不能为实型。

15. C++程序由类和函数组成,模板也分为类模板(class template)和函数模板(function template).
   
函数模板与模板函数的区别是:函数模板是模板的定义,定义中用到通用类型参数.模板函数是实实在在的函数定义,它由编译系统在遇到具体函数调用时所生成,具有程序代码.
   
同样,在说明了一个类模板后,可以创建类模板的实例,即生成模板类

16.纯虚函数如何定义?使用时应注意什么?
virtual void f()=0;
是接口,子类必须要实现

17..数组和链表的区别
数组:数据顺序存储,固定大小
连表:数据可以随机存储,大小可动态改变

18. ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?
应用层
表示层
会话层
运输层
网络层
物理链路层
物理层
tcp /udp
属于运输层
TCP
服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。
TCP 不同, UDP 并不提供对 IP协议的可靠机制、流控制以及错误恢复功能等。由于 UDP比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。
tcp:
提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好
udp:
不提供稳定的服务,包头小,开销小

19. 已知一个数组table,用一个宏定义,求出数据的元素个数
#define NTBL
#define NTBL (sizeof(table)/sizeof(table[0]))

20. 线程与进程的区别和联系?线程是否具有相同的堆栈? dll是否有独立的堆栈?
进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。

每个线程有自己的堆栈。
DLL
中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行,只有线程拥有堆栈,如果DLL中的代码是EXE中的线程所调用,那么这个时候是不是说这个DLL没有自己独立的堆栈?如果DLL中的代码是由DLL自己创建的线程所执行,那么是不是说DLL有独立的堆栈?

以上讲的是堆栈,如果对于堆来说,每个DLL有自己的堆,所以如果是从DLL中动态分配的内存,最好是从DLL中删除,如果你从DLL中分配内存,然后在EXE中,或者另外一个DLL中删除,很有可能导致程序崩溃

21.关键字const是什么含意?
我只要一听到被面试者说:“const意味着常数,我就知道我正在和一个业余者打交道。只要能说出const意味着只读就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:
1).
关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
2).
通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
3).
合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

22. 关键字volatile有什么含意并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1).
并行设备的硬件寄存器(如:状态寄存器)
2).
一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3).
多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1).
一个参数既可以是const还可以是volatile吗?解释为什么。
2).
一个指针可以是volatile吗?解释为什么。
3).
下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1).
是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2).
是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3).
这段代码的有个恶作剧。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此ab可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}

23、语句for(1 )有什么问题?它是什么意思?
、和while(1)相同。

24do……whilewhile……do有什么区别?
、前一个循环一遍再判断,后一个判断以后再循环

25.队列和栈有什么区别?
、队列先进先出,栈后进先出

26. 对于一个频繁使用的短小函数,C语言中应用什么实现,C++中应用什么实现?
c用宏定义,c++inline

27. 用两个栈实现一个队列的功能?要求给出算法和思路!
、设2个栈为A,B,一开始均为空.
入队:
将新元素push入栈A;
出队:
(1)
判断栈B是否为空;
(2)
如果不为空,则将栈A中所有元素依次pop出并push到栈B
(3)
将栈B的栈顶元素pop出;
这样实现的队列入队和出队的平摊复杂度都还是O(1),比上面的几种方法要好。
28.
c语言库函数中将一个字符转换成整型的函数是atool()吗,这个函数的原型是什么?
、函数名: atol 
:把字符串转换成长整型数 
: longatol(const char *nptr); 
程序例
include 
include 
int main(void) 

long l; 
char *str = "98765432";
l = atol(lstr); 
printf("string = %s integer = %ld\n", str, l); 
return(0); 
}

30.局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函

数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内
31
、如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,

那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错
32
、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错

33. 直接链接两个信令点的一组链路称作什么?
PPP
点到点连接

34. Heapstack的差别。
Heap
是堆,stack是栈。
Stack
的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。
Stack
空间有限,Heap是很大的自由存储区
C
中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行

35const define的区别关键回答出const编译时进行安全类型检查。
两者都可以定义常量,有专门的调试工具对const常量进行调试,宏常量没调试工具

36:分配内存时为什么内存不会重叠,地址分配是相对还是绝对的,这个我也说不清哦
内存地址是唯一的,逻辑地址和物理地址是不同的,内存不会重叠,
可能扯上:程序中内存分配有静态分配(全局变量,静态常量,编译时就分配好了);动态分配(用malloc,new分配);
栈上分配(局部变量);还有代码段。

37postmessage把消息发送到消息队列就返回,sendmessage把消息发送到消息队列处理完之后返回(许多人不知道哦,我未毕业面试时在这个问题上挂了次,后来又有次把它们说反了)

38:通讯方式有:信号,信号量,消息队列,共享内存
同步方法:信号量,互斥量,事件,临界区(这几个区别?金山把我问趴了,如果你用过就应该清楚使用过程,可爱的金山没了)

39C++socketJava的差不多,服务端:建立一个ServerSocket对象(server不是sever),之后注册一个监听类(不知道这说错了没啊),用accept()方法接收客户端请求;客户端:建立一个Socket对象,用send()方法发送数据。(应届生说错了末怪)

40:比如一个按钮按下,就发送一条消息,消息发送到消息队列,消息循环从消息队列中取出消息分发到对应的窗口,由窗口函数处理。
(由窗口函数处理不知道错了没)
个人说法,错了末叫,网上书上有的的答案。(回答了上面6个问题那公司就叫我去报道了。对了他首先问的是:你的C++基础扎不扎实?扎实)

41. strcpy的根本区别? C++:memset,memcpy 
#include "memory.h"
memset
用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ '‘\0';例:chara[100];memset(a, '\0', sizeof(a));
memcpy
用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:chara[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
strcpy
就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:chara[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。
strcpy 
原型:extern char *strcpy(char *dest,char *src); 
用法:#include 
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:srcdest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
memcpy 
原型:extern void *memcpy(void *dest, void *src, unsigned intcount);
用法:#include 
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:srcdest所指内存区域不能重叠,函数返回指向dest的指针。
Memset
原型:extern void *memset(void *buffer, char c, int count);
用法:#include 
功能:把buffer所指内存区域的前count个字节设置成字符c
说明:返回指向buffer的指针。

42. 是干什么用的ASSERT()
ASSERT()
是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0),程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:
...... 
ASSERT( n != 0); 
k = 10/ n; 
...... 
ASSERT
只有在Debug版本中才有效,如果编译为Release版本则被忽略。 
assert()
的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。 

43 "pause");系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。"省去了使用getchar();system

44. 请问C++的类和C里面的struct有什么区别?
c++
中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有 

45. 请讲一讲析构函数和虚函数的用法和作用?
析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。知识在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另:析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,虚拟函数的功能是使子类可以用同名的函数对父类函数进行重载,并且在调用时自动调用子类重载函数,如果是纯虚函数,则纯粹是为了在子类重载时有个统一的命名而已。

46.请你详细的解释一下 IP 协议的定义,在哪个层上面,主要有什么作用? TCP  UDP 呢?

UDP  TCP 在传输层, IP 在网络层, TCP/IP 是英文 Transmission Control Protocol/InternetProtocol 的缩写,意思是 "传输控制协议 / 网际协议 "  TCP/IP 协议组之所以流行,部分原因是因为它可以用在各种各样的信道和底层协议(例如 T1 X.25 、以太网以及 RS-232 串行接口)之上。确切地说, TCP/IP 协议是一组包括 TCP 协议和 IP 协议, UDP  User Datagram Protocol )协议、 ICMP  Internet Control Message Protocol )协议和其他一些协议的协议组。 TCP/IP 协议并不完全符合 OSI 的七层参考模型。传统的开放式系统互连参考模型,是一种通信协议的 7 层抽象的参考模型 , 其中每一层执行某一特定任务。该模型的目的是使各种硬件在相同的层次上相互通信。这 7 层是 : 物理层、数据链路层、网路层、传输层、话路层、表示层和应用层。而 TCP/IP 通讯协议采用了 4 层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。这 4层分别为:

应用层 :应用程序间沟通的层,如简单电子邮件传输( SMTP )、文件传输协议( FTP )、网络远程访问协议( Telnet )等。

传输层 :在此层中,它提供了节点间的数据传送服务,如传输控制协议( TCP )、用户数据报协议( UDP )等, TCP UDP 给数据包加入传输数据并把它传输到下一层中,这一层负责传送数据,并且确定数据已被送达并接收。

互连网络层 :负责提供基本的数据封包传送功能,让每一块数据包都能够到达目的主机(但不检查是否被正确接收),如网际协议( IP )。

网络接口层 :对实际的网络媒体的管理,定义如何使用实际网络(如 Ethernet  Serial Line 等)来传送数据。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值