一、#include “filename.h”和#include <filename.h>的区别 ]@EjKgs
I
g`#U~
#include “filename.h”是指编译器将从当前工作目录上开始查找此文件 IftPN6(Z
%?seX+ne
#include <filename.h>是指编译器将从标准库目录中开始查找此文件 N~Gh>{N
EifYK
jp|wc,]!
二、头文件的作用
@Hzsud
'CvZiW[_r
加强安全检测 {ib`mC^
_B2t|uQ
通过头文件可能方便地调用库功能,而不必关心其实现方式 Wo&i)S<i0F
U4gZW]F
`#hy'S:e
三、* , &修饰符的位置 2mRso.Ah
B(~D*H2T[
对于*和&修饰符,为了避免误解,最好将修饰符紧靠变量名 9I9)5`d|Jn
.|K5b]na
:}lE@Y,R
四、if语句 U1Oq"Ij~
|kn}iA@72p
不要将布尔变量与任何值进行比较,那会很容易出错的。 @0G}Q
O3Uu{'=0
整形变量必须要有类型相同的值进行比较 fN9hBC@
=~)n,5
浮点变量最好少比点,就算要比也要有值进行限制 2
UgjH
F~:5/-zs
指针变量要和NULL进行比较,不要和布尔型和整形比较 b$BUo8O}
V}( "8L
S9.jc@#.`
五、const和#define的比较 7W*OyH^
(L\tp>
E-
const有数据类型,#define没有数据类型 D4G{= Y}G
C9fJLCufC
个别编译器中const可以进行调试,#define不可以进行调试 3jQ
|C=
I^o^@C
在类中定义常量有两种方式 975KRnj
rpvm].4
1、 在类在声明常量,但不赋值,在构造函数初始化表中进行赋值; L:31toGK
_T1e##Sq,
2、 用枚举代替const常量。 '{|87kI
Cs$g]&a
t6tqv
六、C++函数中值的传递方式 m+L:\mvA
;,<s'5icyg
有三种方式:值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference) @{bf]Oc
!"wIb.j}0
void fun(char c) //pass by value QRRZMdEGs[
Ruf*aF(
void fun(char *str) //pass by pointer _*+M'3&=
yO !*pC
void fun(char &str) //pass by reference h0GXN\xI
hAY_dM
如果输入参数是以值传递的话,最好使用引用传递代替,因为引用传递省去了临时对象的构造和析构 [=iq4F'7
f"[C3o2P
函数的类型不能省略,就算没有也要加个void (Fu9lW}n
35ng_,t$
</fzBaTo
七、函数体中的指针或引用常量不能被返回 V3UEuA
n4ISHxM
Char *func(void) m~}nM |m%
}5A?WH_
{ yVW )DQ4?
y==x
char str[]=”Hello Word”; >yaRz+
4"GY0)
Q
//这个是不能被返回的,因为str是个指定变量,不是一般的值,函数结束后会被注销掉 -1@kt<Es
=lzjMRX(?
return str; ]`lTkh
Y,+$vj:y8
} U+\\#5$
+UB. M
函数体内的指针变量并不会随着函数的消亡而自动释放 KjhOz%Yt[o
S -im
o
H:CwUFL
八、一个内存拷贝函数的实现体 \E n ^Vf
RxAZ<8T_
void *memcpy(void *pvTo,const void *pvFrom,size_t size) |d{4_o90
FvRog<3X
{ (u~@@d"
Cjw|.c`
assert((pvTo!=NULL)&&(pvFrom!=NULL)); 1v`*%95
_- { > e
byte *pbTo=(byte*)pvTo; //防止地址被改变 NZv1dy`fa
&Y\`FY\
byte *pbFrom=(byte*)pvFrom; &L_(yJ~-
gg<lWeS/3
while (size-- >0) w'}b 8m(L
fi1tF/`
pbTo++ = pbForm++; /W fpA\4S
0;)4.*t
return pvTo; |TkO'QN
|A"zxNeS"
} xw`Pq6
gx3arVa
<_h
九、内存的分配方式 "zv?qS
Ty7xjIs
分配方式有三种,请记住,说不定那天去面试的时候就会有人问你这问题 ^W;\faG
_/hWzj=q
1、 静态存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、常量。 W<\KRF$S;
Fvg>>HVu
2、 栈上分配,函数内的局部变量就是从这分配的,但分配的内存容易有限。 ,XR1N$LN8_
3~Ah8,
3、 堆上分配,也称动态分配,如我们用new,malloc分配内存,用delete,free来释放的内存。 [V
=O$X_
K1jE_]@Z
L,BuzU[1S
十、内存分配的注意事项 &S/KR$^ %
wD4Kil=v
用new或malloc分配内存时,必须要对此指针赋初值。 "HlT-0F
1a`dB
~>
用delete 或free释放内存后,必须要将指针指向NULL rxt)l
?nE<Aig
不能修改指向常量的指针数据 uq'T:d
A3MVNz$wo"
2>p>AvcK
十一、内容复制与比较 JT!-Q!O}O
Ww:,O48%
//数组…… Ju#
- >]
Z!DGCw
char a[]=”Hello Word!”; ).5$c0`U&
54v}iG
char b[10]; y$'(/iyz
ApR>b%
strcpy(b,a); *{6{ZKM
xO{yr[x"L
if (strcmp(a,b)==0) DYx3NDX7
it \3-
{} oUoDj'JN{
ve<D[jQsk
//指针…… rjz$~(&m6
:A"GOc,
char a[]=”Hello Word!”; 4;=+qb
]sB-}n)
char *p; |bDUekjR
,Tjc\;~%
p=new char[strlen(a)+1]; _ ZMoPEW
Q3T@=z2j%
strcpy(p,a); g{RVxGE7
VB o=*gn,$
if (strcmp(p,a)==0) C8ek{o)%W
DgW*Br8<
{} Y'H|Tk^`
d#NG]V/
G*^4+^Vz?
十二、sizeof的问题 GUSEbIz):
)H8Rfn?
记住一点,C++无法知道指针所指对象的大小,指针的大小永远为4字节 Dn~c
yH/m@#
char a[]=”Hello World!” jnho*,X
R.^
Y'TLyc
char *p=a; dg-nv]7
b@`h]]~:
count<<sizeof(a)<<end; //12字节 Bq@_/*'*Y
bi~1d"j
count<<sizeof(p)<<endl; //4字节 }hRw{#*8
ozB2L\D7
而且,在函数中,数组参数退化为指针,所以下面的内容永远输出为4 9vZ:oO
=#0f4z
void fun(char a[1000]) F=EG#<@u
juIi-*R!
{ :Y>FuE
hh#p=Y(f
count<<sizeof(a)<<endl; //输出4而不是1000 9X/]O<i,Es
Kjzo>fIC{
} PUcxlD/a}
UB^OMB-W.m
K,j'!VQA4g
十三、关于指针 O3 NI
3127 4O
1、 指针创建时必须被初始化 >\[/e{Q"
"lLwgh;
2、 指针在free 或delete后必须置为NULL H< 51dJn~
^pwT8Bp
3、 指针的长度都为4字节 2fN2!OT
P8[rp
4、释放内存时,如果是数组指针,必须要释放掉所有的内存,如 m55|&Ux|
6--t6>5
char *p=new char[100]; \w#)uYK{i_
G{CKb{
strcpy(p,”Hello World”); FNlS)Bs
'-X[T}
delete []p; //注意前面的[]号 Q-<h)WTA
6pP:Q_U$
p=NULL; p?-qlPl
C2
4"H|D
5、数组指针的内容不能超过数组指针的最大容易。 'Y2ImSWj
z;wOtKl5r
如: N2 4J!L
/:B2-4>Q!
char *p=new char[5]; /Vdu|k=
k~Z;S QyN
strcpy(p,”Hello World”); //报错 目标容易不够大 \?tE,\Ln
uo9FLm
delete []p; //注意前面的[]号 X~g U$
7w\L<vFm
p=NULL; };Pdn7;1G:
g~p43sVV
BD,J4xH;
十四、关于malloc/free 和new /delete g>E.Snj}
k@Qd:I;;
l malloc/free 是C/C+的内存分配符,new /delete是C++的内存分配符。 L;h|Sk]{
fDjJdRS"
l 注意:malloc/free是库函数,new/delete是运算符 4v.{C"M
jZr"d*Y
l malloc/free不能执行构造函数与析构函数,而new/delete可以 ]$~\GE^
I
>aKa
l new/delete不能在C上运行,所以malloc/free不能被淘汰 TrPw*4h 9s
WeZ?L|&%w0
l 两者都必须要成对使用 2Q=I`H_
zb3,2D+P
l C++中可以使用_set_new_hander函数来定义内存分配异常的处理 g o9tvK
C <Pd_&
#$X _,+<HZ
十五、C++的特性 uA4xxY
muAgsH$/
C++新增加有重载(overload),内联(inline),Const,Virtual四种机制 =O%'qUj`q
=&Z#QD"vl
重载和内联:即可用于全局函数,也可用于类的成员函数; H
S)$|m_
+wp !hk&C5
Const和Virtual:只可用于类的成员函数; 1z3>nou2{
fG zx;<0P!
重载:在同一类中,函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数不叫重载。如果在类中调用同名的全局函数,必须用全局引用符号::引用。 <
v1.+
~jJF&*)
覆盖是指派生类函数覆盖基类函数 /%1-tGh
zJ)`snN|
函数名相同; t|P+^SL
]TVc 'G;
参数相同; _1G;!eO
G5hf m-
基类函数必须有Virtual关键字; f cnv[B..{
jr(|-!RVMN
不同的范围(派生类和基类)。 KwNOB _
0SR[)ma
隐藏是指派生类屏蔽了基类的同名函数相同 & LhQr-g
%mAwK<MY`
1、 函数名相同,但参数不同,此时不论基类有无Virtual关键字,基类函数将被隐藏。 bgeJVI
k%R(Qga
2、 函数名相同,参数也相同,但基类无Virtual关键字(有就是覆盖),基类函数将被隐藏。 qnFg7X>C,
c+{ ar^)*
内联:inline关键字必须与定义体放在一起,而不是单单放在声明中。 W2{4s
1
.On3ZN
Const:const是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。 h<G7ocu !
; GEr8_7
1、 参数做输入用的指针型参数,加上const可防止被意外改动。 s14D(:t(
Vkfc&+
2、 按值引用的用户类型做输入参数时,最好将按值传递的改为引用传递,并加上const关键字,目的是为了提高效率。数据类型为内部类型的就没必要做这件事情;如: OP|X-
IdoS6
将void Func(A a) 改为void Func(const A &a)。 b#-=Dbe
?)g [Xc;K
而void func(int a)就没必要改成void func(const int &a); <m/XGFc
_6m{zvyX>
3、 给返回值为指针类型的函数加上const,会使函数返回值不能被修改,赋给的变量也只能是const型变量。如:函数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。 Dtox/ ,"
xFcW%m>9C
4、 Const成员函数是指此函数体内只能调用Const成员变量,提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能调用Const成员变量。 ):\+%v^
t>P[Yld"
Virtual:虚函数:派生类可以覆盖掉的函数,纯虚函数:只是个空函数,没有函数实现体; G<P/COI#M5
[0D.+("EW
q'9;
十六、extern“C”有什么作用? YJ+l
\Wb}
7+Er}y>
Extern “C”是由C++提供的一个连接交换指定符号,用于告诉C++这段代码是C函数。这是因为C++编译后库中函数名会变得很长,与C生成的不一致,造成C++不能直接调用C函数,加上extren “c”后,C++就能直接调用C函数了。 F. I\?b
EMPujik-
Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。 9"?;H%.
~l('ly
~7gFddi=i
十七、构造函数与析构函数 X4L@|"ZI
\0K&2'
派生类的构造函数应在初始化表里调用基类的构造函数; M< H+$}[
'U,\5jj'Y
派生类和基类的析构函数应加Virtual关键字。 \!"3yd
Wo Z@
不要小看构造函数和析构函数,其实编起来还是不容易。 5S[:;o
x\IuM
#include <iostream.h> k*OHI/uiow
>`^;h]Q
class Base ?69E_E
]@m`bs_6
{ #\ECQF
7Y)i>[u3
public: V/xjI<