程序员面试题汇总之预处理

预处理也称为预编译,它为编译做预备工作,主要进行代码文本的替换工作,用于处理#开头的指令,其中预处理器产生编译器的输出。

3.1#define 有哪些缺陷

  • 它无法进行类型检查。宏定义是在编译前进行字符的替换,因为还没有编译,不能编译前就检查好类型是否匹配,而只能在编译时才知道,所以不具备类型检查功能。
  • 由于优先级不同,使用宏定义时,可能会存在副作用。
  • 无法进行单步调试
  • 会导致代码膨胀。由于宏定义是文本替换,需要堆代码进行展开,相比较函数调用的方式,会存在较多的冗余代码。
  • 在C++中,使用宏无法操作类的私有数据成员。

3.2含参数的宏和函数有什么区别

特点如下:

  • 函数调用时,首先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。
  • 函数调用时在程序运行时处理的,它需要分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,也不进行值的传递处理,也没有“返回值”的概念。
  • 对函数中的实参和形参都要定义类型,两者的类型要求一致,如果不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。
  • 调用函数只可得到一个返回值,而用宏可以设法得到好几个结果。
  • 使用宏次数多时,宏展开后源程序会变得很长,而函数调用不使源程序变长。
  • 宏替换不占用运行时间,而函数调用则占用运行时间。
  • 参数每次用于宏定义时,他们都将重新求值,由于多次求值,具有副作用的参数可能会产生不可预料的结果,而参数在函数被调用前只求值一次,在函数中多次使用参数并不会导致多种求值过程,参数的副作用并不会造成任何特殊的问题。

3.3如何判断一个变量是有符号数还是无符号数?

采用取反操作

  • 由于无符号数和有符号数相减结果为无符号,所以可以通过相减可以判断。
  • 通过改变符号位判断,把A进行一个位运算,将最高位置1,判断是否大于0;

3.4枚举和define有什么不同?

  • 枚举常量是实体中的一种,而宏定义不是实体。
  • 枚举常量属于常量,但宏定义不是常量。
  • 枚举常量具有类型,但宏没有类型,枚举变量具有与普通变量相同的性质。
  • #define宏常量是在预编译阶段进行简单替换,枚举常量则是在编译的时候确定其值。
  • 一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
  • 枚举可以一次定义大量相关的常量,而#define宏一次只能定义一个。

3.5typedef和define有什么区别?

两者都是替一个对象取一个别名,以此来增加程序的可读性,不同之处:

  • 原理不同。#define是C语言中定义的语法,它是预处理指令,在预处理时进行简单而机械的字符串替换,不做正确性检查,不管含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。typedef是关键字,它在编译时处理,所以其具有类型检查的功能。
  • 功能不同。#define不仅可以为类型取别名,还可以定义常量,变量,编译开关等。
  • 作用域不同。#define没有作用域的限制,只是在之前预定义过的宏,在后面的程序中均可以使用,而typedef有自己的作用域。
  • 对指针的操作不同。

3.6C++中宏定义与内联函数有什么区别?

  • 宏定义是在预处理阶段进行代码替换,而内联函数是在编译阶段插入代码。
  • 宏定义没有类型检查,内联函数有类型检查。

3.7内联函数和普通函数有什么区别?

内联函数和普通函数最大的区别在于其内部的实现方面上,普通函数在被调用时,系统首先要跳跃到该函数的入口地址,执行函数体,执行完成后,在返回到函数调用的地方,函数始终只有一个复制;而内联函数则不需要进行一个寻址的过程,当执行到内联函数时,此函数展开,如果在N处调用了此内联函数,则此函数就会有N个代码段的复制。

3.8 #define和const的区别?

define既可以替代常数值,又可以替代表达式,甚至是代码段,但是容易出错。而const得引入可以增加程序得可读性,它使程序得维护与调试变得更加方便。主要差异:

  • define只是用来进行单纯的文本替换,define常量的生命周期止于编译期,不分配内存空间,它存在于程序的代码段,在实际程序中它只是一个常数,一个命令中的参数并没有实际的存在;而const常量存在于程序的数据段,并在堆栈中分配了空间,const常量在程序中确确实实的存在,并可以被调用、传递。
  • const常量有数据类型,而define常量没有数据类型,编译器可以对const常量进行类型的安全检查。
  • 很多IDE支持调试const定义的常量,而不支持define定义的常量。

你可能感兴趣的:(每日一贴)