1.C语言头文件包含<x.h> 和 "x.h"的区别?
头文件用<>引用时,编译器会在系统标准库路径下查找该文件。
头文件用”“引用时, 编译器会先在当前路径下查找,如果当前路径没有找到,再到系统路径下查找
2.CPU内部的TLB模块的主要作用是?
(Translation Lookaside Buffer)
主要用于加速CPU从虚拟地址到物理地址的转换过程,从而提高CPU的性能。
3.用char定义一个字符时,计算机存储的是字符还是对应的ASCII码值?
用char定义一个字符时,计算机存储的是对应的ASCII码值。在C/C++中,char类型是一种整数类型,用于存储字符的ASCII码值。例如,字符'A'的ASCII码值是65,用char类型定义时,实际上存储的是整数值65。
当需要输出字符时,可以使用printf函数的%c格式化符号,将ASCII码值转换为对应的字符输出。例如,printf("%c", 65)会输出字符'A'。
需要注意的是,C/C++中的char类型默认是有符号类型,范围是-128到127。如果需要使用无符号类型的char,可以使用unsigned char类型。
4.计算机存储数据为什么要用补码
计算机存储数据时使用补码的主要原因是为了解决负数的表示问题。在计算机中,数据以二进制形式存储,但是使用原码表示负数会出现两个问题:
-
零的表示不唯一:在原码中,正数的最高位为0,负数的最高位为1。但是,0的原码、正数的原码和负数的原码都是不同的,这会导致计算机在进行加减运算时需要特殊处理0,增加了运算的复杂度。
-
减法运算不方便:在原码中,减法运算需要将被减数的符号位取反,然后与减数相加。这种运算方式不仅复杂,而且容易出错。
补码是一种解决这些问题的方法。在补码中,正数的补码与原码相同,而负数的补码是将其原码取反后再加1。这样,补码中只有一种表示0,而且减法运算可以转化为加法运算,简化了运算的过程。因此,计算机存储数据时使用补码可以提高运算的效率和精度。
5. C++中const int a = 10; a会被分配内存吗?
在C++中,使用const关键字定义的常量在编译时会被替换为字面值,因此不会分配内存。在这个例子中,常量a的值为10,编译器会在编译时将所有使用a的地方替换为10,而不会在运行时分配内存来存储a的值。这也是使用常量的好处之一,可以避免在程序运行时不必要的内存分配和赋值操作。
6.为什么尽量不要对寄存器变量取地址
寄存器变量是指使用register关键字声明的变量,它们的值存储在CPU的寄存器中,而不是内存中。由于寄存器的访问速度比内存快得多,因此使用寄存器变量可以提高程序的执行效率。
然而,对寄存器变量取地址会导致它们被强制存储到内存中,从而失去了使用寄存器的优势,反而会降低程序的执行效率。此外,由于寄存器变量的数量是有限的,对寄存器变量取地址还可能导致其他变量无法被分配到寄存器中,从而影响程序的性能。
因此,尽量不要对寄存器变量取地址,除非确实需要在程序中使用指针来引用这些变量。在大多数情况下,应该避免对寄存器变量取地址,以便让编译器可以自由地将它们存储在寄存器中,从而提高程序的执行效率。
7.内联函数和宏定义的区别
内联函数和宏定义都可以用来优化程序的执行效率,但是它们有以下几点区别:
-
内联函数是在编译时展开,而宏定义是在预处理时展开。因此,内联函数可以进行类型检查和错误检查,而宏定义不行。
-
内联函数可以使用函数的参数和局部变量,而宏定义只能使用宏定义时传入的参数和全局变量。
-
内联函数可以进行递归调用,而宏定义不行。
-
内联函数的代码会被复制到调用它的地方,而宏定义只是简单地替换文本。因此,内联函数的代码会增加程序的大小,而宏定义不会。
-
内联函数可以像普通函数一样进行调试,而宏定义不行。
综上所述,内联函数比宏定义更加安全、可读性更高,但是会增加程序的大小。而宏定义虽然能够减少程序的大小,但是不够安全,可读性也不高。