一、#include “filename.h”和#include <filename.h>的区别 \D}$foHg
n2&M?MGX
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 .KF(_
92
'z">4{5
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 "IJcKoB
?)FY7[x.
LH>h]OTQF
二、头文件的作用 !24g_R[3"
WFMQ;
加强安全检测 A]m_&A#
M[KYt"v
通过头文件可能方便地调用库功能,而不必关心其实现方式 &%@>S.
' g Fewo
?/24-n
三、* , &修饰符的位置 F1&7m
)f$l
#L xfE<^
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 $
Bdxu
a`S3v
_Uup*#m
四、if语句 >I9|N}I
q%wF=<W
不要将布尔变量与任何值进行比较,那会很容易出错的。 z.
xRJ
1DM$FG_Z-
整形变量必须要有类型相同的值进行比较 ^%Fn|U\u
d4A3DTW
浮点变量最好少比点,就算要比也要有值进行限制 zM<yd#`yt8
n_-k <3
指针变量要和NULL进行比较,不要和布尔型和整形比较 J*]JH{
E1Rz<&L
;V)94YT
五、const和#define的比较 .;NoKO7)
??XtN.]7
const有数据类型,#define没有数据类型 wm/>_
K${CHKFf
个别编译器中const可以进行调试,#define不可以进行调试 u
%&4[zb
~,reS:9RZ
在类中定义常量有两种方式 @wW)#!Mou
I}1<epd ,
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; }3y Q*<
Ui;PmwQc&
2、 用枚举代替const常量。 ,\E5et4
0p!N'7N
`;#I_R_K
六、C++函数中值的传递方式 kl9<l*
1Yy*G-7}
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) dF0:'y
f`_6X~
p
void fun(char c) //pass by value ]\oE}7K%r
f{f|frs
void fun(char *str) //pass by pointer cUZ^,)8
Z
mS >I#?
void fun(char &str) //pass by reference ?=\_U
v$bR&bCT
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 u3_AZ2-;
\|Ya*8V
函数的类型不能省略,就算没有也要加个void =!PUKa3f<
5b%zpx0Y
0+"P1/
七、函数体中的指针或引用常量不能被返回 9NcC.}#-5
R,[+9U|4V
Char *func(void) >)S'`e4Gu
wfc+E9E
{ ru1FJ{n
}J\KnaKo
char str[]=”Hello Word”; 8:t1%O$
%'<m[wf^ o
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 kNTxYJ
R3} Z"
return str; Qv:J#uVw?O
m4kUA"n5
} ^tKJ}}
K9f7,/
函数体内的指针变量并不会随着函数的消亡而自动释放 %TRH,-@3h
n"Q fW~ U
%#b+ =J
八、一个内存拷贝函数的实现体 MA5BTq<&
?3Dsz
void *memcpy(void *pvTo,const void *pvFrom,size_t size) vCtag]H2@
6d|%8.q1
{ >,%7bq=T!
.%N*g[J
assert((pvTo!=NULL)&&(pvFrom!=NULL)); NuKx{y}P
oi}\;TG
byte *pbTo=(byte*)pvTo; //防止地址被改变 `(?x@Y>.Ht
{"w4+m~+te
byte *pbFrom=(byte*)pvFrom; |&a[@(N:zf
L~xzfO
while (size-- >0) bLi>jE.%.
p3(&9~s
pbTo++ = pbForm++; }9ZcO\M
5T;,wQ<
return pvTo; BFyVq
$2\k| @)s
} YC0FXN V
*FEY"W+bY
;R.l?Bg
九、内存的分配方式 2d Px s:8&
"Crm\UI6
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题 dLI`\e<r&[
3xz{[ 5<p
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 1]j_4M14aA
&`4v,l^Zi6
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 a
uz2n
1u0NG)*f
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 ,zY!EHpx
Zf%6U[{ T
;qT7BUh(%
十、内存分配的注意事项
[{!5{k!
1p9+c~4l:
用new或malloc分配内存时,必须要对此指针赋初值。 }];_ug*
"
^ 04|tda
用delete 或free释放内存后,必须要将指针指向NULL O;*.dR
p%6j2;D
不能修改指向常量的指针数据 -N[Q*;h|
sw715"L
?krgZ;Jj
十一、内容复制与比较 &Kgl\;}
Qv@Z#
//数组…… |%~sU,Y\(
.5x+FHu7
char a[]=”Hello Word!”; g+98G8R
*"D8E^9
char b[10]; enGjom
-dn\*n5
strcpy(b,a); h .Iscr^~
zbDM+;
if (strcmp(a,b)==0) '
Z}/3 dp
Dj9).lgc
{} Zu/}TS9bi
8?rRLM4
//指针…… $lMEZt8A
r%/*,lLO
char a[]=”Hello Word!”; Q0j$u[x6s
*OQr:e<}
char *p; G:2m)0bW
0UB,EI8
p=new char[strlen(a)+1]; P]G`Y>#$r
z@0*QZ.y1
strcpy(p,a); {~"6/L
+L86w7
if (strcmp(p,a)==0) R2af>R
Ibd
na9z7
{} O0gLu1*1v
*XK9-%3
MMfcY
3#%
十二、sizeof的问题 oZV=vg5Dq
=wW3Tr7~
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 ![BQ;X
[J|)DUjt
char a[]=”Hello World!” THM\-abz
m18 If
char *p=a; xNh#= 6__9
bt,^-gt@
count<<sizeof(a)<<end; //12字节 &ns !\!
89@e &h*
count<<sizeof(p)<<endl; //4字节 {g>k-.
_/_1:ivY8
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 6"Km E}
_ s]=g
void fun(char a[1000]) 0NB6S&lI^k
lr[a~ca\
{ ~_Tm S9
;y7V-sf
count<<sizeof(a)<<endl; //输出4而不是1000 bV#U&)|
2>3gC_^go
} aNpeePF)z
[*j
C
yuvt<kz
十三、关于指针 ;u'mSJI'
tZ]|3wp
1、 指针创建时必须被初始化 >Udb*76
D
~R]E=/ m|
2、 指针在free 或delete后必须置为NULL {Tp0#fi
p0xd
c3
3、 指针的长度都为4字节 tj ,*-).4%
Eg"DiI)7
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 aPq9^S*
,R1`/aRy
char *p=new char[100]; fa#]G^f
Vs~^r>
strcpy(p,”Hello World”); eiJO;%fl>l
U-ILzK
delete []p; //注意前面的[]号 s7CoUd2
\]U@=w
p=NULL; \*H/YByTb
dF{3~0+,
5、数组指针的内容不能超过数组指针的最大容易。 j[XA"DZR<
8z^?PZ/
如: R$&|*0
x+vNA J
char *p=new char[5]; qwu++9BM
^A^,/3
strcpy(p,”Hello World”); //报错 目标容易不够大 r3l}I6
_dj<xPO
delete []p; //注意前面的[]号 @^y/V@lDm
*hAeA+:
p=NULL; GqI^$5?
URDb
,@=qaU
十四、关于malloc/free 和new /delete 2,O-/A;tW*
Wiqy".YY
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 J_s?e#s
mf'N4y%
l 注意:malloc/free是库函数,new/delete是运算符 >w jWX{&?
^CTgo,uf6H
l malloc/free不能执行构造函数与析构函数,而new/delete可以 p3:x\P<|
U`JzE"ps]
l new/delete不能在C上运行,所以malloc/free不能被淘汰 +(5 H$O{h
$V~r*#$.
l 两者都必须要成对使用 GA{>=Q_~
J.:"yK""
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 .Lo$uKsW$l
I]>-~_
YH^_d3A;
十五、C++的特性 4@|K^nT`
-vI?b#
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 .b]g#Du=
Z9ciS";L
重载和内联:即可用于全局函数,也可用于类的成员函数; v@;:aN
PGMu6$
Const和Virtual:只可用于类的成员函数; C8cB Lsa[J
7Nc@7_=
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 6g!#"=ls;
R:B-4
覆盖是指派生类函数覆盖基类函数 t'4hWNR'
8Uvf9,I'
函数名相同; #6_?7 (X
MC/$:PV
参数相同; sMli! u
EuqmA7s8A
基类函数必须有Virtual关键字; ~)D2U:"^xm
0\wMlV`F
不同的范围(派生类和基类)。 kf0zL3|
E=w $r
隐藏是指派生类屏蔽了基类的同名函数相同 C/e`O|G
;u,%an<(
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 UuAn`oYhV
3 S:}fPR
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 -B$oq8)n*
US'X9=b_
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 OekcU%C
Kwfrh?
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 WUAjb,eo
4pkc9\
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 F&;g<
SD
skdSK7 n
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: pq*b"Jku1
fu9y3`
将void Func(A a) 改为void Func(const A &a)。 BgD;"GD*W
h|dVVCsN
而void func(int a)就没必要改成void func(const int &a); j*Q/vY!T
N2;T\xx,
3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。 C;wN>HE
Ka2U@fK"
4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。 `8\pihww
QY-P!JD
Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体; p{!aRB%
NaG1j+LN
ZP*Hx
%U
十六、extern“C”有什么作用? v*QobI
z]Z>+|
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。 5wRDH1z@{
l},*^Sn<5
Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。 Q <^'v>~n
b.h~QyI/W
k$}XZ,Q
十七、构造函数与析构函数 O?D*<rwD
,Zzh. z::D
派生类的构造函数应在初始化表里调用基类的构造函数; X6!u(plVQ
*FR
Eh@R
派生类和基类的析构函数应加Virtual关键字。 ;%]Q%7
C>N)~Ut
不要小看构造函数和析构函数,其实编起来还是不容易。 1]fqt[*)
;38DB o
#include <iostream.h> nWbe=z&y8[
~m[^|w
class Base W$B>O
:74^?
{ (E&}SI~
2y#4rl1Utx
public: C#p$YQf
jr*A1y*
virtual ~Base() { cout<< "~Base" << endl ; } v/8K?$"q
zkI\ji
}; Jm\'=#U#
0^]E-Zf
class Derived : public Base
,L\OhT
%D\TLY
{ wz9V)_V*
%&4sHDP
public: D._q'v<
8G1Tpn
virtual ~Derived() { cout<< "~Derived" << endl ; } '_g8fz
3
jbn{5af
}; Ngu+V
_I&0HRi
void main(void) eq"a)QB3m
a>.2Q<1
{ -}MWA>an8
C:_!zY'z
Base * pB = new Derived; // upcast %xyt4}-)m
aoco'BR F
delete pB; 45edyQ
|`U^+Nf
} !?Z}b.%W
,78QLh9:
输出结果为: '>`?T}a,
+T
[0r
~Derived 5X|=qZ
^lB1- ;ng
~Base (".`#909
/+"BU-aQk
如果析构函数不为虚,那么输出结果为 >wdR4!x!?
`{N0+n
~Base #|GP]`YT
z~A||@4'
<!Nj2>
十八、#IFNDEF/#DEFINE/#ENDIF有什么作用 rV"<1y:g
,@/b7BVv
仿止该头文件被重复引用