一、#include “filename.h”和#include <filename.h>的区别 J3K=z
"/#JC}]
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 NR{wq|"
&1xCPKIr
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 xvr5$x|h
2ej7Ql_@c
<qCa9@Ea
二、头文件的作用 ou|emAV
DX>a0-Xj
加强安全检测 L[` l80
Qw5nfg3T
通过头文件可能方便地调用库功能,而不必关心其实现方式 Wgq|Q*
OG,P"sv
sGvbL-S-f:
三、* , &修饰符的位置 \U~4b_aN
S:\i
M:
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 )xGAe#E~j
[M_{~1xX
h6
\P&Z
四、if语句 :QCL9QZ'
^E
!v D
不要将布尔变量与任何值进行比较,那会很容易出错的。 #x%'U}sF
90}{4&C.^
整形变量必须要有类型相同的值进行比较 QFyL2Xes/
mCtS_"W
浮点变量最好少比点,就算要比也要有值进行限制 YdY-Jg Xm
)&DAbB!O
指针变量要和NULL进行比较,不要和布尔型和整形比较 =BsV`p7rU
i%glQT
"(koR Q
五、const和#define的比较 .p`4>XA
s:`i~hjq
const有数据类型,#define没有数据类型 ?HZp@&
KWwtL"3
个别编译器中const可以进行调试,#define不可以进行调试 $|4C]Me (
q!c(~UVw
在类中定义常量有两种方式 @u3`lhUcT
+Qs]8*^?;
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; \/-c)
Ae)xFnuq3
2、 用枚举代替const常量。 #%"q0"
OfsP5*d
y>{:[L9*
六、C++函数中值的传递方式 'Pz%c}hJ
w7nt $L5
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) NOz3_k
^S#;
void fun(char c) //pass by value $o"nTl
B.<SC
void fun(char *str) //pass by pointer
K
+7
^s,3*cAU
void fun(char &str) //pass by reference KuNLu31%
xQ?>72grP
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 f*ZU a
#GsOE#*>T
函数的类型不能省略,就算没有也要加个void [^>XRBSm
(su,=Z
mDD.D3RS
七、函数体中的指针或引用常量不能被返回 KaIKb=4L|
pA7-B>Y
Char *func(void) t2&kGf"
,OZ
{ *7Dba5B
CB7dr&>
char str[]=”Hello Word”; npP C;KD
{+N<
9(O
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 :\TMm>%q
{%jAp11y+O
return str; "EW8ll7r
D?|D)"?qb
} 5f0M{J,KC
Pz]WT1J0
函数体内的指针变量并不会随着函数的消亡而自动释放 4^_6~ YP7
H7O~So*N5
Y#U.9>h
八、一个内存拷贝函数的实现体 p l)":}/)
Iil2R}1
void *memcpy(void *pvTo,const void *pvFrom,size_t size) jKS j );
|jsI-?%8J
{ .Xg.,kW
!_glZ*tL
assert((pvTo!=NULL)&&(pvFrom!=NULL)); ;W|kc</R*
1=VyD<dNG6
byte *pbTo=(byte*)pvTo; //防止地址被改变 _K5<)( )
6:1`lsP
byte *pbFrom=(byte*)pvFrom; ci,(]T+!
Po>6I0y
while (size-- >0) ?pL|eS7
HG]ARgOB
pbTo++ = pbForm++; VO#rJ1J
AXw qN:P}
return pvTo; 7:`XE&Z
;_sJ>.=\
} ;H$Cq'
I
D2e-b
yoE-a
九、内存的分配方式 goM;Pf
"<
h'ik3mLH
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题 =D zrM%
WC_.j^sW
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 G/x6zdk
2"0VXtv6
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 gI:g/ R
!G%!zNA S
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 L3]J8oEmU
^&3vGu9
2[
sY?C
十、内存分配的注意事项 tqZ91QpW
s/1r{;q
用new或malloc分配内存时,必须要对此指针赋初值。 88Pt"[{1
hV3]1E21"
用delete 或free释放内存后,必须要将指针指向NULL ]4rmQAS7"
Q`CuZkP(
不能修改指向常量的指针数据 3G// _f
mR}8} K]L
U$:^^Zt`B
十一、内容复制与比较 +\dVC,,=^g
/N0mF< P
//数组…… QPy h.9:N
E2hsSqsu=
char a[]=”Hello Word!”; 1$Up7=Dr=
a-5UG#o
char b[10]; eI-fH
dJ"44Wu+J
strcpy(b,a); j;$f[@0o
}0~$^J
if (strcmp(a,b)==0) r$<!?Z
|:)Bo<8
{} iBE|6+g~Cj
J~x]~}V&
//指针…… fb
f&bJT
R6~6b&-8
char a[]=”Hello Word!”; tmGhJZ2j
Zf M]A)
char *p; ^P^"t^O
kn#?+Q
p=new char[strlen(a)+1]; `JIp$
Ehy(;n)\
strcpy(p,a); <n_?$ TJ
U=v>gNba
if (strcmp(p,a)==0) (4Db%Iw
;v8TT}R
{} 8;M,l2pmR{
e_-g|ukC
#kQ! GMZH
十二、sizeof的问题 n3e,vP? R
e"@r[pq-{u
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 q~>!_q]FE
5?3 v;B6
char a[]=”Hello World!” W *0!Z:?
U/c+j{=~
char *p=a; m.P
F'_)/
j'*.=cwsp
count<<sizeof(a)<<end; //12字节 S5|7D[*
eg~
Dm>Es
count<<sizeof(p)<<endl; //4字节 &"u(0q
dC<%D'L*
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 2NFk#_9e~
hMupQDv/I
void fun(char a[1000]) K-YxZAf
Tw \@]fw
{ do`'K3a"
3SM'vV0[
count<<sizeof(a)<<endl; //输出4而不是1000 \,v^v]|
+R?E @S
} fq1w <e
'3XOU.
)^UqB0C6^
十三、关于指针 yO-2.2h
6rS
? FG=
1、 指针创建时必须被初始化 ks$5$,^T2o
'>[ZfT
2、 指针在free 或delete后必须置为NULL E.yFCaL
+;H=_~b
3、 指针的长度都为4字节 D~qi6@Ga
qV=O;
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 ym
p*:lH(
4JBfA,
char *p=new char[100]; ~m R^j
{\?f|mmq
strcpy(p,”Hello World”); 2SC'Z>A
3{H!B&sb
delete []p; //注意前面的[]号 i Q3wi
mj9|q8v{+
p=NULL;
zCq6k7u
b`wT*&
5、数组指针的内容不能超过数组指针的最大容易。 ^`-Hg= d
~+\A4BW
如: 5Bcmz'?!
<)cmI .J3
char *p=new char[5]; .&=\
*cZc
tIA)LF
strcpy(p,”Hello World”); //报错 目标容易不够大 KJn 3&7
u 'ng'j'
delete []p; //注意前面的[]号 qvsfU*wo?
|rpMwkR
p=NULL; HVC|0}
M/[9ZgDc
WUDXx %
十四、关于malloc/free 和new /delete HDo=W qG
Kd#64NSi$A
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 b9f5
v&^N +>p
l 注意:malloc/free是库函数,new/delete是运算符 }WQ:Rmi
X7aj/:fXe
l malloc/free不能执行构造函数与析构函数,而new/delete可以 xAsy07J?
8BIPEY -I?
l new/delete不能在C上运行,所以malloc/free不能被淘汰 }Ny~.EV5^
3e[k 9`
l 两者都必须要成对使用 "Q23s"
I#yd/d5^
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 lKirc2
V6<Ki
:Ea]baM"
十五、C++的特性 YkV-]%c
m<9W#
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 Yh%
is-{U?-
重载和内联:即可用于全局函数,也可用于类的成员函数; `tsqnw
la!rg#)-X
Const和Virtual:只可用于类的成员函数; g.EKdvY"%H
nYY' hjZ
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 \AR3DDm
RK]."m0c~#
覆盖是指派生类函数覆盖基类函数 2wh{[Q2f
RA62Z&W3
函数名相同; 9;c]_zt
wa9{Q}wSa
参数相同; l\-(li
H
pQxi0/d p
基类函数必须有Virtual关键字; M7lMOG(\
K[|d7e
不同的范围(派生类和基类)。 3412znM&
fm% Y*<Y"
隐藏是指派生类屏蔽了基类的同名函数相同 Eh;~y*k\
KWV{wW=-
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 g>R md[!/
yYTiAvN
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 T1b9Zqc)f
8>jd2'v{
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 `S7${0e
)%OV|\5#
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 M*c`@\
tU7eW#"w
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 Ec]cCLB
8:A6Ew&\]O
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: cYTX)]^u
C44Dz.rs
将void Func(A a) 改为void Func(const A &a)。 ,Gd8 <