答案:
define和const 都可以用于定义常量但以下区别(生效时间,内存占用情况,类型检查):
答案:
1. 首先#define是预处理命令,在预处理阶段只是机械的替换带入字符串,并不会左类型检查,
2. typedef是关键字,作用是给自己的作用域内给一个已经存在的类型起个别名
3. #define没有作用域的限制,只要是之前预定义过的宏,在以后的程序中都可以使用,而typedef有自己的作用域
4. 对指针的操作不同
比如: #define intper int *
typedef int * pre
答案:
答案:
对于#include<头文件>,表示是系统文件,编译会先从标准库路径下搜索-->编译器设置的头文件路径-->系统变量
对于#include”头文件”,当前头文件目录-->编译器设置的头文件路径-->系统变量
对于编译速度来说:
语句#include< stdlib.h >是正确的,而且程序编译速度比#include “stdlib.h”要快
答案:
#define SECOND_PER_YEAR(60*60*24*365)UL
重点是看有没有加UL
答案:
预处理、编译、汇编、链接
预编译:这个过程主要的处理操作如下:
(1) 将所有的#define删除,并且展开所有的宏定义
(2) 处理所有的条件预编译指令,如#if、#ifdef
(3) 处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。
(4) 过滤所有的注释
(5) 添加行号和文件名标识
编译:这个过程主要的处理操作如下:
(1) 词法分析:将源代码的字符序列分割成一系列的记号。
(2) 语法分析:对记号进行语法分析,产生语法树。
(3) 语义分析:判断表达式是否有意义。
(4) 代码优化:
(5) 目标代码生成:生成汇编代码。
(6) 目标代码优化
汇编:这个过程主要是将汇编代码转变成机器可以执行的指令。
链接:将不同的源文件产生的目标文件进行链接,从而形成一个可以执行的程序
答案:
不可以,因为静态变量是有记忆的,不会随函数结束而结束,所以,如果定义在头文件中,那么就会被多个文件开辟空间,浪费资源或者重新出错。
答案:
生效、类型、检查,调试,实体
答案:
1.宏函数不是函数,是宏定义,只是使用起来像函数,宏函数是在预编译的时候把所有的宏名用宏体来替换,简单的说就是字符串替换。
2.内联函数,内联函数本质上是一个函数,内联函数一般用于函数体的代码比较简单的函数,不能包含复杂的控制语句,while、switch,并且内联函数本身不 能直接调用自身。
3.宏函数和内联函数如何提高效率?
内联函数是在编译的时候进行代码插入,编译器会在每处调用内联函数的地方直接把内联函数的内容展开,这样可以省去函数的调用的开销,提高效率。
宏函数则是在预处理的时候把宏体展开减去了参数压栈,函数调用,返回值等操作。
4.宏定义是没有类型检查的,无论对还是错都是直接替换;而内联函数在编译的时候会进行类型的检查,内联函数满足函数的性质,比如有返回值、参数列表。
答案:
内联函数一般用于函数体的代码比较简单的函数,不能包含 复杂的控制语句,while、switch,并且内联函数本身不能直接调用自身。
最根本的区别是普通函数在调用时会调到函数入口,执行函数,再返回来,而内联函数不需要寻址,直接在该处将函数张开,如果N处调用了内联函数则会有n处复制该代码,而普通函数只有一个复制。
答案:
默认的类中的析构函数并不不是虚函数,之所以要是虚析构函数,主要是考虑继承时子类内存释放问题。
将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。
举例说明:
当A为基类,B为A的继承类,考虑如下情况:
A *p = new B();
.....
delete p;
如果此时A的析构函数不是虚函数,那么在delete p的时候就会调用A的析构函数,而不会调用B的析构函数,这样就会造成B的资源没有释放。
而如果A的析构函数为虚函数,那么就会调用B的析构函数,一切正常。
答案:
当类中有虚成员函数时,类会自动生成虚函数表和虚表指针,虚表指针指向虚函数表。每个类都有自己的虚函数表,虚函数表的作用就是保存本类中虚函数的地址,我们可以把虚函数表形象地看成一个数组,这个数组的每个元素存放的就是各个虚函数的地址。
这样一来,就会占用额外的内存,当们定义的类不被其他类继承时,这种内存开销无疑是浪费的。