1.指针和引用的区别

1.指针是一个变量,变量存储一个地址指向内存中一个存储单元,需要单独分配内存空间。引用相当于变量的别名,不需要单独分配空间

2.引用必须初始化,指针可以先不进行初始化

3.指针可以设置为const类型,引用不可以为const

4.作为形参时,引用在函数体内可直接修改原值,指针是原变量的一个拷贝

5.单目运算符++,作用在引用上int a=1;int b=&a; b++相当于a++;

作用在指针上int a =1; int *b=&a; b++只表示指针地址增加,a不曾变化

6.指针可以有多级,引用只有一级。

7.指针定义后可以修改为执行其他的存储单元,引用定义后不能修改。

8.sizeof运算符处理后,计算指针表示指针的大小:32为系统得到4;计算引用得到相应类型的大小:char型引用为1.

2.volatile作用(cpu缓存机制),实例有哪些?

在编译优化时,为了优化执行速度,有些变量在调用时使用保存在寄存器中的拷贝。使用volatile修饰的变量表示这个变量会被意外改变,每次使用都应小心的从内存读取原值

>现象举例:

  1.状态寄存器的内容

  2.中断服务程序中访问的非自动变量

  3.多线程程序的共享变量

3.static const用法说明(参数及变量)。

>const用法:

  1.在定义的时候必须进行初始化

  2.表示不会被程序修改的变量

  3.修饰形参表示形参在调用函数体内不能被修改

  4.修饰指针时的几种情况:

    const int *a 指针指向的为一个常整形数

    int *const a 指针是一个常指针

    const int *a const 一个执行常整形数据的常指针

static用法:

  1.static变量只会被定义一次,避免了多重定义的问题

  2.static变量默认初始化为0,存储在静态存储区BSS段。变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。

  3.变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

  4.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

4.内联函数作用,与宏定义的区别。内联函数为什么定义在头文件中并且加static

宏的作用是基本的字符替换,在编译阶段进行。内联函数的使用时为了节省掉函数调用的时间,省去了call和ret并且具备函数功能

  1.内联函数在运行时可调试,而宏定义不可以;

  2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;

  3.内联函数可以访问类的成员变量,宏定义则不能;

  4.在类中声明同时定义的成员函数,自动转化为内联函数。

>内联函数为什么定义在头文件中并且加static

  inline 关键字实际上仅是建议内联并不强制内联,gcc中O0优化时是不内联的,即使是O2以上,如果该函数被作为函数指针赋值,那么他也不会内联,也必须产生函数实体,以获得该函数地址。

  经测试c文件中的仅inline函数即使Os优化也不内联,因为没有static,编译认他是全局的,因此像普通函数一样编译了,本c文件也一样通过 bl inline_func 这样的方式调用,不像网上别人说的,本c会内联,其他c文件则通过bl inline_func 方式。加入static 后则内联了。(Os优化等级测试)

  所以在头文件中用inline时务必加入static,否则当inline不内联时就和普通函数在头文件中定义一样,当多个c文件包含时就会重定义。所以加入static代码健壮性高,如果都内联了实际效果上是一样的。(gcc下验证过O0级别includes.h中仅定义inline的函数,编译失败,Os编译成功)

  虽然知道了头文件中用inline函数时要加入static,但是为什么要在头文件中定义函数呢?

  一些简单的封装接口函数,如 open() { vfs_open() } 仅仅是为了封装一个接口,我们不希望耗费一次函数调用的时间,解决方法一是宏,但是作为接口,宏不够清晰。那选择inline,但是如果在c文件中写

main.c

inline void open(void)

{ vfs_open(); }

  头文件声明,外部要使用则不会内联的,因为编译器有个原则,以c文件为单位进行逐个编译obj,每个c文件的编译是独立的,该c文件用到的外部函数都在编译时预留一个符号,只有等到所有obj生成后链接时才给这些符号地址(链接脚本决定地址),所以其他c文件编译时只会看到这个函数的声明而无法知道她的实体,就会像普通函数一样通过bl 一个函数地址,等链接的时候再填入该地址了,他做不到内联展开。
  所以要内联则必须在每个用到它的c文件体现实体,那就只有在头文件了,所以把这类希望全局使用并且增加效率的函数实现在头文件中添加static inline。

5.静态内存分配和动态内存分配区别。

存储空间:静态内存在编译阶段分配在栈空间,动态内存在运行阶段分配在堆上
6、分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
答:bool类型,任何非零值都是真,记做TRUE,零值记做假,FLAUSE。与零值比较通常使用if(var)和if(!var)。
Int型与零值比较很简单,if(var==0)和if(var!=0).
Flaot型变量。应该注意精度限制。它和double变量一样,不能使用“==”或者“!=”,正确的使用是const float EPSINON=0.00001;if(var>=-EPSINON)&&(var<=EPSION)
指针变量,if(p==NULL)和if(p!=NULL).

6。枚举与#define的区别

7.内存对齐规则。

(1)对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个暑假成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员自身长度)的倍数;
    (2)在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员大小中,比较小的那个进行;
    #pragma pack(n)表示设置为n字节对齐。VC 6.0默认8字节对齐。

内存对齐的主要作用:
    (1)平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取得某些特定类型的数据,否则抛出硬件异常。
    (2)性能原因:经过内存对齐后,CPU的内存访速度大大提升。
    图一:
    
    这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。
    图二:
    
    CPU把内存当成是一块一块的,块的大小可以是2,、4、8、16字节的大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory granularity(粒度)。

8.动态分配对象与静态分配对象区别。

9.内存溢出有哪些因素。

1.格式字符串复制 2.递归调用 3.

10.new/delet与malloc/free区别。

  1.new分配内存时会根据申请的变量类型返回相应的类型的指针,mallco申请内存返回void类型指针。
  2.new 分配内存会自动调用构造函数,mallco仅仅申请堆上内存空间

11.模板怎么实现,模板的作用

12、类成员函数的重载、覆盖和隐藏的区别?
重载:相同的范围在同一个类中,函数名相同,参数不同,virtual关键字可省略
覆盖:不同的范围(分布基于派生类和基类),函数名相同,参数相同,基类中一定要有virtual关键字。
隐藏:是指派生类的函数屏蔽了和他同名的基类函数。隐藏的规则:

(1)派生类的函数与基类的函数同名,但是参数不同。基类的函数将被隐藏,此时不管有无关键字(注意别与重载混淆)。 
       (2)派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

13.多态

  •   多态是什么:多态是由虚函数实现的。举例:动物基类和派生类(叫声)
  •   多态都有哪些(动态和静态的):http://blog.csdn.net/hackbuteer1/article/details/7475622
    •   多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。(通过函数重载实现的)而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。(通过虚函数实现的)
    •   动态绑定怎么实现:声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。
      •   例如:A *a;B b;a=&b;a.god();//这也是相当于动态绑定(有些题目比较难理解)
  •   纯虚函数和虚函数区别
    •   纯虚函数:在基类中只能声明不能定义,在派生类中必须都实现这个纯虚函数。带有纯虚函数的称为抽象类,只能当做基类使用,抽象类不能定义对象
    •   虚函数:在基类中声明定义,但是在派生类中可以不定义。
    •   引入纯虚函数比较安全,效率也比较高。

14.说说什么是野指针?野指针什么情况下出现? (详细)

  •   野指针:指向一个已经删除的对象或者未申请访问受限地址的指针。
  •   出现情况:没有初始化(要么等于NULL,要么指向对的地方),释放指针没有置为NULL(释放只是释放了指针所指的内存,指针本身并没有释放掉)

15.断言ASSERT()作用是什么?它是函数还是宏?为什么不能是函数?

  •  assert其实是一个宏,它的作用是一个判断计算表达式真假。例如:assert(a!=0)(一般的它只允许调用一个表达式参数,如果多个参数判断不准确),如果a!=0,就是结果正确,程序继续运行,如果false那就会先向stderr打印一个错误信息,然后再调用abort终止程序。(一般把这个宏放在程序中来进行调试,它主要是用作debug版本中 )
  • 它的缺点是:频繁的调用会影响程序的性能,会增加额外的开销。

12.多线程锁机制有哪些

13.自旋锁和互斥锁区别。

14.进程间通信和线程间通信方法

1.线程间通信:管道,消息队列,共享内存,全局变量,

15.

最新文章

  1. 20150514Linux下rpm包安装错误及解决方案
  2. jquery-easyui中表格的行编辑功能
  3. (2)jni编程学习笔记
  4. oracle11g OEM无法连接到数据库实例解决办法
  5. 数据结构复习:交换排序原理及C++实现
  6. 关于sqlmap无法打开的问题解决办法
  7. .Net Service开发(一)
  8. codeforces 3D . Least Cost Bracket Sequence 贪心
  9. DOM(一)
  10. 我喜欢的两个js类实现方式
  11. hdu_5507_GT and strings(AC自动机)
  12. C++ 学习之函数重载、基于const的重载
  13. c#堆与栈
  14. ABAP-加密解密
  15. 微信企业号开发之weixin://preInjectJSBridge/fail
  16. ui-router 1.0 003 lazyloading
  17. lineman 的理念与 modern web app
  18. python-day33--Process类中的方法及属性
  19. Beta周王者荣耀交流协会第六次会议
  20. 你知道吗?31种 CSS 选择器的应用

热门文章

  1. 巴厘岛的雕塑(sculptures)
  2. express上传图片
  3. (转)使用openGL显示图像(一)建立OpenGL ES的环境
  4. python实现人民币大写转换
  5. cs224d 作业 problem set1 (一) 主要是实现word2vector模型,SGD,CBOW,Softmax,算法
  6. Redis Sentinel用法
  7. 洛谷 P2023 维护序列——线段树
  8. jmeter 不同线程组之间传递变量3
  9. __attribute__((regparm(3))) from GNU C
  10. CSS 中功能相似伪类间的区别