一、#include “filename.h”和#include <filename.h>的区别 4)E|&)-fu8
&*ZC0V3
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 F_ _H(}d
mf~Lzp
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 x57'Cg \
-sx-7LKi
VlV)$z_
二、头文件的作用 <%/:w/
tPzM7
n|
加强安全检测 bCt_yR
6yp+h
通过头文件可能方便地调用库功能,而不必关心其实现方式 W'd/dKUx
oX#9RW/ >I
-P*xyI
三、* , &修饰符的位置 6_Fpca3L
UMv"7~
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 :;<\5Oy
^
1=ip,D
5(KG=EHj_
四、if语句 KKV)DExv?
7_1W:-A7W
不要将布尔变量与任何值进行比较,那会很容易出错的。 B'!PJj
=s6E/K
整形变量必须要有类型相同的值进行比较 fls#LcI9>6
xV?*!m$V%R
浮点变量最好少比点,就算要比也要有值进行限制 z6Fun
yX3PUO9
指针变量要和NULL进行比较,不要和布尔型和整形比较 phe"JNML
"zXGp7Q'#
Ys)+9yPPn
五、const和#define的比较 m^5s>hUl
/AoVl'R
const有数据类型,#define没有数据类型 |z T%$
*WD;C0?z
个别编译器中const可以进行调试,#define不可以进行调试 ,v|CombIc.
v)%[
在类中定义常量有两种方式 [Yn;G7cK
N*HH,m&
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; JUmw$u
Ko]QCLL
2、 用枚举代替const常量。 4VC/-.At
9armirfV'P
`~0P[>|+
六、C++函数中值的传递方式 zU=YNrn
zLo;.X[Y
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) KxGKA
m\/>C|f\
void fun(char c) //pass by value R9bhC9NP
tx gvVQ
void fun(char *str) //pass by pointer NYGmLbq
<&KLo>B^
void fun(char &str) //pass by reference /cM 5
Q
+R3H,
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 U2VV[e)Z!
>pN;J)H
函数的类型不能省略,就算没有也要加个void 7N!tp,?
zUNH8=U
10/x'#(
七、函数体中的指针或引用常量不能被返回 Ri9Kr
id3)6}
Char *func(void) 56"#Syj
x GwTk
{ poTl|y @
zoJ_=- *s
char str[]=”Hello Word”; Wk7L:uK
P=&'wblm?
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 2%`^(\y
D!c1;IHZ
return str; f<'n5}{RO0
a$~IQ2$|6
} E(7@'d{o
B:B8"ODV
函数体内的指针变量并不会随着函数的消亡而自动释放 a|8|@,
,LoMt ]H
~?2rGE
八、一个内存拷贝函数的实现体 #Tup]czO
/A%om|+Gq
void *memcpy(void *pvTo,const void *pvFrom,size_t size) bELIRM9
71JM
[2
{ )3BR[*u*
=X)Q7u".7
assert((pvTo!=NULL)&&(pvFrom!=NULL)); v<{wA`'R+
A Z]P+v
byte *pbTo=(byte*)pvTo; //防止地址被改变 -08&&H
Rrh<mo(yj#
byte *pbFrom=(byte*)pvFrom; }Q47_]5
: =
]sq}IN
while (size-- >0) JmnBq<&,0
R)sp
pbTo++ = pbForm++; |\i:LG1
V"w`!
return pvTo; |De!ti
}pbBo2
} ^2C0oX
IXbdS9,>F
IlcNT_
5a8
九、内存的分配方式 ?BWHr(J
M(_^'3u
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题 (45NZBs
<QYCo1_
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 A/ 7r:yO
gJ<@;O8zu0
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 fBHkLRFH
Y1$ #KC
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 sN6 0o 7.
)?!vJb"
MV
Hz$hyB
十、内存分配的注意事项 "z^BKb5
2$o2.$i81
用new或malloc分配内存时,必须要对此指针赋初值。 1zh$IYrd
4w;rl(s
用delete 或free释放内存后,必须要将指针指向NULL g4~X#}:z$O
8O"x;3I9
不能修改指向常量的指针数据 34X(J-1\|i
f}L>&^I)
${jA+L<J
十一、内容复制与比较 Kj~>&WU
XR{5]lKt_
//数组…… yq/[ /*7^
NmH}"ndv+
char a[]=”Hello Word!”; }9L 40)8
w/lXZg
char b[10]; Paae-EmC
U@o2gjGN
strcpy(b,a); K*([9VZ
_7-"VoX
if (strcmp(a,b)==0) WHlD%u
|#DC.Ga!
{} O!#L#u53
wQF&GGYR
//指针…… <7vI h0
&,m'sQ
char a[]=”Hello Word!”; I><99cwFI
yRgDhA
char *p; b5iIV1g
w,M1`RsK
p=new char[strlen(a)+1]; JxX
jDYrU
o{ ,ba~$.w
strcpy(p,a); *Gk<"pEeS
M!xm1-,[
if (strcmp(p,a)==0) DiZ!c"$
5@w'_#!)
{} <Z\MZ&{k{*
:0J-ek.;
jw`&Np2Q
十二、sizeof的问题 pl
jV|.?
]ro1{wm!WU
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 *eJhd w*
A^T~@AO
char a[]=”Hello World!” SX_kr^#
<6d{k[7fz)
char *p=a; +XU$GSw3(
xWC\954
count<<sizeof(a)<<end; //12字节 1jZDw~
eZ8Y"i\!y
count<<sizeof(p)<<endl; //4字节 _|^&eT-u
d&[M8(
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 *pcbwd!/
ZaukMEq
void fun(char a[1000]) oW
yN:Qh
b6LC$"t0
{ E]HND.`*>
D+*uKldS;
count<<sizeof(a)<<endl; //输出4而不是1000 +WV_`Rx#
e 5WdK
} >6.[i@RmWU
Xa? 6#
)+jK0E1
十三、关于指针 ;qMnO_E
eI/\I:G{f
1、 指针创建时必须被初始化 Rk437vQD,
2;Y@3d:z
2、 指针在free 或delete后必须置为NULL yZj}EBa
;qT!fuN;
3、 指针的长度都为4字节 (!XYH@Mz<w
=u:6b} =
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 &9RW9u "
NE=#5?6%g7
char *p=new char[100]; _Cv[`e.
*uI hxMX
strcpy(p,”Hello World”); |mQtjo
)"pxry4v7J
delete []p; //注意前面的[]号 <6}f2^
c]g<XVI
p=NULL; >'2w\Uk~:
aowPji$H
5、数组指针的内容不能超过数组指针的最大容易。 W[1f]w3
RAv RNd
如: (N~zJ.o
8Y{}p[UFT
char *p=new char[5]; wH(vX<W-E
G+ $)W
u
strcpy(p,”Hello World”); //报错 目标容易不够大 5KC\1pei
$8X tI
delete []p; //注意前面的[]号 | `)V^e_
%/6e"o
p=NULL; xnhDW7m
}(g+: ]p-
.qqb>7|q
十四、关于malloc/free 和new /delete Pw^c2TQ
Ye\*b?6
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 f@F^W YQm
`:bvuc(
l 注意:malloc/free是库函数,new/delete是运算符 -NflaV~
>DL-Q\U
l malloc/free不能执行构造函数与析构函数,而new/delete可以 o$H Jg
|`94W j<
l new/delete不能在C上运行,所以malloc/free不能被淘汰 v'bd.eqw
Sf4h!ly
l 两者都必须要成对使用 [A%e6
02# b:
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 11@2 ;vw
LjH&f 4mY
qV, $bw
十五、C++的特性 y
8d`},
Zjp5\+hHV
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 eJ=Y6;d$
OB*Xb*HN
重载和内联:即可用于全局函数,也可用于类的成员函数; iRj x];:Vu
d4/`:?w
Const和Virtual:只可用于类的成员函数; LO$#DHPt
Q:fUM[
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 YP\4XI
'Qs3
覆盖是指派生类函数覆盖基类函数 %:be{Y6
6(<~1{
X%
函数名相同; ]=86[A-2N
Y9H *S*n
参数相同; ev;5?9\E
tN'- qdm
基类函数必须有Virtual关键字; O%++0k;
&6|^~(P?
不同的范围(派生类和基类)。 {HRxyAI!
dl7p1Cr
隐藏是指派生类屏蔽了基类的同名函数相同 *F8uu.
a9@l8{)RX
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 ".Deu|>
K3r>nGLBo
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 dn)tP6qc/
H:{(CY?t
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 k+Ma_H`
i:Z.;z$1
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 QhE("}1
]N(zom_0d
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 Dpp52UnTE
Ng;b!S
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: d$?n6|4
,f/IG.
将void Func(A a) 改为void Func(const A &a)。 AZ]SRz9mKY
]-s`#
而void func(int a)就没必要改成void func(const int &a); ]O9f"cj
Uwm[q+sTp
3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。 <T.3ZZ%
h'YcNkM
2>
4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。 Aya;ycsgE
AFm*60C
Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体; BE2\? q-
y1"^S
0&rH 9
十六、extern“C”有什么作用? VGDEP!)-8
GLKN<2|2@y
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。 5W]N]^v
TaHi+
Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。 tSXjp
knK=ENf;e
;'18
十七、构造函数与析构函数 _8b>r1$
vVN[bD<
派生类的构造函数应在初始化表里调用基类的构造函数; ={i&F
M"$RtS|h
派生类和基类的析构函数应加Virtual关键字。 ]MA)='~
bQN4ozSi
不要小看构造函数和析构函数,其实编起来还是不容易。 by
y1MgQd
sImxa`kb
#include <iostream.h> J0WXH/:
K?O X
class Base Zn 5m.=z
/h.3<HI."*
{ VX>t!JP p
Z%n.:I<%ZV
public: D>x'3WYR
LYq2A,wm$
virtual ~Base() { cout<< "~Base" << endl ; } (PrPH/$
<ZvPtW
}; BLH3$*,H
UCj#t!Mw
class Derived : public Base Dp6"I!L<|
5~R{,]52
{ S| -{wC%
w>q_8V_K
public: uy-Ncy
TtjSLkF
virtual ~Derived() { cout<< "~Derived" << endl ; } I8%'Z>E(
B)cb}.N:
}; NizJq*V>
.-26 N6S
void main(void) nT.2jk+
'nDT.i
{ I/-w65J]
CY).I`aJ
Base * pB = new Derived; // upcast z`:^e1vG
gGdYh.K&e5
delete pB; awW\$Q
`M<G8ob
} yhn
$4;m
C`_D{r
输出结果为: 5F+ f '~
! tPK"k
~Derived ZXDMbMD
;Wh[q*A
~Base [^=8k2
0|Ft0y`+
如果析构函数不为虚,那么输出结果为 !9cP NIi
9C~GL,uKs
~Base n *0F
:Du{8rV
u]-El}*[
十八、#IFNDEF/#DEFINE/#ENDIF有什么作用 9/KQAc*
B;7s ]R
仿止该头文件被重复引用