一、#include “filename.h”和#include <filename.h>的区别 XAF]B,h=
j!Ys/D
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 X=6L-^o)
oz:J.<j24Z
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 d3?gh[$
:mCGY9d4L
+|+fDQI
二、头文件的作用 _f "I%QTL
*"F*6+}w"
加强安全检测 h<?I?ZR0$
cMy?&
通过头文件可能方便地调用库功能,而不必关心其实现方式 F{7
BY~d
L7(.dO0C
2y8FP#
三、* , &修饰符的位置 ;9=4]YZt
B}p.fE
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 6OPNP0@r
yfFe%8w_vw
.1J`>T?=Q
四、if语句 +U<Ae^V
S*3$1BTl
不要将布尔变量与任何值进行比较,那会很容易出错的。 4T&Jlu?:
p{r{}iYI
整形变量必须要有类型相同的值进行比较 aa!1w93?i
b^8"EBo
浮点变量最好少比点,就算要比也要有值进行限制 V)`Q0}
+&_n[;
指针变量要和NULL进行比较,不要和布尔型和整形比较 _J"J[$
CSm(yB{|pC
:t+LuH g
五、const和#define的比较 5HvYy
*B/
O,J,Q|`H&
const有数据类型,#define没有数据类型 Z$YG'p{S
+'` ^ N
个别编译器中const可以进行调试,#define不可以进行调试 {=R
vFA
OQuTM[W
在类中定义常量有两种方式 !a'{gw
\4*i;a.kU
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; waV4~BdL
}zeKf/?'
2、 用枚举代替const常量。 Xa>c]j
RhjU^,%
S |@
Y !
六、C++函数中值的传递方式 ;Oqbfl#%
[vdC $9z,
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) q> #P|
g@>y`AFnr
void fun(char c) //pass by value %-!:$ 1;
a[lx&CHgI
void fun(char *str) //pass by pointer !$o9:[B
E/ku VZX
void fun(char &str) //pass by reference AucX4J<
e=u}J%|
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 A#79$[>w
N *n?hN
函数的类型不能省略,就算没有也要加个void aMJ9U)wnK
@(tuE
$~A\l@xAG
七、函数体中的指针或引用常量不能被返回 zfml^N
gp{P _
Char *func(void) Qcs0w(
*OKve
{ )7rMevF(xJ
*K=me/
3
char str[]=”Hello Word”; U:IeMf-;
I)G.tJZ
e
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 3_ =:^Z
qRZLv7X*j
return str; ,76nDXy`
mO\=#Q>
} a>nV!b\n5
r3Ih]|FK#
函数体内的指针变量并不会随着函数的消亡而自动释放 D4GXZX8K
D2#.qoP #
:4238J8
八、一个内存拷贝函数的实现体 ."v&?o
Ck]
'DH_ihZ
void *memcpy(void *pvTo,const void *pvFrom,size_t size) n ZS*"O#L
g[xn0rG
{ 3Q+THg3~?
qSL~A-
assert((pvTo!=NULL)&&(pvFrom!=NULL)); l)1ySX&BU
Nx(y_.I{K
byte *pbTo=(byte*)pvTo; //防止地址被改变 04z2gAo
=Sn!'@%U]
byte *pbFrom=(byte*)pvFrom; *_yp]z"
K~z9b4a>
while (size-- >0) /#?i +z
#+P)X_i`
pbTo++ = pbForm++; \RTX fe-`
-Ar 3>d
return pvTo; K<Y-/t
zd[cp@
} Lec%kC
}EHmVPe
r|7 hm:F)
九、内存的分配方式 rw dj
}Rq-IRa'
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题 i+.b R.WO
Wv)2dD2I
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 We#O'm
`L}Irt}
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 N+ R/ti
P!2[#TL0
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 ,t>/_pI+=
$yg}HS7HC
C0Ti9
十、内存分配的注意事项 ldm=uW
NvlG@^&S
用new或malloc分配内存时,必须要对此指针赋初值。 !.k
~x}=lK N
用delete 或free释放内存后,必须要将指针指向NULL .:s**UiDR
8/E?3a_g-
不能修改指向常量的指针数据 Fop"m/
uU00ZPS*G[
X<"W@
十一、内容复制与比较 %7rWebd-
o%A@
OY
//数组…… zc-.W2"Hu
J;BG/VI1
char a[]=”Hello Word!”; +hS}msu'
:ITz\m
char b[10]; Kth^WHL
x:Kca3p v_
strcpy(b,a); #r)c@?T@j
"ealYveu
if (strcmp(a,b)==0) u_U51C\rb
j^Z3
{} PDssEb7
r0\cgCn
//指针…… ~3 z10IG
v
~%6!Tr
char a[]=”Hello Word!”; O-vvFl#4
kST
char *p; R:v`\
1)M>vdrP
p=new char[strlen(a)+1]; yeNC-U<
5ff66CRw
strcpy(p,a); # 1,(I
a4! AvG
if (strcmp(p,a)==0) EkqsE$52
x3my8'h@
{} `W[oLQ
]7^YPFc+
ef!V EtEOv
十二、sizeof的问题 BY$%gIB6>
,Tyh._sa
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 ~Hs a6F&F
~z!U/QR2
char a[]=”Hello World!” NLC}XL
E$rn^keM
char *p=a; rf8`|9h"7
"sRR:wzQu
count<<sizeof(a)<<end; //12字节 .yF7{/
#.%;U' #O
count<<sizeof(p)<<endl; //4字节 P Z;O
pp
MqI!i>
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 7Q.?]k&
Y0U<l1(|
void fun(char a[1000]) ^YKEc0"w(
}45&s9m=
{ Ydu=Jg5u7
Qp${/
count<<sizeof(a)<<endl; //输出4而不是1000 sEL[d2oO
W$P)fPU'
} @&d/}Mx"t
Jh[fFg]
yHhBUpIo
十三、关于指针 |k+Y >I&
y4Plm.
1、 指针创建时必须被初始化 6kKIDEX
X4Eq/q"
2、 指针在free 或delete后必须置为NULL r>`65o
/W/ =OPe
3、 指针的长度都为4字节 >9|/sH@W
w.Ft-RXA W
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 aC$hg+U$G
a3037~X
char *p=new char[100]; \?)<==^
WrL&$dEJ?M
strcpy(p,”Hello World”); U)+Yh
}}l04kN_
delete []p; //注意前面的[]号 fXBA
P10#
O6;7'
p=NULL; 7WW@%4(
QE$sXP7&u
5、数组指针的内容不能超过数组指针的最大容易。 y%\kgWV
H{`S/>)[
如: m>? OjA!
m
Fwx},dl
char *p=new char[5]; *9((b;Ju
Yyby 1
strcpy(p,”Hello World”); //报错 目标容易不够大 QkwBw^'_5
7\K=8G
delete []p; //注意前面的[]号 3j(GcR9
7
rOziKZ"
p=NULL; <`b)56v:+
X[}5hZcX
uG2Hzav
十四、关于malloc/free 和new /delete O[;>Y'zqC%
uJm9h(xq
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 .T/\5_Bx
vVmoV0kGt
l 注意:malloc/free是库函数,new/delete是运算符 s7iguFQ
8AVM(d@
l malloc/free不能执行构造函数与析构函数,而new/delete可以 INE8@}e
-Yy,L%E]F:
l new/delete不能在C上运行,所以malloc/free不能被淘汰 Id(L}i(X
{d(@o!;Fi
l 两者都必须要成对使用 frk(2C8T
iu2{%S)w
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 G0|j3y9$
cWP34;NNM
m49GCo k+
十五、C++的特性 ~%B^`s
=M)+O%`*6
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 u!];RHOp|
)}1J.>5
重载和内联:即可用于全局函数,也可用于类的成员函数; r%JJ5Al.S
8/x@|rjW
Const和Virtual:只可用于类的成员函数; #7+oM8b
3@*J=LGhKc
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 ^i2W=A'P
*pCT34'--
覆盖是指派生类函数覆盖基类函数 J84Q|E
+HQX]t:Y
函数名相同; lO9ML-8C1
B)O{+avu
参数相同; (hS
j4Cp
ds,NNN<HW
基类函数必须有Virtual关键字; 9sifc<za
0{j]p^'<
不同的范围(派生类和基类)。 u1xCn\
hMh8)S
隐藏是指派生类屏蔽了基类的同名函数相同 Ro`9Ibqr
YN#i^(
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 De@GNN"-
_$ ]3&P
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 ]
hGU.C"(
Lqb9gUJ:U
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 #!l\.:h%
d:.S]OI0
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 x}$SB%9/
Ly0^ L-~|
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 *Fb]lM7D
k*d0ws#<l
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: Va"Q1 *"
fgK1+sW
将void Func(A a) 改为void Func(const A &a)。 +]
>o@
Tz[ck'k
而void func(int a)就没必要改成void func(const int &a); 3,=97Si=
F~2bCy[Z
3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。 *JDQaWzBd
z^j7wMQ
4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。 f^b.~jXSR}
z'Atw"kA
Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体; NKd}g
I !=ew |
'/%]B@!
十六、extern“C”有什么作用? zgXg-cr
4t]ccqX*{
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。 'hN_H}U
+sq'\Tbp
Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。 S=B?bD_,c
,$s
NfW
ZxLd h8v.
十七、构造函数与析构函数 (3~h)vaJ
jR[VPm=
派生类的构造函数应在初始化表里调用基类的构造函数; 82l$]W 4
lKWe=xY\B
派生类和基类的析构函数应加Virtual关键字。 \9j +ejGf
(Ild>_Tdb`
不要小看构造函数和析构函数,其实编起来还是不容易。 d$qivct
f]%:.N~1w
#include <iostream.h> 5]pvHc
#@FMH*?xX6
class Base Z0HfrK#oU
=?]H`T:
{ LK\L}<;1V
yuIy?K
public: ,Ta k',
B;x5os
virtual ~Base() { cout<< "~Base" << endl ; } pURtk-Fr2
WxLbf+0o
}; Od_xH
""$vaqt
class Derived : public Base oGt,^!V1
1T&NU
{ \PReQ|[ah
{Tx"G9
public: 'u@,,FFz[K
gQ90>P:
virtual ~Derived() { cout<< "~Derived" << endl ; } yp}J+/PX}
QS7<7+
}; NULew]:5
|i_+b@Lul
void main(void) _y:-_q
skr dL.5
{ %8Eu{3
@^P<(%p
Base * pB = new Derived; // upcast (;\"
K?
8Of.n7{
delete pB; B&