本文无意推翻这些代码规范,只是对这些代码规范提出一些不足之处,只是希望大家不要盲目地迷信“权威”,也希望各开发团队在制定自己的代码规范的时候,不要无视我所说的这些东西。大家如果有什么看法,欢迎提出,不过没有营养的纯喷就算了。
1.《高质量C++/C编程指南》
1.1 规则2-2-2中的变量声明
我本科的毕业设计需要写计算四维Rǒssler超混沌系统数值解的程序,于是我就把我以前写过的计算三维Lorenz的程序改了改。这个Rǒssler超混沌系统的方程组如下(来自参考文献[3]):
涉及到的变量的声明如下:
-
double x0,y0,z0,w0; //初始条件
-
double a,b,d,e,f,g,k; //参数
-
double dt,tmax,tmin; //时间参数
如果要求每行只能声明一个变量的话,就只能这么写:
-
//初始条件
-
double x0;
-
double y0;
-
double z0;
-
double w0;
-
-
//参数
-
double a;
-
double b;
-
double d;
-
double e;
-
double f;
-
double g;
-
double k;
-
-
//时间参数
-
double dt;
-
double tmax;
-
double tmin;
感觉很费篇幅。对于计算数值解的函数体内,就更加明显:
-
double t=0.0; //时间
-
double x=x0,y=y0,z=z0,w=w0; //初始条件
-
//Runge-Kutta法临时变量——单位dt时间间隔内x、y、z、w的变化量
-
double dx1,dy1,dz1,dw1;
-
double dx2,dy2,dz2,dw2;
-
double dx3,dy3,dz3,dw3;
-
double dx4,dy4,dz4,dw4;
如果要求每行只能声明一个变量的话,就只能这么写:
-
//时间
-
double t=0.0;
-
-
//初始条件
-
double x=x0;
-
double y=y0;
-
double z=z0;
-
double w=w0;
-
-
//Runge-Kutta法临时变量——单位dt时间间隔内x、y、z、w的变化量
-
double dx1;
-
double dy1;
-
double dz1;
-
double dw1;
-
-
double dx2;
-
double dy2;
-
double dz2;
-
double dw2;
-
-
double dx3;
-
double dy3;
-
double dz3;
-
double dw3;
-
-
double dx4;
-
double dy4;
-
double dz4;
-
double dw4;
可见要求每行只能声明一个变量未必能使代码变得好看,有时会起到一些反作用。
1.2 8.5.1节:“用内联取代宏代码”
还以我的毕业设计为例
在我写的Lorenz系统的数值解的计算程序中,计算数值解的函数内的主循环体的一部分如下(
Runge-Kutta法):
-
dx1=dt*fx(x,y,z);
-
dy1=dt*fy(x,y,z);
-
dz1=dt*fz(x,y,z);
-
-
dx2=dt*fx(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0);
-
dy2=dt*fy(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0);
-
dz2=dt*fz(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0);
-
-
dx3=dt*fx(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0);
-
dy3=dt*fy(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0);
-
dz3=dt*fz(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0);
-
-
dx4=dt*fx(x+dx3,y+dy3,z+dz3);
-
dy4=dt*fy(x+dx3,y+dy3,z+dz3);
-
dz4=dt*fz(x+dx3,y+dy3,z+dz3);
-
-
x=x+(dx1+2.0*dx2+2.0*dx3+dx4)/6.0;
-
y=y+(dy1+2.0*dy2+2.0*dy3+dy4)/6.0;
-
z=z+(dz1+2.0*dz2+2.0*dz3+dz4)/6.0;
对于四维的Rǒssler系统,我将循环体改成了如下代码:
-
dx1=dt*fx(x,y,z,w);
-
dy1=dt*fy(x,y,z,w);
-
dz1=dt*fz(x,y,z,w);
-
dw1=dt*fw(x,y,z,w);
-
-
dx2=dt*fx(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0,w+dw1/2.0);
-
dy2=dt*fy(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0,w+dw1/2.0);
-
dz2=dt*fz(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0,w+dw1/2.0);
-
dw2=dt*fw(x+dx1/2.0,y+dy1/2.0,z+dz1/2.0,w+dw1/2.0);
-
-
dx3=dt*fx(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0,w+dw2/2.0);
-
dy3=dt*fy(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0,w+dw2/2.0);
-
dz3=dt*fz(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0,w+dw2/2.0);
-
dw3=dt*fw(x+dx2/2.0,y+dy2/2.0,z+dz2/2.0,w+dw2/2.0);
-
-
dx4=dt*fx(x+dx3,y+dy3,z+dz3,w+dw3);
-
dy4=dt*fy(x+dx3,y+dy3,z+dz3,w+dw3);
-
dz4=dt*fz(x+dx3,y+dy3,z+dz3,w+dw3);
-
dw4=dt*fw(x+dx3,y+dy3,z+dz3,w+dw3);
-
-
x=x+(dx1+2.0*dx2+2.0*dx3+dx4)/6.0;
-
y=y+(dy1+2.0*dy2+2.0*dy3+dy4)/6.0;
-
z=z+(dz1+2.0*dz2+2.0*dz3+dz4)/6.0;
-
w=w+(dw1+2.0*dw2+2.0*dw3+dw4)/6.0;
就以循环体的前3~4行为例,如果可以使用这样的宏函数,以后在提高超混沌系统的维数时,会好得多:
-
#define CALC_D1(VAR) d##VAR##1=dt*f##VAR (x,y,z,w)
另外,C/C++的宏函数还可以写成这样:
-
#define PRINT_VAR(VAR) std::cout << #VAR << "=" << (VAR)
所以说内联函数并不能完全取代宏函数,对于这种两情况,应当允许特例。
2.Qt编码风格(http://qt-project.org/wiki/Qt_Coding_Style_SimplifiedChinese)
2.1 “变量声明”部分中第四条“等到真正需要使用时再定义变量”
写for循环的时候,许多人都习惯把变量i的声明放在循环体内,即for(int i=0;;),但如果需要两个for循环的话,那么此变量是否还有效,冒似在不同的编译器下是不同的,所以应当再加一条,不应在for循环体及其头的语句内声明。
2.2 “大括号”部分中“控制语句的body中只有一行时不使用大括号”
-
if (a == 0)
-
if (b == 0)
-
c=1;
-
else
-
c=2;
对于这点,虽然《C/C++高质量编程》的要求比较烦索,但我还是偏向于《高质量C/C++编程》,因为如果按《高质量C/C++编程》的说法来进行的话,如果以后需要再加其它的语句,或减为一行,也就不需要再增删大括号了。
2.3 “圆括号”中“使用圆括号将表达式分组”
我觉得加减乘除运算可以不必加圆括号。
参考文献:
1.林锐 高质量 C++/C 编程指南
2.
3.
何海莲,王光义
,一个新的Rossler超混沌系统 [D],杭州电子科技大学
,2008
版权声明:本文乃pl014(panuins@gmail.com)
原创文章,如需转载,需要注明原文地址。
阅读(2297) | 评论(0) | 转发(0) |