C++后台开发校招面试常见问题

转载自:https://blog.csdn.net/shanghairuoxiao/article/details/72876248

1.[extern关键字作用]

http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html)

  1. 当它与"C"一起连用时,如: extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的,C++的规则在翻译这个函数名时会把fun这个名字变得面目全非,可能是fun@aBc_int_int#%$也可能是别的,不同的编译器采用的方法不一样.
    为什么extern "C"呢???
    因为C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库中的名字与C语言的不同。参考:https://blog.csdn.net/u014783685/article/details/84973067
  2. extern不与"C"在一起修饰变量或函数时,如在头文件中:extern int g_Int,它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用。extern以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。
    切记:对于变量,只在头文件中做声明。即extern char g_str[];,不要在头文件中定义:char g_str[] = "123456";
    因为,变量可以声明多次,但只能定义一次。如果有2个.cpp包含了这个头文件,那么这个变量就会被定义两次,那么就会出错。

1.0 关于_声明与定义_:

 extern int a;//声明一个全局变量a
 int a; //定义一个全局变量a
 
 extern int a =0 ;//定义一个全局变量a 并给初值。 
 int a =0;//定义一个全局变量a,并给初值,与上一行不能连起来使用,会出现重定义。 

1.1 extern"C"的使用

参考:https://blog.csdn.net/big_bit/article/details/51595714?utm_source=copy

  1. 可以是单一语句
   extern "C" double sqrt(double)`;
  1. 可以是复合语句,相当于复合语句中的声明都加了extern"C"
extern "C"   
{
     double sqrt(double);
     int min(int, int);  
}

3.可以包含头文件,相当于头文件中的声明都加了extern"C"

extern"C"   
{
    #include <cmath>  
}
  1. 不可以将extern"C"添加在函数内部

  2. 如果函数有多个声明,可以都加extern"C",也可以只出现在第一次声明中,后面的声明会接受第一个链接指示符的规则。

  3. 除extern"C",还有extern"FORTRAN"等。

1.2 extern修饰变量时的方法:

  1. 使用头文件,然后声明它们,然后其他文件去包含头文件。
    注:B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在链接时从模块A生成的目标代码中找到此函数。例:
/*a.h*/
#include<iostream>
extern int i;

/*a.cpp*/
#include"a.h"
int i=4;

 /*main.cpp*/
#include"a.h"
int  main(){
	cout<<i<<endl;
	return 0;
}
  1. 在其他文件中直接extern。 例:
/*a.h*/
#include<iostream>
extern int i;

/*a.cpp*/
#include"a.h"
int i=4;

/*main.cpp*/
#include<iostream>
extern int i;
int  main(){
 	cout<<i<<endl;
 	return 0;
}

http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html

2.头文件里面的ifndef /define/endif的作用

参考:https://blog.csdn.net/yapingmcu/article/details/8027473
例如:要编写头文件test.h
在头文件开头写上两行:

          #ifndef _TEST_H
          #define _TEST_H//一般是文件名的大写
         ············
         ············
         头文件结尾写上一行:
          #endif 

为什么要用这些呢?

#ifndefif not define的简写,是一种宏定义判断,作用是防止多重定义,对同一文件进行多次编译报错。所以最好是将每一个头文件都使用上这个方法,将头文件的内容都放在#ifndef#endif中。

一般格式为:

#ifndef   <标识 >   
#define   <标识 >   
......   
......   
#endif   <标识 >  

命名规则

但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h

#ifndef   _STDIO_H_   
#define   _STDIO_H_    ......   
#endif

详细解释:

1.比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。加上ifndef/define/endif,就可以防止这种重定义错误。
例:假设你的工程里面有4个文件,分别是a.cpp,b.h,c.h,d.h
a.cpp的头部是:

#include   "b.h "
#include   "c.h "  

b.hc.h的头部都是: #include "d.h "d.h里面有class D的定义。 这样一来, 编译器编译a.cpp的时候,先根据#include "b.h "去编译b.h这个问题,再根据b.h里面的#include "d.h",去编译d.h的这个文件,这样就把d.h里面的class D编译了; 然后再根据a.cpp的第二句#include "c.h ",去编译c.h,最终还是会找到的d.h里面的class D,但是class D之前已经编译过了,所以就会报重定义错误
2…在#ifndef中定义变量出现的问题(一般变量不定义在#ifndef中)。

#ifndef   AAA   
#define   AAA    
...   
 int   i;   
  ...   
#endif   

里面有一个变量定义 在vc中链接时就出现了i重复定义的错误,而在c中成功编译。
结论
(1).当你第一个使用这个头的.cpp文件生成.obj的时候,int i 已经在里面定义了。当另外一个使用这个的.cpp再次[单独]生成.obj的时候,int i又被定义。然后两个obj被另外一个也include这个头的.cpp连接在一起,就会出现重复定义.
(2).把源程序文件扩展名改成.c后,VC按照C语言的语法对源程序进行编译,而不是C++。在C语言中,若是遇到多个int i则自动认为其中一个是定义,其他的是声明
(3).C语言和C++语言连接结果不同,可能(猜测)是在进行编译的时候,C++语言将全局变量默认为强符号,所以连接出错。C语言则依照是否初始化进行强弱的判断的。(参考)
解决方法
(1).把源程序文件扩展名改成.c。
(2).推荐解决方案: .h中只声明 extern int i;在.cpp中定义

 <x.h>
#ifndef __X_H__
#define __X_H__ 
extern int i;
#endif //__X_H__ 
<x.c>
int i;

相同作用:#pragma once

#pragma once方式却不受一些较老版本的编译器支持,一些支持了的编译器又打算去掉它,所以它的兼容性可能不够好。

3.volatile关键字

  1. 访问寄存器要比访问内存要块,因此CPU会优先访问该数据在寄存器中的存储结果,但是内存中的数据可能已经发生了改变,而寄存器中还保留着原来的结果。(如汇编语句改变了内存中的值,而不让编译器知道),为了避免这种情况的发生将该变量声明为volatile,告诉CPU每次都从内存去读取数据。
    在多线程中,两个线程使用到同一个变量,而且这个变量的值可能会发生改变时,应该用volatile声明,让编译器每次操作该变量时一定要从内存中真正取出,当一个变线程改变了该变量的值时,对另外一个线程是可见的。
  2. 一个参数可以即是const又是volatile的吗?

答案:如果一个变量不会被本程序改变,通常可能给它加上const,但如果该变量可能被其他程序或外部端口改变,而本程序又在检测这个变量的值,就需要给它加上volatile。于是变量就同时有volatile和const了,这个时候该变量具有const和volatile的双重属性。该变量不可以在编译过程中被程序代码修改,同时编译器不得对i进行优化编译。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后台开发:核心技术与应用实践 作者:徐晓鑫 著 出版日期:2016年08月06日 封面宣传语:腾讯云平台技术总监黄世飞、Facebook对外支付项目主程张子兴、微软软件工程师彭可竞、阿里巴巴资深算法工程师周乐、百度大数据高级测试工程师畅晋联袂推荐;围绕后台开发需要掌握的核心技术,从多个方面、多个角度进行了阐述,覆盖了该领域的几乎所有内容;充分抓住本质并结合实践,文字通俗易懂,可操作性强 出版书名:后台开发:核心技术与应用实践 作者:徐晓鑫 著 封底文字 专家评价 后台开发是一个“历史悠久”的领域,同时也是一个沉淀深厚,高技术价值的领域。本书清晰、严谨、务实的风格显示出晓鑫对该领域知识的深刻理解。 ——张子兴 Facebook对外支付项目主程,美国加州MenloPark 每一位从事后台开发的专业人士都需要一本后台开发指南。对每一位想要认真从事该领域工作的人来说,本书是一本绝对必读的书籍。 ——彭可竞 微软软件工程师,美国华盛顿州Redmond 本书是作者多年后台开发、架构和研究的精华。书中用通俗的文字、详尽的示例代码,结合实际工作中的案例,讲述了后台开发方方面面的知识,内容丰富。对于从事后台开发的人员,这是一本很好的由浅入深的学习书籍。 ——周乐 阿里巴巴资深算法工程师,北京望京 使用C++语言进行后台开发有一定的门槛,本书可以很好地帮助你跨过这个“门槛”。 ——畅晋 百度大数据高级测试工程师,北京上地 前勒口 互联网网民日益剧增,各种应用层出不穷,各项技术更新不断。单是游戏行业,近几年就经历了从端游、页游到手游的巨大变迁,客户端更新迭代之快,始料未及。而后台开发中使用到的技术,却变化不是很大。让服务性能更高、处理能力更强、安全性更好,是后台开发工程师永恒的主题。 后台开发中用到的技术,深而广,需要读的“大部头”很多,光是Richard Stevens的APUE,UNP,TCP/IP详解就够读个半年以上。读者通过阅读本书,可以从实践出发,快速由浅入深地进入后台开发领域。在读完本书,有了实践的经验之后,再去阅读大师们的著作,会更有体会,更懂得如何欣赏。 读书的最高境界莫过于“把书读薄,把书读厚”。本书文字通俗易懂,让你更快地“读薄”,同时又涉及较多的核心知识点,顺着这些知识点,读着读着也发觉“读厚”了。 后勒口 徐晓鑫,腾讯资深软件研发工程师,先后在腾讯游戏之洛克王国、QQ会员、QQ秀等项目工作,精通后台开发各种技术,实战经验丰富。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值