QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2953|回复: 0
打印 上一主题 下一主题

[分享] C++编程技巧

[复制链接]
字体大小: 正常 放大

1253

主题

442

听众

-586

积分

复兴中华数学头子

  • TA的每日心情
    开心
    2011-9-26 17:31
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    自我介绍
    数学中国网站(www.madio.cn)是目前中国最大的数学建模交流社区

    邮箱绑定达人 优秀斑竹奖 发帖功臣 元老勋章 新人进步奖 原创写作奖 最具活力勋章 风雨历程奖

    群组越狱吧

    群组湖南工业大学数学建模同盟会

    群组四川农业大学数学建模协会

    群组重庆交通大学数学建模协会

    群组中国矿业大学数学建模协会

    跳转到指定楼层
    1#
    发表于 2004-9-27 18:42 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta |邮箱已经成功绑定
    <><FONT style="FONT-SIZE: 12px; FONT-FAMILY: MS Shell Dlg, Tahoma, sans-serif, 宋体">C++语言是一个面向对象的语言,使用C++编写的代码更加简捷、高效,更具可维护性和可重用性。但是很多人使用了C++语言后却感到C++与C编程没有什么区别。这其实是由于对C++语言的特点和特色理解和使用不够造成的。事实上,没有任何一个程序员使用C语言的编程效率可以超过C++语言的。 ! \9 O& K( I+ d
    一、使用new和delete进行动态内存分配和释放
    8 F8 B' u4 i1 Z- V. d( a. _运算符new和delete是C++新增的过算符,提供了存储的动态分配和释放功能。它的作用相当于C语言的函数malloc()和free(),但是性能更为优越。使用new比使用malloc()有以下的几个优点: $ z$ }9 N( t9 n! @* H; K
    (1)、new自动计算要分配类型的大小,不使用sizeof运算符,比较省事,可以避免错误。 5 S; K, M+ w, m+ O
    (2、它自动地返回正确的指针类型,不用进行强制指针类型转换。
    6 U- f' I, W3 F$ L0 J% M: C2 x% ?(3)、可以用new对分配的对象进行初始化。
    5 Y5 z6 \- X8 I8 m2 m2 x2 U使用例子:
    6 `+ K0 A, f# _. ^9 ~(1)、int *p;
      g, Y* m1 r; D1 T: z- Y3 pp=new int[10]; //分配一个含有10个整数的整形数组
    $ i* J5 v3 o% g- v5 Udelete[] p; //删除这个数组
    - U! Q# V  M' p/ q" v+ X6 {(2)、int *p;
    " L8 E: h% M! O$ Cp=new int (100);//动态分配一个整数并初始化 2 W$ f: y* j  L: p+ H2 Y% D
    二、使用inline内连函数替代宏调用 : r+ Y: y" y$ c. N3 P
    对于频繁使用的函数,C语言建议使用宏调用代替函数调用以加快代码执行,减少调用开销。但是宏调用有许多的弊端,可能引起不期望的副作用。例如宏:
    " a: M& [8 q5 Z) b9 y#define abs(a) ((a)<0?(-a):(a)), 当使用abs(I++)时,这个宏就会出错。 3 G" H1 ?7 B1 Q* }0 ^9 w! N9 h( r; }
    所以在C++中应该使用inline内连函数替代宏调用,这样即可达到宏调用的功能,又避免了宏调用的弊端。 # _# m' M) h# w5 }, Y/ \; m
    使用内连函数只需把inline关键字放在函数返回类型的前面。例如:
      O4 U. w2 P4 |inline int Add(int a,int b);//声明Add()为内连函数 : m; X* u2 N( p  K8 D0 Z' P
    这样编译器在遇到Add()函数时,不再进行函数调用,而是直接嵌入函数代码以加快程序的执行。
    , J6 U! L0 r2 e  x+ M* A三、使用函数重载
    0 F' E, `& ~  G3 x2 k在C语言中,两个函数的名称不能相同,否则会导致编译错误。而在C++中,函数名相同而参数不同的两个函数被解释为重载。例如: - ]$ K6 N0 G+ l
    void PutHz(char *str); //在当前位置输出汉字 7 z( k5 ~" L& `. v3 N. Q# X* M0 g. J6 @" W
    void PutHz(int x,int y,char *str); //在x,y处输出汉字 & N# x$ ?1 V+ R$ J: A) E, }
    使用函数重载可以帮助程序员应付更多的复杂性,避免了使用诸如intabs()、fabs()、dabs()等繁杂的函数名称;同时在大型程序中,使函数名易于管理和使用,而不必绞尽脑汁地去处理函数名。
    - B1 j/ q" H) q: @% U; m四、使用引用(reference)代替指针进行参数传递 & u2 L/ _1 y( R
    在C语言中,如果一个函数需要修改用作参数的变量值的时候 ,参数应该声明为指针类型。例如: 8 B. M4 T8 o: k* p) {7 ~8 h
    void Add(int *a) {(*a)++;}   |$ \4 d& f. ?4 K7 ^% M* C+ q
    但是对于复杂的程序,使用指针容易出错,程序也难以读懂。在C++中,对于上述情况 可以使用引用来代替指针,使程序更加清晰易懂。引用就是对变量取的一个别名,对引用进行操作,就相当于对原有变量进行操作。,例如使用引用的函数定义为:
    $ B1 x2 n5 l9 U8 m4 yvoid Add(int &amp;a) (a++<IMG src="http://www.vczx.com/forum/images/smilies/wink.gif" border=0>; //a为一个整数的引用 4 P4 H# M( r- r
    这个函数与使用指针的上一个函数的功能是一样的,然而代码却更为简洁和清晰易懂。 0 m$ L2 X& f$ e: k9 V0 I, c
    五、使用缺省参数
    2 R$ v! ^8 ]: m. l在C++中函数可以使用缺省参数,例如:
    * s4 g3 a  g$ ~+ {void PutHzxy(char *str,int x=-1,int y=-1) # @+ A1 [8 ]- ^6 K. E
    { if (x==-1) x=wherex(); + \: f  T; M3 S# ]: Y3 U1 N& n
    if (y==-1) y=wherey(); 7 j/ F: b5 X% _4 p
    moveto(x,y)
    / l" |* [1 i$ q# C4 v' qPutHz(str);}
    - {7 P" |. h% T, h" `" }0 n" X. t可以有两种方式调用函数PutHzxy(),例如:
    . W  Y; R. ~9 n$ s/ pPutHzxy("C++语言");//使用缺省参数,在当前位置输出
    1 R3 |. n3 t+ h! u6 sPutHzxy("C++语言",10,10);//没有使用缺省参数 0 ?2 P- w2 A9 `. q/ b
    通常的情况下,一个函数应该尽可能地具有更大的灵活性,使用缺省参数为程序员处理更大的复杂性和灵活性提供了有效的方法。所以在C++的代码中都大量的使用了缺省参数。   a" r$ }: y3 |( E* ]2 `
    需要说明的是,所有的缺省参数必须出现在不缺省参数的右边。亦即,一旦开始定义取缺省数值的参数,就不可再说明非缺省的参数。 7 U  Q' m+ x+ W+ f9 o
    例如: 7 S+ `1 s; U/ A  C8 S% a
    void PutHzxy(char *str,int x=-1,int y=-1); //正确 ' H; y- _: I9 L* n
    void PutHzxy(int x=-1,int y=-1,char *str);//错误
    ! G( E  b2 u# Q* _; j六、使用“类”对数据进行封状 , D/ O# J# ^# W; o' Z$ a
    C语言是模块化的程序语言,通过函数的使用和文件的单独编译实现了一定的数据封装功能。但C++通过使用“类”的强大功能,在数据封装、继承等很多的方面比C做得更好。通过使用“类”把数据和对数据的所有操作集合封装在一起,建立了一个定义良好的接口,使程序员在使用一个类的时候可以只关心它的使用,而不必关心它的实现。
    ! f1 @! H% K" R. |由于函数也可一定程度上实现对数据的封装,在编写C++程序时何时使用函数,何时使用类,对于C++的初学者难以把握。根据笔者的经验,对于函数和类的使用总结出以下的方法:
    , v9 D$ ~8 [: O) }' H0 r: w首先把程序需要完成的功能划分为很多的基本子过程,一个子过程实现一种相对完整的功能。然后根据如下的规则进行划分:
    7 V2 t8 u2 L  D8 J; g(1)、如果有一些数据被两个以上的子过程同时使用,应该把这些数据和这些子过程使用“类”进行封装。
    # X; y/ }* L% O: ~6 V0 U* \(2)、如果一些数据只被一个子过程使用,应把这些数据和这个子过程合成一个函数。这些数据声明为这个函数的内部临时数据。 7 R+ o0 j9 q. f* F, m
    (3)、如果一些数据被一个子过程在不同的时间里几次使用,应把这些数据和这个子过程合成一个函数。这些数据被定义为这个函数的内部静态数据。 5 e/ \3 V, ^6 j7 Z, _& V% u) t
    (4)、如果一个子过程的功能在以后可能被修改或扩展,应该把这些过程及其使用的数合成一个类,以便以后使用继承的方法对其功能进行修改和扩充。 4 R5 y& ?  h$ a! V" K
    (5)、当(2)、(3)和(4)矛盾时,以(4)为准。
    , T! d* I# t6 n# g+ R5 x2 A: w例如,对于在C++中使用鼠标这一程序含有10多个子过程,诸如MouseOpen(),MouseHide()等等。如果是调用DOS的33H中断来实现,因为在程序中各个子过程之间没有共同使用的数据,所以应该把每个子过程定义为函数。
    4 P' U6 x  Y) \7 v  E1 \4 w/ c. H; k9 B4 I又如,如果定义了一个表示图形的数据结构,对于这个图形要进行放大、移动、旋转等子过程。因为这些子过程都要使用公共的图形数据,所以应该把这些子过程和这些图形数据定义为一个类。
    3 l; z2 u: e% t% U七、使用模板和BIDS % M9 ?+ T( G) I$ r& E
    在Borland C++ 3.1中还引入模板(template)的功能,通过模板Borland C++ 3.1实现了功能强大的BIDS(Borland International Data Structures)。使用BIDS可以不需编程实现可以存储任何数据类型的数组、链表、椎栈、队列等数据结构。下面的例子实现了一个存储整形变量的堆栈: ( r: R" O8 U; k- x: y! y
    typedef BI_StackAsVector &lt;int&gt; intstack;
    - _4 D/ X" I- Z2 ~5 bmain()
    3 I6 k* I) p1 S{instack is;//定义一个整形变量的堆栈
    ( C" v* d+ m& D3 K! E; Ffor(int I=0;I&lt;10;I++)
    / ~. e2 ]$ D, I- ]0 |3 m  Mis.push(I);//10个数压栈   q4 g$ H1 B; k
    for(I=0;I&lt;10;I++)
    2 ^, T! a/ T# T% I8 M+ Mcout&lt;&lt;is.ppop()&lt;&lt;end1; //10个数出栈 5 V/ W# u" s0 b1 V: U- i$ X3 f* D
    }
    ) ~! r0 a3 E' {; [. R' R' v0 o1 Q通过语句is.push(),is.pop()可以对堆栈进行操作。对BIDS的使用可以参照《Borland c++ 3.0程序员指南》。 / v. k3 L/ C+ `8 x6 l
    本文以Borland C++ 3.1为背景,但是适用于大多的C++编译器</FONT></P>
    " {& P- ^5 @" ^<>; M$ {8 M9 J  H8 u; U" O- K
    <><FONT style="FONT-SIZE: 12px; FONT-FAMILY: MS Shell Dlg, Tahoma, sans-serif, 宋体">__________________  h( ?5 s6 }2 O4 D. ]# {
    </FONT></P>
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    数学中国网站是以数学中国社区为主体的综合性学术社区,下分建模、编程、学术理论、工程应用等版块。从2003年11月建站以来一直致力于数学建模的普及和推广工作,目前已经发展成国内会员最多,资源最丰富,流量最大的数学建模网络平台。我们始终秉承服务大众的理念,坚持资源共享、共同进步的原则,努力营造出严肃、认真、务实、合作的学术氛围,为中国数学的发展做出应有的贡献。
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-17 02:11 , Processed in 0.400928 second(s), 52 queries .

    回顶部