程序员面试宝典(第四版)——读书笔记-2、第六章:预处理、const与sizeof
2015-08-08 15:34
597 查看
6.1
宏定义
1、 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
解析:
1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。
2 、写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
这个测试是为下面的目的而设的:
1) 标识#define在宏中应用的基本知识。这是很重要的。因为在 嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
3) 懂得在宏中小心地把参数用括号括起来
6.2
const
1、修饰一般变量
const int i=2;
// the above same as
int const i=2;
即,修饰符const可以用在类型说明符前,也可以用在类型说明符后。(习惯多用在类型说明符前,但建议用在类型说明符后)
2、修饰数组(同修饰变量)
3、修饰指针
const int *p1;// p1可变,p1指向的对象不可变
int const *p2;// 同上
int ival=1;
int* const p3=&ival;// p3不可变且必须初始化,p3指向的对象可变
const int* const p4=&ival;// 指针p4和p4指向的对象都不可变,且p4必须初始化
记忆方法1 :const修饰符可以放在所修饰类型的前面或后面,建议放在后面。
记忆方法2 :先忽略类型名(编译器解析的时候也是忽略类型名),我们看const离哪个近,就是修饰它后面的那个类型。
const int *p1;// const修饰*p1
int const *p2;// 同上
int ival=1;
int * const p3=&ival;// const修饰p3
const int * const p4=&ival;// 第一个const修饰*p4,第二个const修饰p4
4、修饰函数的参数和函数的返回值
5、const与#define相比不同之处
C++中可以用const定义常量,也可以用#define定义常量,但是前者比后者有很多优点
const常量有数据类型,而宏常量没有数据类型;编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误。边际效应;有些集成化的调试工具可以对const常量进行调试,但不能对宏常量进行调试。
6、在const成员函数中,用mutable修饰成员变量名后,就可以修饰类的成员变量了。
mutable int m_Count;
6.3
sizeof
1、字符指针的大小是一个定值,就是4个字节;字符数组实际值再加上隐含的”\0“一个字节。
2、注意静态变量时存放在全局数据区的,而sizeof计算栈中分配的大小
不计算在内的。例如static int b不计算在内
3、说明sizeof和strlen之间的区别
sizeof是运算符,strlen是函数。
sizeof可以用类型作参数,strlen只能用char*
作参数,且必须是以“\0”结尾的。sizeof还可以用函数做参数。
数组做sizeof的参数不退化,传递给strlen就退化为指针。
4、sizeof的使用场合:
sizeof的主要用途是与存储分配和I/O系统那样的历程进行通信;
看看某种类型的对象在内存中所占的单元字节。
如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。
6.4
内联函数和宏定义
1、内联函数和宏定义的差别是什么?
内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接镶嵌到目标代码中。而宏只是一个简单的替换。
内联函数要做参数类型检查,这是内联函数跟宏相比的优势。
inline 是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到那里去。对于短小代码来说inline增加空间消耗换来的是效率提高,这方面和宏是一模一样的,但是inline在和宏相比没有付出任何额外代价的情况下更安全。至于是否需要inline函数,就需要根据实际情况来取舍。
inline一般只适用于如下情况:
一个函数不断被重复调用。
函数只有简单的几行,且函数内不存在while、for、switch语句。
宏定义
1、 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
解析:
1) #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
2)懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3) 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4) 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。记住,第一印象很重要。
2 、写一个"标准"宏MIN ,这个宏输入两个参数并返回较小的一个。
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
这个测试是为下面的目的而设的:
1) 标识#define在宏中应用的基本知识。这是很重要的。因为在 嵌入(inline)操作符 变为标准C的一部分之前,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2)三重条件操作符的知识。这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else更优化的代码,了解这个用法是很重要的。
3) 懂得在宏中小心地把参数用括号括起来
6.2
const
1、修饰一般变量
const int i=2;
// the above same as
int const i=2;
即,修饰符const可以用在类型说明符前,也可以用在类型说明符后。(习惯多用在类型说明符前,但建议用在类型说明符后)
2、修饰数组(同修饰变量)
3、修饰指针
const int *p1;// p1可变,p1指向的对象不可变
int const *p2;// 同上
int ival=1;
int* const p3=&ival;// p3不可变且必须初始化,p3指向的对象可变
const int* const p4=&ival;// 指针p4和p4指向的对象都不可变,且p4必须初始化
记忆方法1 :const修饰符可以放在所修饰类型的前面或后面,建议放在后面。
记忆方法2 :先忽略类型名(编译器解析的时候也是忽略类型名),我们看const离哪个近,就是修饰它后面的那个类型。
const int *p1;// const修饰*p1
int const *p2;// 同上
int ival=1;
int * const p3=&ival;// const修饰p3
const int * const p4=&ival;// 第一个const修饰*p4,第二个const修饰p4
4、修饰函数的参数和函数的返回值
5、const与#define相比不同之处
C++中可以用const定义常量,也可以用#define定义常量,但是前者比后者有很多优点
const常量有数据类型,而宏常量没有数据类型;编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误。边际效应;有些集成化的调试工具可以对const常量进行调试,但不能对宏常量进行调试。
6、在const成员函数中,用mutable修饰成员变量名后,就可以修饰类的成员变量了。
mutable int m_Count;
6.3
sizeof
1、字符指针的大小是一个定值,就是4个字节;字符数组实际值再加上隐含的”\0“一个字节。
2、注意静态变量时存放在全局数据区的,而sizeof计算栈中分配的大小
不计算在内的。例如static int b不计算在内
3、说明sizeof和strlen之间的区别
sizeof是运算符,strlen是函数。
sizeof可以用类型作参数,strlen只能用char*
作参数,且必须是以“\0”结尾的。sizeof还可以用函数做参数。
数组做sizeof的参数不退化,传递给strlen就退化为指针。
4、sizeof的使用场合:
sizeof的主要用途是与存储分配和I/O系统那样的历程进行通信;
看看某种类型的对象在内存中所占的单元字节。
如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。
6.4
内联函数和宏定义
1、内联函数和宏定义的差别是什么?
内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接镶嵌到目标代码中。而宏只是一个简单的替换。
内联函数要做参数类型检查,这是内联函数跟宏相比的优势。
inline 是指嵌入代码,就是在调用函数的地方不是跳转,而是把代码直接写到那里去。对于短小代码来说inline增加空间消耗换来的是效率提高,这方面和宏是一模一样的,但是inline在和宏相比没有付出任何额外代价的情况下更安全。至于是否需要inline函数,就需要根据实际情况来取舍。
inline一般只适用于如下情况:
一个函数不断被重复调用。
函数只有简单的几行,且函数内不存在while、for、switch语句。
相关文章推荐
- 黑马程序员——Java基础语法---数组
- 黑马程序员——20,IO流,FileWriter,FileReader
- 程序员面试宝典(第四版)——读书笔记-1、第五章:程序设计基本概念
- 剑指offer面试题46:求1+2+...+n
- 黑马程序员--Java面向对象理解
- 【黑马程序员】Java笔记--集合框架
- 做一个有情操的程序员:论那没卵用的磁贴
- 剑指offer面试题4-- 替换空格
- 【转】2012年6月25 – 某欧美上市企业PHP工程师最新面试题
- 【面试题】从网上看到的一道面试题之自我见解
- 你面试微软前必须要读的十本书:
- 面试题:在一个数组中除两个数字只出现1次外,其它数字都出现了2次, 要求尽快找出这两个数字
- 程序员保值的五个关键点
- 【剑指Offer面试题】 九度OJ1372:最大子向量和(连续子数组的最大和)
- “反应快”的程序员更优秀吗?
- 黑马程序员——-——java基础之异常
- 2014百度面试题
- 【LeetCode-面试算法经典-Java实现】【104-Maximum Depth of Binary Tree(二叉树的最大深度)】
- 【LeetCode-面试算法经典-Java实现】【102-Binary Tree Level Order Traversal(二叉树层序遍历)】
- 【LeetCode-面试算法经典-Java实现】【103-Binary Tree Zigzag Level Order Traversal(二叉树分层Z字形遍历)】