C C++面试常问简答题(2)

51.h头文件中的ifndef/define/endif 的作用?

答:防止该头文件被重复引用。

52.#i nclude<file.h> 与 #i nclude "file.h"的区别?

答:前者是从Standard Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。

 

53.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?

C++语言支持函数重载,C语言不支持函数重载。C++提供了C连接交换指定符号extern “C”

解决名字匹配问题。


首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。

通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数

extern "C"是连接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的,来看看C++中对类似C的函数是怎样编译的:


作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:

void foo( int x, int y );
  

该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。

_foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的,后者为_foo_int_float。

同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。

未加extern "C"声明时的连接方式

假设在C++中,模块A的头文件如下:

// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
int foo( int x, int y );
#endif  

在模块B中引用该函数:

// 模块B实现文件 moduleB.cpp
#i nclude "moduleA.h"
foo(2,3);

加extern "C"声明后的编译和连接方式

加extern "C"声明后,模块A的头文件变为:

// 模块A头文件 moduleA.h
#ifndef MODULE_A_H
#define MODULE_A_H
extern "C" int foo( int x, int y );
#endif  

在模块B的实现文件中仍然调用foo( 2,3 ),其结果是:
(1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;

(2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。

如果在模块A中函数声明了foo为extern "C"类型,而模块B中包含的是extern int foo( int x, int y ) ,则模块B找不到模块A中的函数;反之亦然。

所以,可以用一句话概括extern “C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):实现C++与C及其它语言的混合编程。  

明白了C++中extern "C"的设立动机,我们下面来具体分析extern "C"通常的使用技巧:

extern "C"的惯用法

(1)在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:


extern "C"
{
#i nclude "cExample.h"
}

而在C语言的头文件中,对其外部函数只能指定为extern类型,C语言中不支持extern "C"声明,在.c文件中包含了extern "C"时会出现编译语法错误。

C++引用C函数例子工程中包含的三个文件的源代码如下:

/* c语言头文件:cExample.h */
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
extern int add(int x,int y);
#endif


/* c语言实现文件:cExample.c */
#i nclude "cExample.h"
int add( int x, int y )
{
return x + y;
}


// c++实现文件,调用add:cppFile.cpp
extern "C"
{
#i nclude "cExample.h"
}
int main(int argc, char* argv[])
{
add(2,3);
return 0;
}

如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern "C" { }。

(2)在C中引用C++语言中的函数和变量时,C++的头文件需添加extern "C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。

C引用C++函数例子工程中包含的三个文件的源代码如下:

//C++头文件 cppExample.h
#ifndef CPP_EXAMPLE_H
#define CPP_EXAMPLE_H
extern "C" int add( int x, int y );
#endif


//C++实现文件 cppExample.cpp
#i nclude "cppExample.h"
int add( int x, int y )
{
return x + y;
}


/* C实现文件 cFile.c
/* 这样会编译出错:#i nclude "cExample.h" */

int main( int argc, char* argv[] )
{
add( 2, 3 );
return 0;
}

15题目的解答请参考《C++中extern “C”含义深层探索》注解:

几道c笔试题(含参考答案)

1. 
What is displayed when f() is called given the code:
class Number {
public:
string type; 

Number(): type(“void”) { }
explicit Number(short) : type(“short”) { } 
Number(int) : type(“int”) { }
};
void Show(const Number& n) { cout << n.type; }
void f()
{
short s = 42;
Show(s); 
}
a) void
b) short
c) int
d) None of the above

2. Which is the correct output for the following code
double dArray[2] = {4, 8}, *p, *q;
p = &dArray[0];
q = p + 1;
cout << q – p << endl; 
cout << (int)q - (int)p << endl;
a) 1 and 8
b) 8 and 4
c) 4 and 8
d) 8 and 1


第一个选C;
虽然传入的是short类型,但是short类型的构造函数被生命被explicit,也就是只能显示类型转换,不能使用隐式类型转换。
第二个选A;

第一个是指针加减,按照的是指向地址类型的加减,只跟类型位置有关,q和p指向的数据类型以实际数据类型来算差一个位置,因此是1。而第二个加减是实际指针值得加减,在内存中一个double类型占据8个字节,因此是8


55请你分别画出OSI的七层网络结构图和TCP/IP的五层结构图。

应用层:为应用程序提供服务

表示层:处理在两个通信系统中交换信息的表示方式

会话层:负责维护两个结点间会话连接的建立、管理和终止,以及数据交换

传输层:向用户提供可靠的端到端服务。UDP TCP协议。

网络层:通过路由选择算法为分组通过通信子网选择最适当的路径,以及实现拥塞控制、网络互联等功能。数据传输单元是分组。IP地址,路由器,IP协议。

数据链路层:在物理层提供的服务基础上,数据链路层在通信的实体间建立数据链路连接,传输一帧为单位的数据包(,并采用差错控制与流量控制方法,使有差错的物理线路变成无差错的数据链路。)

物理层:传输比特流。传输单元是比特。调制解调器。

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

网络层。

57.请问交换机和路由器各自的实现原理是什么?分别在哪个层次上面实现的?

交换机:数据链路层。路由器:网络层。

58.全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的 ?

 全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。全局变量在main函数调用后,就开始分配,如果是静态变量则是在main函数前就已经初始化了。而局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)

59.8086是多少位的系统?在数据总线上是怎么实现的? 


8086微处理器共有4个16位的段寄存器,在寻址内存单元时,用它们直接或间接地存放段地址。

  代码段寄存器CS:存放当前执行的程序的段地址。

  数据段寄存器DS:存放当前执行的程序所用操作数的段地址。

  堆栈段寄存器SS:存放当前执行的程序所用堆栈的段地址。

  附加段寄存器ES:存放当前执行程序中一个辅助数据段的段地址。

由cs:ip构成指令地址,ss:sp构成堆栈的栈顶地址指针。DS和ES用作数据段和附加段的段地址(段起始地址或段值)

 

8086/8088微处理器的存储器管理

   1.地址线(码)与寻址范围:N条地址线     寻址范围=2N

   2.8086有20地址线     寻址范围为1MB  由 00000H~FFFFFH

   3. 8086微处理器是一个16位结构,用户可用的寄存器均为16位:寻址64KB

   4. 8086/8088采用分段的方法对存储器进行管理。具体做法是:把1MB的存储器空间分成若干段,每段容量为64KB,每段存储器的起始地址必须是一个能被16整除的地址码,即在20位的二进制地址码中最低4位必须是“0”。每个段首地址的高16位二进制代码就是该段的段号(称段基地址)或简称段地址,段号保存在段寄存器中。我们可对段寄存器设置不同的值来使微处理器的存储器访问指向不同的段。

   5.段内的某个存储单元相对于该段段首地址的差值,称为段内偏移地址(也叫偏移量)用16位二进制代码表示。

   6.物理地址是由8086/8088芯片地址引线送出的20位地址码,它用来参加存储器的地址译码,最终读/写所访问的一个特定的存储单元。

   7.逻辑地址由某段的段地址和段内偏移地址(也叫偏移量)两部分所组成。写成:

     段地址:偏移地址(例如,1234H:0088H)。

   8.在硬件上起作用的是物理地址,物理地址=段基地址×10H十偏移地址



联想笔试题 
  1.设计函数 int atoi(char *s)。 
  2.int i=(j=4,k=8,l=16,m=32); printf(“%d”, i); 输出是多少? 

60.解释局部变量、全局变量和静态变量的含义。

 

61.论述含参数的宏与函数的优缺点。 

普天C++笔试题 
  1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。 
  2.写一个函数,将其中的\t都转换成4个空格。

 

61.Windows程序的入口是哪里?写出Windows消息机制的流程。 

 

 

62.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。 
  

4.如何定义和实现一个类的成员函数为回调函数?
5.解释堆和栈的区别。

6.C++里面如何声明const void f(void)函数为C程序中的库函数? 
  7.下列哪两个是等同的 
  int b; 
  A const int* a = &b; 
  B const* int a = &b; 
  C const int* const a = &b; 
  D int const* const a = &b; 
  8.内联函数在编译时是否做参数类型检查? 
  void g(base & b){ 
   b.play; 
  } 
  void main(){ 
   son s; 
   g(s); 
   return; 
  }


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GDB 调试指南

大家好&#xff0c; 好久没给大家带来原创干货了&#xff0c;导致很多新来的小伙伴以为我这个号就是个机构号&#xff0c;其实不是&#xff0c;这个是个人号&#xff0c;背后的小编我是一个有血有肉有情怀的人&#xff0c;不管怎么样&#xff0c;我的目的是尽量带给大家优质的干…

ASP.NET MVC3 异步刷新

ASP.NET MVC3 异步刷新2011-08-13 09:51:53标签&#xff1a;MVC3 异步刷新 休闲 N Layer 职场原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://leelei.blog.51cto.com/856755/638408好久没…

一个反射的妙用案例

今天在工作中遇到一种场景: 一个表格有10个列,要求当点击某列列头时,下拉展示该列的所有数据 解决的常规办法是根据传入的列参数值,判断是哪一列,使用switch()或者if-else判断过滤出哪一列的值 但这个办法太臃肿,如果有100个字段,那这个分支选择就太大了 所以采用反射,你传什么…

常规键盘快捷键

按键 目的 Ctrl A 全选Ctrl B 整理收藏夹Ctrl C 复制Ctrl D 删除/添加收藏Ctrl E 搜索助理Ctrl F 查找Ctrl H 历史记录Ctrl I 收藏夹Ctrl J IE7.0里的源Ctrl L &#xff1d;CtrlO 打开Ctrl M 网页搜索框中的确定&#xff08;等于回车&#xff09;Ctrl N 新窗…

指针和引用的区别和联系

在c的学习中&#xff0c;我们经常被应该如何使用指针和引用这个问题所困扰&#xff0c;那么我这里给大家说一下在我的学习过程中对指针和引用的理解&#xff0c;和它们之间的区别&#xff0c;希望各位朋友给出不同的意见并且指出我在学习中的一些错误首先我们来聊一下指针&…

编译rocksdb源码导致的部署失败

这几天经历了一次心酸的历程&#xff0c;使用了rocksdb第三方库&#xff0c;编译器是7.2&#xff0c;rocksdb是20190701从github上取下来的&#xff0c;由于rocksdb自己的CMakeList.txt中使用了-marchnative编译参数&#xff0c;强制使用了编译代码服务器的cpu指令集&#xff0…

跌倒的收获

有个"渔王"非常苦恼&#xff0c;就因为三个儿子的捕鱼技术都很一般。他常向人诉苦&#xff1a;"我从儿子们刚懂事起就传授技术&#xff0c;怎么他们都比不上平常人的孩子&#xff1f;" 一位路人听后&#xff0c;问&#xff1a;"你一直是手把手地教他们…

检测APK是否混淆

目录 为什么要检测APK是否混淆混淆的优点混淆的缺点APK的混淆的分类检测工具检测人工检测自动化检测为什么要检测APK是否混淆 apk代码混淆就是为了保护代码安全&#xff0c;防止被反编译拿到源码做审计找出危险漏洞&#xff0c;现在大部分的APK都会做混淆。 下面分析混淆APK后的…

基于asp.net的Web开发架构探索(转)

问题由来 最近在研究适合团队开发的web架构解决方案&#xff0c;该架构即要适合分工协作又要有一定扩展性&#xff0c;适合不同的数据库需要&#xff0c;因此我查阅了一些资料&#xff0c;初步构想出了一套架构&#xff0c;请各位多多指教。 探索 web开发架构最经典莫过于三层架…

ubuntu要更新18.04了,lei了lei了~~~

Ubuntu 18.04 LTS将于2018年4月26日发布。开发商现在有六个月的时间来打造“Bionic Beaver 仿生海狸”。 对于那些你不知道Ubuntu 4 &#xff08;xx.04&#xff09;版本遵循27周的时间表&#xff08;而不是10月发行的25周时间表&#xff0c;由于圣诞节和新年的小事情&#xff0…

SkipList 以及高度的确定

转载&#xff1a;https://www.cnblogs.com/lnlvinso/p/8848883.html 结果&#xff1a;skiplist的高度是个随机值。 SkipList理解 记下自己对跳表SkipList的理解。 SkipList采用空间换时间的思想&#xff0c;通过增加数据间的链接&#xff0c;达到加快查找速度的目的。 数据库L…

20个正则表达式,举一反三,相信对你很有用

转载:https://www.cnblogs.com/wxd0108/p/5580772.html 正则表达式经常被用于字段或任意字符串的校验&#xff0c;如下面这段校验基本日期格式的JavaScript代码&#xff1a; var reg /^(\\d{1,4})(-|\\/)(\\d{1,2})\\2(\\d{1,2})$/; var r fieldValue.match(reg); if(rnull)a…

约瑟夫环问题---循环单链表

约瑟夫环问题是比较经典的问题&#xff0c;原来做的题目是依次输出数字&#xff0c;而原来的循环链表结构不改变&#xff0c;今天遇到一道题是要求按照顺序重新组成一个循环单链表。 题目&#xff1a;一些人围坐一圈报数&#xff0c;形成一个循环单链表&#xff0c;当报数是m或…

IIS AppCreate子目录的错误(0x80020006)

这几天做了升级用的安装包,需要在原来的ASP 的虚拟目录下&#xff0c;再创建一个新的ASPNet 虚拟目录。上网查了C# iis设定的资料&#xff0c;按照上面一路做下来&#xff0c;还是无法成功过。 代码只有两行&#xff0c;如下&#xff1a;DirectoryEntry siteVDir new Director…

网络通信TCP协议三次握手

刚刚看linux公社看见里面一个讲TCP的文章&#xff0c;文章讲的很有意思生动形象&#xff0c;很有助于对TCP协议的理解和掌握&#xff0c;所以转载过来方便以后看一下HAHA~~~TCP是什么? TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的、可靠的、 …

聊聊RocksDB Compact

导语 对于 LevelCompact 策略&#xff0c;RocksDB会根据每一层不同的策略计算出CompactScore&#xff0c;根据CompactScore大小来决定那一层将会优先进行Compact&#xff0c;然后选择Level-N 和Level-(N1&#xff09;的文件进行Compact。如何计算CompactScore&#xff1f; 如何…

Android入门逆引手册 - 12 评分条(RatingBar)的使用

这里介绍评分条android.widget.RatingBar类的使用。 ● 评分&#xff08;星&#xff09;的最大数的设置&#xff0c;调用setNumStars()方法。● 现在的评分的设置&#xff0c;调用setRating()方法。 例程源码(Java)[java]RatingBar ratingBar (RatingBar)findViewById(id.rati…

数据库事务的四大特性以及事务的隔离级别

本篇讲诉数据库中事务的四大特性&#xff08;ACID&#xff09;&#xff0c;并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作&#xff0c;那么该数据库必须要具备以下四个特性&#xff1a; ⑴ 原子性&#xff08;Atomicity&#xff09; 原子性是指事务包含…

程序员面试的一些注意点

一、前言 自己即将踏上求职的征程&#xff0c;所以整理一篇有关于程序员面试的小窍门&#xff0c;帮助自己和正在求职、即将求职的一些小伙伴跳过一些坑。 二、简历制作1. 不要放头像普通人大概率都不是帅哥美女&#xff0c;所以不想让外观成为评判标准的就不要放照片上去了。2…

如何解决数据倾斜问题?

转载&#xff1a;https://blog.csdn.net/Mr_HHH/article/details/89399518 今天在工作中遇到了数据倾斜的问题&#xff0c;一条SQL执行了8小时才执行完&#xff0c;看计划是先join再做distinct&#xff0c;卡在了join上&#xff0c;数据量比较大&#xff0c;并且重复数据比较多…