面试题笔记(四)0

1.

在主函数中会优先调用局部变量value,若没有才会调用全局变量,而函数printvalue()打印的是全局变,若无

全局变量则会编译报错

2.i++与++i的效率问题

内建数据类型的情况,效率没有区别

自定义数据类型的情况,++i效率更高,因为前缀式可以返回对象的引用,而后缀式只能返回对象的值,所以导致在大对象的时候产生了较大的复制开销,引起效率较低

现在让我们再考虑自定义数据类型(主要是指类)的情况。此时我们不需要再做很多汇编代码的分析了,因为前缀式(++i)可以返回对象的引用,而后缀式(i++)必须产生一个临时对象保存更改前对象的值并返回(实现过自定义类型++运算符定义的就知道),所以导致在大对象的时候产生了较大的复制开销,引起效率降低,因此处理使用者自定义类型(注意不是指内建类型)的时候,应该尽可能的使用前缀式地增/递减,因为他天生体质较佳。
答案:
内建数据类型的情况,效率没有区别。
自定义数据类型的情况,++i效率较高。

3.编程风格问题

布尔型用 if (flag)  if (!flag),因为不同的编译器对TRUE和FALSE的值是不同的,不能用其直接比较

整形用 if (value == 0) if(value != 0),

浮点型

指针变量P  用其与NULL比较,虽然null与0值相同,但两者意义不同

4.当表达式中有无符号整形与有符号整形时,都自动转化为无符号

5

两种不使用中间参数的交换两个值的方法,swap1可能会产生溢出

6.头文件中 

#ifdef _cpulspuls //表示当前使用的是C++编译器

#ifdef _stdc_  //表示当前使用的是C编译器

extern "c" 是c++编译器提供的与c连接交换指定的符号,用来解决名字匹配问题

7.可以用atexit()函数来注册程序正常终止时要被调用的函数,并且在main()函数结束时,调用这些函数的顺序与注册的顺序相反。

8.宏参数的连接

#define STR(s)  #s

表示用#将s变成一个字符串

#define CONS(a,b)  (int)*(a##e##b)

##表示将两个宏参数贴合在一起,如CONS(2,3)实际表示的值是2e3

9.#define常量在编译时首先进行替换,然后再进行编译。它的生命周期止于编译期,存在于代码段,在实际程序中只是一个常数,一个命令中的参数,没有实际存在

const常量存在于数据段(const修饰的全局变量在常量区),被分配了空间,是确确实实存在并且可以被调用,传递它有数据类型,而宏常量没有

10.//被const修饰的局部变量,放在栈区,可以通过指针强转类型,修改const修饰的变量
//被const修饰的全部变量,放在静态数据区,如果试图通过指针强转类型,会被kill掉

1.修饰变量,修饰的全局变量在常量区(静态),修饰的局部变量在栈上

2.修饰函数的形参,

void fun(A a)

void fun(A const &a)

第一个函数效率低,函数体内需要产生临时对象用于复制参数a,临时对象的构造复制析构都要消耗时间,第二个函数用引用传递,不需要产生临时变量,但引用可能会改变a,所以加上const

3.修饰函数返回值,则返回值不能被直接修改,且该返回值只能赋值给const修饰的变量

4.修饰类中成员函数,该函数不能修改成员变量

11.static修饰局部变量,全局变量,函数

12.sizeof()返回的是size_t类型,为unsigned int ,保证可以容纳最大对象的字节大小

程序在编译的时候就被计算过了,所以sizeof可以做数组的维数

13.sizeof(联合体)也要注意字节对齐

输出为16

14.#pragma pack()改变编译器对齐方式

输出为13

15,

这里的函数中的f是一个临时的局部变量,建立一个对局部变量的引用会出错

16.引用与指针区别

1.初始化要求不同

2.可修改性:引用定义后不可修改,指针随时都可以

3.不存在NULL引用

4.测试需要区别:由于引用不会指向空指针,所以不需要检测引用的合法性,而指针需要测试,指针效率更高

5.应用的区别:不改变指向用引用,存在NULL或需要改变指向时用指针

17.int a[5] = {}

     &a + 1 &a是对象(数组)首地址,a+1是数组下一个元素的地址,即a【1】,而&a+1是下一个对象的地址,即a【5】

猜你喜欢

转载自blog.csdn.net/cb673335723/article/details/81196637