C/C++复习笔记(2)
这是一篇针对学习《程序员面试宝典》过程中的笔记,这本书的质量先不去考量,他其中确实涉及了不少虽然编程过程中一般用不到但确实是有必要注意的东西,而且又是各个企业的历史真题,总有值得学习的东西。
也算临时抱佛脚吧(`・ω・´)
内容可能会比较杂,排版可能也会比较乱
MarkDown导出,有的地方会有一点点乱
CH6
C预处理命令
稍微系统一点来看这部分东西
#define
宏替换,遇到标识符则替换
#define identifier string
- 没有分号,空格分隔,一行结束
- 定义后即可成为其他宏定义的一部分
- 仅仅是文本替换,且是对可识别的文本进行替换
- 长于一行时,用
\
来续 - C中普遍用大写字母
- 注意L表示长整型,U表示无符号长整型,例
#define SECONDS_PER_YEAR (365*24*60*60)UL
P47面试例题3多了个句号。
#error
强迫编译器停止编译
调试用,在程序崩溃前给出一些文本消息
#include
说得奇奇怪怪的,没看懂
条件编译
#if
,else
,elif
,endif
if
的一般含义是,若后面的常量表达式为true
,则编译其与endif
之间的代码
#if const-expression
statement sequence
#endif
那么else
和endif
就不用多说了
ifdef
和ifndef
表达的意思是,“如果有定义”和“如果无定义”
#ifdef macroname
statement sequence
#endif
undef
取消前面的宏定义
progma
允许向编译程序传送指令
- message参数:遇到就输出消息文本
#progma message("message text")
- code_seg参数:设置程序中函数代码存放的代码段,写驱动的时候会用到
#progma code_seg(["section-name"[, "section-class"]])
-
#progma once
:仅编译一次?没看太明白 -
#progma hdrstop
:头文件编译到次为止
还可以使用#progma startup
来指定编译优先级
-
#progma resource
:将文件加入工程#progma resource "*.dfm"
-
#progma warning
:输出警告控制
#progma warning(disable:4507 34, once:4385, error:164)
#progma warning(disible:4507 34) //不显示4507和34号警告
#progma warning(once:4385) //4385号警告仅显示一次
#progma warning(error:164) //将164号警告看做错误
#progma warning(push) //保存所有警告消息的现有警告状态
#progma warning(push, n) //保存所有警告的现有警告状态,并将全局警告等级设置为`n`
#progma warning(pop) //弹出最后一个警告,`push`与`pop`之间做的所有改动取消
progma comment(...)
:将注释记录放入一个对象文件或可执行文件中
常用的lib
关键字,可以帮我们连入一个库文件
progma pack(n)
:指定结构体以n字节对齐
extern
#ifdef __cplusplus
extern "C" {
#ifdef
/*...*/
#ifdef __cplusplus
}
#endif
}
几个预编译指令的意思我们已经知道了
extern
关键字表明函数和全局变量作用范围,告诉编译器,其声明的函数和变量可以在本模块或其他模块中使用。提供给其它模块使用的函数和全局变量用extern
修饰,然后另一个模块包含它即可。这样在编译时虽然找不到,但不会报错,会在连接的时候去找。
与extern
对应的是static
。
一个程序可能包含其他语言的片段,或者不同编译器的代码。他们在注册变量保持参数和参数在栈上的布局可能不一样。、
可以使用extern
来指定一个编译与连接的规约:
extern "C" char * strcpy(char *, const char *);
而下面的代码仅表示在连接的时候调用strcpy()
:
extern char * strcpy(char * , const char *);
这个C
指的是一种连接规约,而非一种语言,如Fortran、assembler等。
为啥不一样呢?
C++支持重载,会将下面的代码
void print(int i);
void print(char c);
void print(float f);
void print(char * s);
编译为
_print_int
_print_char
_print_float
_print_string
C并不支持重载,因此都会被编译成
_print
预处理指令必须位于源文件的最前面。
P47面试试题1
类的声明
class A{
public:
A(){
/*...*/
};
~A();
}
A:~A(){
/*...*/
}
A()
是构造函数,~A()
是析构函数。可以定义在里面,也以在外面实现。
实例化和删除对象
A aa = A();
delete(&aa);
const
const
修饰指针有四种情况
int b = 500;
const int * a = &b;
int const * a = &b;
int * const a = &b;
const int * const a = &b;
1和2情况相同,就是利用*a
修改不了里面的值
想修改的话,要么改b
,要么指向其他的,也就是说,指向啥无所谓,没有修改的权限而已。
3呢,你指向啥是固定的,但是内容可以修改。必须初始化。
4最惨,除了访问就没有权限了,也要初始化。
想一下,如果不初始化,里面的东西又不能改动,那就没用了。
const
成员函数,也就是只读的。
const
的成员有数据类型,方便检测,而#define
是没有数据类型的。
sizeof()
说是sizeof()
,实际是各种东西占多大空间的问题。
|东西|字节数|
|—-|—-|
|地址|4|
|int|4|
|long|4|
|char|1|
- 如下定义的字符串,隐含
\0
char s[] = "12333"; //sizeof(s) = 6
\0
等占位符占一个字节- 结构体(根据CPU优化规则来的)
- 小于处理器位数时 结构体的大小一定是结构体里面最长的东西的整数倍
- 大于处理器位数时 以处理器位数为对齐单位
结构体需要保存到文件或者网络传输,禁用对齐
#progma pack(1) //
static
存放在全局数据区,sizeof()
够不着
sizeof()
是运算符,strlen()
是函数。
sizeof(string)
,是在堆上动态分配的,因此,值是固定的。但是书上说是4,我在VS2015下面测试却是28。应该是和它的类成员有关系
inline
和宏
inline
是安全地将代码嵌入进去,宏是简单替换。