设为首页 加入收藏

TOP

改善C++程序的建议:语法篇1
2015-07-20 17:25:38 来源: 作者: 【 】 浏览:2
Tags:改善 程序 建议 语法

?

建议0 不要让main函数返回void

操作系统将main作为程序入口,main函数执行程序代码,最后返回程序的退出状态。但是C++中有一个好坏难定的规定:

在main函数中,return语句用于离开main函数(析构掉所有的具有动态生存时间的对象),并将其返回值作为参数来调用exit函数。如果函数执行到结尾而没有遇到return语 句,其效果等同于执行了return 0;。

也就是说编译器会协助完成返回值的问题。

然而,这样的坏处就是,当编译器不支持这个规定的时候,程序就会出错,比如

int main()

{

}

在VC下编译是成功的,在g++下编译,就会提示错误:‘main’必须返回’int‘

?

?

建议1 区分0的4个面孔

1 整型0

2 空指针NULL

3 字符串结束标记''

' '是一个字符,占8位,其二进制位表示是 00000000,在C/C++中,''作为字符串的结束标记,是唯一的结束标记

4 逻辑FALSE/false

false/true是标准C++语言里新增的关键字,而FALSE/TRUE是通过#define定义的宏:

#ifndef FALSE

#define FALSE 0

#endif

#ifndef TRUE

#defineTRUE 1

#endif

也就是说FALSE/TRUE是int类型,而false/true是bool型,两者是不一样的,bool在C++里是占用1个字节

?

建议2 避免那些有运算符引起的混乱

?

=和== :在if语句中 比较两个表达式是否相等,

if( nValue == 0)

{ ... }

如果程序员出现疲劳或精神不集中,把’==‘写成’=‘,这样if(nValue = 0),那么这个if条件是恒成立,并且nValue被赋值为0,并且不会提示错误

这恐怕不是程序员想要的。。。

但如果把常量写在前面,如if(0 == nValue){ },这样如果程序员写成if(0 = nValue){ },编译器会直接的提示错误

但是对于&和&& 、|和|| 这类运算符,就需要平时养成谨慎的习惯了。

?

?

建议3 对表达式计算顺序不要向当然

让我们来看一个例子

if(nGrade & MASK == GRAND_ONE)

{...}

我们的本意是,通过nGrade和MASK取与,然后在比较是否等于GRAND_ONE,

可是,实际上上面的代码的真实效果是if( nGrade & (MASK == GRAND_ONE)){}

这个建议的核心是,不要吝啬括号,让语义表达的更准确,这样可以减少出错

?

如: a = p() + q() * r();

三个函数p() 、q() 、r()的执行顺序可能是6种组合中的一个,所以a的值是不确定的,在这种情况下,就需要明确一种执行顺序,

int x=p();

int y = q();

a = x+y*r();

?

类似的: expr1 ? expr2 : expr3

建议4 小心宏#define使用中的陷阱

定义宏时,要使用完备的括号:

比如定义两个参数相加, #define ADD(a,b) ((a)+(b))是一个安全的方式

使用宏时,不允许参数发生变化,

?

定义宏时,用大括号将宏所定义的多条表达式括起来

?

建议5 不要忘记指针变量的初始化

局部变量的指针未初始化,可能导致程序崩溃

全局变量的指针,编译器会悄悄完成变量的初始化(0)。

?

建议6 明晰逗号分隔表达式的奇怪之处

逗号表达式是从C继承来的,其中每个表达式都会被执行,不过,整个表达式的值仅是最右边表达式的结果

如:if(++x,--y,x<20 && y >0),该语句返回的是“ x<20 && y>0”与0比较的结果

另外,逗号表达式既可以用作左值,也可以用作右值。

?

建议7 时刻提防内存溢出

C语言中的字符串库没有响应的安全保护措施,strcpy、strcat等函数操作时没有检查缓冲区大小,容易引起安全问题

好的方法是,定义一个函数,并传递确定的长度,如:

const int DATA_LENGTH = 16;

void DataCopy(char* src ,int len)

{

char dst[DATA_LENGTH];

for(int i=0;src[i] != 0 && i

cout<

if(len < DATA_LENGTH)

strcpy(dst,src);

}

这里如果,src的长度是10,当i=10时,src[10]就已经越界了。。。

?

?

建议8 拒绝晦涩难懂的函数指针

比如 void (*p[10]) (void (*)() );

1 声明一个无参数、返回空的函数指针的typedef,如:typedef void (*pfv)();

2 声明一个指向参数为pfv且返回空的函数指针, 如 : typedef void (*pFun_taking_pfv) (pfv));

3 定义数组,pFun_taking_pfv p[10];

?

建议9 防止头文件重发包含

方式一:

#ifndef __TEST_H__

#define __TEST_H__

......

#endif

方式二:

#pragma once

优缺点:方式一的缺点是宏导致的编译时间长

方式二的缺点是只是针对物理路径相同的文件,而不是文件的内容

?

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDoj -3351- Seinfeld -栈的简单.. 下一篇C++编码规范

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·Linux_百度百科 (2025-12-26 12:51:52)
·Shell 流程控制 | 菜 (2025-12-26 12:51:49)
·TCP/UDP协议_百度百科 (2025-12-26 12:20:11)
·什么是TCP和UDP协议 (2025-12-26 12:20:09)
·TCP和UDP详解 (非常 (2025-12-26 12:20:06)