一、#include “filename.h”和#include <filename.h>的区别 jec03wH_0
k^Tu9}[W1
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 }U7>_b2
qnW5I_]
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 l<PGUm:_
1@yXVD/
iN*d84KTP
二、头文件的作用 to[EA6J8l
+1Si>I
加强安全检测 BS;rit:
ABNsi$]r0
通过头文件可能方便地调用库功能,而不必关心其实现方式 -le:0NUwI
mz1Xk ]nE
' :g8a=L
三、* , &修饰符的位置 `=uCp^+v
mvVVPf9
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 D4s*J21)D
7
tF1g=\
}zRYT_:
四、if语句 .2Q`. o)
Wq0h3AjR
不要将布尔变量与任何值进行比较,那会很容易出错的。 |O\(<n S
/AJ^wY
整形变量必须要有类型相同的值进行比较 f<xF+wE
$%;NX[>j
浮点变量最好少比点,就算要比也要有值进行限制 <3P?rcd,5K
n]ar\f
指针变量要和NULL进行比较,不要和布尔型和整形比较 d`StBXG!
AS|gi!OVA
P0RMdf
五、const和#define的比较 / Zz2=gDY
qzE/n
const有数据类型,#define没有数据类型 wC!(STu
a: iIfdd4'
个别编译器中const可以进行调试,#define不可以进行调试 hOfd<k\A
+hY/4Tx<
在类中定义常量有两种方式 I-kM~q_
U'" ;
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; 6TfL|W<
jt"p Js'
2、 用枚举代替const常量。 eWqJ 2Tt
rNU,(htS
LAwX9q`
六、C++函数中值的传递方式 BRQ9kK20
:eQ@I+
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) 3, ,Z
$7TYix8=
void fun(char c) //pass by value )prpG !
GK95=?f~8;
void fun(char *str) //pass by pointer &BG^:4b
~#I1!y~`
void fun(char &str) //pass by reference ~W5fJd0
IAnY+=^
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 >m}.}g8
7*'_&0
函数的类型不能省略,就算没有也要加个void :b=`sUn<X+
s7FqE>#c0
n+zXt?{u
七、函数体中的指针或引用常量不能被返回 /,Ln)?eD
]_d(YHYf
Char *func(void) 5tP0dQYd
KPW: r#d
{ |t]-a%A=w
3(^9K2.s}
char str[]=”Hello Word”; lxbbyy25
Q;m
.m2
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 x18ei@c
b44H2A.
return str; >P\Tnb"Q\
d#ld*\|
} (`3Bi]7
@=Ly#HuUM
函数体内的指针变量并不会随着函数的消亡而自动释放 y>~=o9J_u
SjlkKulMF
}y=7r!{@
八、一个内存拷贝函数的实现体 .a=M@;p
L4Nk+R;
void *memcpy(void *pvTo,const void *pvFrom,size_t size) zG [-n.
bn<&Xe
{ T:;e 73
J'@I!Jc
assert((pvTo!=NULL)&&(pvFrom!=NULL)); <+_OgF1G
9!2KpuWji
byte *pbTo=(byte*)pvTo; //防止地址被改变 U%gP2]t%cs
7dPA>5"XD
byte *pbFrom=(byte*)pvFrom; %=#&\ldPS
(~}l ?k
while (size-- >0) =C`v+NPM)|
rZJp>Q)s
pbTo++ = pbForm++; ]d$)G4X1
Oq+C<}eg
return pvTo; V_+3@C
gl]{mUZz}
} c0Q`S"o+
yc%AkhX*
gP/]05$e
九、内存的分配方式 fD,#z&
C,tlp
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题
>kC@7h5)
"ajZ&{Z
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 ,wX/cUyZ
.WyI.Y1
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 ]~ec]Y
ReSP)%oW
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 guwnYS
}E?s*iP
%A82{
十、内存分配的注意事项 NKGo E/
4`Fbl]Q
用new或malloc分配内存时,必须要对此指针赋初值。 %}j/G l5
[c>X Q
用delete 或free释放内存后,必须要将指针指向NULL Onot<}K
`awk@
不能修改指向常量的指针数据 QZh8l-!#5
/x$ jd)C
o"[qPZd>
十一、内容复制与比较 OY[N%wr!
7F+f6(hB
//数组…… xg3G
$#t&W&
char a[]=”Hello Word!”; z2"2Xqy<U
R?l>Vr
char b[10]; &p=~=&g=
*l7
ojv
strcpy(b,a); Bljh'Qp>C
i&_sbQ^
if (strcmp(a,b)==0) q/4PX
^~(bm$4r
{} =FwFqjvl
QF%@MK0zC
//指针…… &mY<e4
1
#EmZ{*
char a[]=”Hello Word!”; g{<3*,
anl?4q3;9
char *p; !_x-aro3<
bz}T}nj
p=new char[strlen(a)+1]; apw8wL2
-O(.J'=8
strcpy(p,a); j5$Sm
=3 -G
if (strcmp(p,a)==0) F'SOl*v(s5
61gZZM
{} V]vk9M2q[l
kP[ Y
4AP<mo
十二、sizeof的问题 :=~([oSNW"
r-'j#|^tz
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 R \`,Q'3
{BKI8vy
char a[]=”Hello World!” :j9;P7&"?
[=LQ,e$r7
char *p=a; mg#+%v
^[qmELW#7
count<<sizeof(a)<<end; //12字节 OM,uR3,
gVZ~OcB!W
count<<sizeof(p)<<endl; //4字节 NEJ
Nu_Z
^-=,q.[7
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 RQe#X6'h
vLkZC
void fun(char a[1000]) t%8*$"~X
N'[^n,\(:
{ `D?vmSQ
"I+wU`AIek
count<<sizeof(a)<<endl; //输出4而不是1000 yYF80mnJz
;PLby]=O
} '9^x"U9c
x>Q#Bvy
2+ 9">a@
十三、关于指针 >L=l{F6
p
Y|1kE;
1、 指针创建时必须被初始化
MNJ$/l)h
L0uN|?}
2、 指针在free 或delete后必须置为NULL >nTGvLOq
\idg[&}l}
3、 指针的长度都为4字节 le8n!Dk(
8+GlM+>4
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 Pb[wysy
,T1t`
char *p=new char[100]; eqjl$QWPJS
BQw#PXp3
strcpy(p,”Hello World”); 9nd'"$
z?E:s.4F
delete []p; //注意前面的[]号 ux-Fvwoh
v)X1R/z5xw
p=NULL; ~Jq<FVK
wAy;ZNu
5、数组指针的内容不能超过数组指针的最大容易。 QF\NHV
rGq~e|.O3
如: KeXQ'.x5O
0!!pNK%(
char *p=new char[5]; JO1c9NyKr
.\1XR
strcpy(p,”Hello World”); //报错 目标容易不够大 NFc<%#H
neOR/]
delete []p; //注意前面的[]号 9Y-s],2V
0~^opNR
p=NULL; [nflQW6
=zI
eZ7
nDaQ1
十四、关于malloc/free 和new /delete <EpP;
(u$Q
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 m2VF}%
EIr
2&5"m;<
l 注意:malloc/free是库函数,new/delete是运算符 {mueP6Gz@J
(obeEH5J
l malloc/free不能执行构造函数与析构函数,而new/delete可以 N5oao'7|A
P_i2yhpK
l new/delete不能在C上运行,所以malloc/free不能被淘汰 =">O;L.xj
v\f 41M7D
l 两者都必须要成对使用 nc&V59*
HM--`RJ
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 $7PFos%@
j7O7P+DmS
#msk'MVt
十五、C++的特性 i}M&1E
[Ma&=2h
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 &HW%0lTs%
z!t&zkAK
重载和内联:即可用于全局函数,也可用于类的成员函数; ##yi^;3Y
t5e% "}>7H
Const和Virtual:只可用于类的成员函数; XlB`Z81j
kGX`y.-[
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 JNk
]$ xz
B4&x?-0ZC
覆盖是指派生类函数覆盖基类函数 O2A Z|[*I
Ks!.$y:x
函数名相同; G|X1c}zAL
I[&z#foN=w
参数相同; tjO||]I
dkRJ^~
基类函数必须有Virtual关键字; c+-L>dsss
WvNX%se]3
不同的范围(派生类和基类)。 QbpRSdxy`$
KqaeRs.u
隐藏是指派生类屏蔽了基类的同名函数相同 aoMQ_@0
b6oPnP_3P
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 v,1.n{!;
:E'38~
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 1>l{c
oREZ^pE@
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 nG{jx_{`
J&Le*R'
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 Bz!ddAvlK
'du:Bxl`d4
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 ILTd*f
I)DLnnQQ
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: j3z&0sc2(0
Z\O ,9
将void Func(A a) 改为void Func(const A &a)。 4z[Z3|_V
T4qbyui{
而void func(int a)就没必要改成void func(const int &a); ugucq},[
)Q(tryiSi
3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。 Uj6R?E{Jt
lXL\e(ow
4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。 .ay
K+6I
^|as]x!sv
Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体; ].2q.7Yur
$eRxCX?b2
=^=9z'u"=
十六、extern“C”有什么作用? xdp{y=,[
w.J2pvyB
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。 c?b?x
6 2
Qn<J@%
Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。 [-1Nn}
I=Ws
/+
>MS}7Hk\
十七、构造函数与析构函数 )#i]exZ
#Rjm3#gc
派生类的构造函数应在初始化表里调用基类的构造函数; )N`ia%p_]
QQ1+uY
派生类和基类的析构函数应加Virtual关键字。 ;STO!^9~
|~rDEv3
不要小看构造函数和析构函数,其实编起来还是不容易。 3"!2C,3c#
)!p=0&z@{
#include <iostream.h>
<k/'mBDk
u|9^tHT>
class Base rWi9'6
L=4?vs
{ ?nj _gL
18V*Cu
public: esbxx##\
+JBhw4et;.
virtual ~Base() { cout<< "~Base" << endl ; } *sB=Ys?
qV8;;&8r
}; eJ$?T7aUf
z15(8Y@2]
class Derived : public Base 8~\Fpz|Og
qs 52)$
{ Zdj~B1
`H^Nc\P#
public: DQH _@-q
aztP`S$h
virtual ~Derived() { cout<< "~Derived" << endl ; } 2%1g%
{HvR24#
}; Af
^6
bo\|mvB~
void main(void) W&BwBp]K
fx%'7/+
{ ^fXNeBj
HSp*lHU
Base * pB = new Derived; // upcast RE!MX>sOEq
ZEUd?"gaR
delete pB; :a#]"z0
Y5cUOfYT
} DV*8Mkzg
Nr3td`;
输出结果为: %v
:a
:14O=C
~Derived p5c'gziR
m!N_TOl-^
~Base q;tsA"l
(fm\kV
如果析构函数不为虚,那么输出结果为 = J).(E89
tN";o\!}
~Base fcD$km
u%VO'}Gz
p0`Wci
十八、#IFNDEF/#DEFINE/#ENDIF有什么作用 \*!g0C8 o
"{qhk{
仿止该头文件被重复引用