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; 
  }

C C++面试常问简答题(2)相关推荐

  1. C C++面试常问简答题(1)

    1.new.delete.malloc.free关系 delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数.malloc与free是C++/C语言的标准库函数,new ...

  2. linux高级运维笔试简答题及答案,企业linux初级和高级运维面试常问题目问答总结技巧讲解(2020年录制)...

    课程增值: 课程是我最近面试辅导的所有学员,成功找到工作,企业常问题目,我带领大家学习,面试如何问答. 我曾经经历面试linux运维没有做大量准备,经历大量hr给我说的一句话就是 回家等通知吧,心碎了 ...

  3. 面向对象程序设计(c++)面试常问——for考研复试面试

    关于c++的一些面试常问问题(考研面试编程语言) 前言: 本人22考研党,已上岸,发一些复试准备整理的资料作为对考研准备的一个收尾.由于近几年基本都是线上复试,线上的话会更加注重概念的考察,本人在复试 ...

  4. Java基础(以及面试常问问题)

    1.Vector,ArrayList, LinkedList的区别(面试常问到的) 三者都是实现集合框架中的List,也就是所谓有序集合,因此具体功能比较近似,比如都提供按照位置进行定位.添加或删除的 ...

  5. python基础知识面试题-Python基本面试解答由浅入深—简答题

    原标题:Python基本面试解答由浅入深-简答题 不管你是学习任何语言,不管你是刚毕业还是行业大佬,找工作最终逃不掉的就是面试题,有的程序员很讨厌面试题,他们觉得面试题不会不代表我做不出东西,其实这种 ...

  6. java8 垃圾收集_面试官:怎么做JDK8的垃圾收集器的调优(面试常问)

    看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在jdk8中有serial收集器.parallel收集器.cms收集器. ...

  7. GET 和 POST 的区别(重要,面试常问)

    GET 和 POST 的区别(重要,面试常问) 1.GET 在浏览器回退时是无害的,而 POST 会再次提交请求. (get:不会再次发送请求:post:浏览器会继续向URI发送请求) 2.GET 产 ...

  8. 给大家提供一些面试常问的问题

    给大家提供一些面试常问的问题 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private :     私有成员, 在类的内部才可以 ...

  9. Java面试常问计算机网络问题

    转载自   Java面试常问计算机网络问题 一.GET 和 POST 的区别 GET请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的:/test/demo_form.asp?na ...

最新文章

  1. WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口
  2. ConfigParser配置文件
  3. ubuntu16.04设置cron日志
  4. android studio导出apk_Android 应用构建速度提升的十个小技巧
  5. micopython 18b20_MicroPython控制8*8LED点阵显示温度
  6. GDC2017访谈: 这3个工具让VR开发者事半功倍
  7. 敏捷开发绩效管理之三:个体动力之源——同行压力(松结对编程,师徒制度,跨职能团队,绩效考核)...
  8. 修改QtCreator的默认pro工程文件,添加assert.h条件切换
  9. c语言用参数确认递归,C语言程序设计(第4章函数)3
  10. WINDOWS NT/2000下如何屏蔽CTRL+ALT+DEL
  11. 2016年物联网技术将从概念走向落地
  12. 将帐套升级到百万用户纪念版实践教程
  13. JS实现图片拖动验证
  14. SQL中COUNT的用法
  15. mac用什么软件测试硬盘好坏,谁说果粉不在意性能?6款macOS下硬盘测速软件介绍...
  16. Centos7 进入单用户模式,修复系统
  17. android客服功能实现,基于环信实现android客户端客服聊天功能
  18. 回顾刚来的那一天还历历在目,不禁感概一番
  19. 解决everything只能搜索C盘的问题
  20. python定位二维码_python实现二维码、条形码识别

热门文章

  1. CloudCC CRM:物联网必将成为CRM的推动力
  2. 用c#编写爬虫在marinetraffic下载船仅仅图片
  3. 动态规划---背包问题分析
  4. 数据库与数据库管理系统
  5. python面试题总结(3)-- 数据类型(字符串)
  6. 表格列求和_excel表格制作,Excel表格的基本操作,包含制作一个表格10方面的知识...
  7. go mongodb排序查询_《MongoDB》day two
  8. vb6在后台将窗体保存到图片_如何将寺库网多个商品图片一键分类保存到一个目录...
  9. 血红蛋白判断access程序答案_普渡大学开发智能手机应用程序 帮助评估贫血症情况...
  10. python哪个版本支持xp_windows支持哪个版本的python