您的位置:首页 > 编程语言 > C语言/C++

c语言开发格式规范总结

2017-09-24 20:34 176 查看
“软件工程(C编码实践篇)”实验报告

实验二:命令行菜单小程序V1.0,具体要求参见视频

程欣+《软件工程(C编码实践篇)》MOOC课程作业

目录

实验要求

实验过程

实验心得

实验总结

附录:从非实验楼环境提交代码

1. 实验要求

1、代码风格规范:

代码风格的原则:简明、易读、无二义性;

缩进、命名、注释等代码编排的风格规范;

《构建之法》4.1代码规范

高质量C++/C编程指南(林锐)

2、具体要求(参照视频中的具体实验过程):

实现一个命令行的菜单小程序,执行某个命令时调用一个特定的函数作为执行动作,实现的命令个数不少于8个;

类似ftp的help目录或者bash的help目录;

程序循环、接收用户的命令,如help、others等命令;

可以广泛通用的命令行菜单子系统组件,可方便地定制而嵌入到其他系统;

实验过程:

1. 在GitHub上先建一个库lab2 ,然后clone到本地

je-vie@jevie-virtual-machine:~$ cd Desktop/
je-vie@jevie-virtual-machine:~/Desktop$ cd workspace/
je-vie@jevie-virtual-machine:~/Desktop/workspace$ git clone https://github.com/Je-vie/lab2.git fatal: destination path 'lab2' already exists and is not an empty directory.
je-vie@jevie-virtual-machine:~/Desktop/workspace$ cd ..
je-vie@jevie-virtual-machine:~/Desktop$ git clone https://github.com/Je-vie/lab2.git Cloning into 'lab2'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
Checking connectivity... done.

je-vie@jevie-virtual-machine:~/Desktop$ cd lab2
je-vie@jevie-virtual-machine:~/Desktop/lab2$ ls
menu.c  README.md
je-vie@jevie-virtual-machine:~/Desktop/lab2$ vi menu.c


2 编辑一个命令行小程序 代码如下:

void monthDay()
{
char arr[][15] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
int monthDay;
printf("请输入数字1-12\n");
scanf("%d", &monthDay);
if (monthDay>=1 && monthDay<=12)
{
printf("%s\n", arr[monthDay-1]);
}
else
{
exit(0);
}
}

void season()
{
char arr[][12] = {"Spring", "Summer", "Autumn", "Winter"};
int season;
printf("请输入数字1-4\n");
scanf("%d", &season);
if (season>=0 && season<=4)
{
printf("%s\n", arr[season-1]);
}
else
{
exit(0);
}
}

void Ask()
{
printf("你可以询问如下问题\ninput 1 :询问星期的英文\ninput 2 :询问月份的英文\ninput 3 :询问季节的英文\ninput 0 :退出\n");
}

void JudgeAndOutput(int inputNumber)
{
if (inputNumber == 0)
{
exit(0);
}
else if(inputNumber == 1)
{
weekDay();
}
else if(inputNumber == 2)
{
monthDay();
}
else if(inputNumber == 3)
{
season();
}
}

while(1)
{
int inputNumber;
Ask();
scanf("%d", &inputNumber);
JudgeAndOutput(inputNumber);
}
}


3 代码运行

je-vie@jevie-virtual-machine:~/Desktop/lab2$ vi menu.c
je-vie@jevie-virtual-machine:~/Desktop/lab2$ gcc menu.c -o menu
je-vie@jevie-virtual-machine:~/Desktop/lab2$ ./menu
你可以询问如下问题
input 1 :询问星期的英文
input 2 :询问月份的英文
input 3 :询问季节的英文
input 0 :退出
1
请输入数字1-7
2
Tuesday
你可以询问如下问题
input 1 :询问星期的英文
input 2 :询问月份的英文
input 3 :询问季节的英文
input 0 :退出
2
请输入数字1-12
12
December
你可以询问如下问题
input 1 :询问星期的英文
input 2 :询问月份的英文
input 3 :询问季节的英文
input 0 :退出
3
请输入数字1-4
3
Autumn
你可以询问如下问题
input 1 :询问星期的英文
input 2 :询问月份的英文
input 3 :询问季节的英文
input 0 :退出
0
je-vie@jevie-virtual-machine:~/Desktop/lab2$


4 上交git

je-vie@jevie-virtual-machine:~/Desktop/lab2$ git add menu.c
je-vie@jevie-virtual-machine:~/Desktop/lab2$ git commit -m "一个命令行小程序"
[master 1606047] 一个命令行小程序
1 file changed, 110 insertions(+)
create mode 100644 menu.c
je-vie@jevie-virtual-machine:~/Desktop/lab2$ git push
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': Je-vie
Password for 'https://Je-vie@github.com':
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 1.04 KiB | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/Je-vie/lab2.git 2222d65..1606047  master -> master
je-vie@jevie-virtual-machine:~/Desktop/lab2$


5 实验总结

语言开发要注意格式规范,使得代码可读性好,下面记录几个比较常见的c语言开发中要注意的格式问题

程序块要采用缩进风格编写,缩进的空格数为4个。

相对独立的程序块之间、变量说明之后必须加空行。比如变量定义和函数之间空一格。

较长的语句要分成多行书写,长表达式要在低优先级操作符处划分新行,操作符放在新行之首,划分出的新行要进行适当的缩进,使排版整齐,语句可读。

例如

perm_count_msg.head.len = NO7_TO_STAT_PERM_COUNT_LEN

+ STAT_SIZE_PER_FRAM * sizeof( _UL );

循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分,长表达式要在低优先级操作符处划分新行,操作符放在新行之首。

例如

if ((taskno < max_act_task_number)

&& (n7stat_stat_item_valid (stat_item)))

{

… // program code

}

不允许把多个短语句写在一行中,即一行只写一条语句。

例如

如下例子不符合规范。

rect.length = 0; rect.width = 0;

应如下书写

rect.length = 0;

rect.width = 0;

if、for、do、while、case、switch、default等语句自占一行,且if、for、do、while等语句的执行语句部分无论多少都要加括号{}。

例如

如下例子不符合规范。

if (pUserCR == NULL) return;

应如下书写:

if (pUserCR == NULL)

{

return;

}

程序块的分界符(如C/C++语言的大括号‘{’和‘}’)应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、switch、case语句中的程序都要采用如上的缩进方式。

逗号、分号只在后面加空格。

int a, b, c;

比较操作符, 赋值操作符”=”、 “+=”,算术操作符”+”、”%”,逻辑操作符”&&”、”&”,位域操作符”<<”、”^”等双目操作符的前后加空格。

if (current_time >= MAX_TIME_VALUE)

a = b + c;

a *= 2;

a = b ^ 2;

“!”、”~”、”++”、”–”、”&”(地址运算符)等单目操作符前后不加空格。

p = ‘a’; // 内容操作”“与内容之间

flag = !isEmpty; // 非操作”!”与内容之间

p = &mem; // 地址操作”&” 与内容之间

i++; // “++”,”–”与内容之间

“->”、”.”前后不加空格。

p->id = pid; // “->”指针前后不加空格

if、for、while、switch等与后面的括号间应加空格,使if等关键字更为突出、明显。

if (a >= b && c > d)

一般情况下,源程序有效注释量必须在20%以上。

说明:注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。

说明性文件(如头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。

示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。

/[b]***************************************[/b]

Copyright (C), 1988-1999, Huawei Tech. Co., Ltd.

File name: // 文件名

Author: Version: Date: // 作者、版本及完成日期

Description: // 用于详细说明此程序文件完成的主要功能,与其他模块

// 或函数的接口,输出值、取值范围、含义及参数间的控

// 制、顺序、独立或依赖等关系

Others: // 其它内容的说明

Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明

1. ….

History: // 修改历史记录列表,每条修改记录应包括修改日期、修改

// 者及修改内容简述

1. Date:

Author:

Modification:

2. …

[b]***************************************[/b]/

15. 函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、返回值、调用关系(函数、表)等。

示例:下面这段函数的注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。

/[b]***************************************[/b]

Function: // 函数名称

Description: // 函数功能、性能等的描述

Calls: // 被本函数调用的函数清单

Called By: // 调用本函数的函数清单

Table Accessed: // 被访问的表(此项仅对于牵扯到数据库操作的程序)

Table Updated: // 被修改的表(此项仅对于牵扯到数据库操作的程序)

Input: // 输入参数说明,包括每个参数的作

// 用、取值说明及参数间关系。

Output: // 对输出参数的说明。

Return: // 函数返回值的说明

Others: // 其它说明

[b]***************************************[/b]/

16. 边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。不再有用的注释要删除。

17. 注释应与其描述的代码相近,对代码的注释应放在其上方或右方(对单条语句的注释)相邻位置,不可放在下面,如放于上方则需与其上面的代码用空行隔开。

18. 注释与所描述内容进行同样的缩排。

说明:可使程序排版整齐,并方便注释的阅读与理解。

示例:如下例子,排版不整齐,阅读稍感不方便。

void example_fun( void )

{

/* code one comments */

CodeBlock One

/* code two comments */

CodeBlock Two

}

应改为如下布局。

void example_fun( void )

{

/* code one comments */

CodeBlock One

/* code two comments */

CodeBlock Two

}

19. 标识符的命名要清晰、明了,有明确含义,同时使用完整的单词或大家基本可以理解的缩写,避免使人产生误解。

说明:较短的单词可通过去掉“元音”形成缩写;较长的单词可取单词的头几个字母形成缩写;一些单词有大家公认的缩写。

示例:如下单词的缩写能够被大家基本认可。

temp 可缩写为 tmp ;

flag 可缩写为 flg ;

statistic 可缩写为 stat ;

increment 可缩写为 inc ;

message 可缩写为 msg ;

20. 对于变量命名,禁止取单个字符(如i、j、k…),建议除了要有具体含义外,还能表明其变量类型、数据类型等,但i、j、k作局部循环变量是允许的。

21. 说明:变量,尤其是局部变量,如果用单个字符表示,很容易敲错(如i写成j),而编译时又检查不出来,有可能为了这个小小的错误而花费大量的查错时间。

22. 示例:下面所示的局部变量名的定义方法可以借鉴。

23. int liv_width

24. 命名规范必须与所使用的系统风格保持一致,并在同一项目中统一,比如采用UNIX的全小写加下划线的风格或大小写混排的方式,不要使用大小写与下划线混排的方式,用作特殊标识如标识成员变量或全局变量的m_和g_,其后加上大小写混排的方式是允许的。

示例: Add_User不允许,add_user、AddUser、m_AddUser允许。

25. 命名规则尽量与所采用的操作系统或开发工具的风格保持一致。

26. 例如Windows应用程序的标识符通常采用“大小写”混排的方式,如AddChild。而Unix应用程序的标识符通常采用“小写加下划线”的方式,如add_child。别把这两类风格混在一起用。

27. 程序中不要出现仅靠大小写区分的相似的标识符。

例如:

int x, X;    // 变量x 与 X 容易混淆

void foo(int x);  // 函数foo 与FOO容易混淆

void FOO(float x);

28. 除非必要,不要用数字或较奇怪的字符来定义标识符。

29. 用正确的反义词组命名具有互斥意义的变量或相反动作的函数等。

说明:下面是一些在软件中常用的反义词组。

add / remove begin / end create / destroy

insert / delete first / last get / release

increment / decrement put / get

add / delete lock / unlock open / close

min / max old / new start / stop

next / previous source / target show / hide

send / receive source / destination

cut / paste up / down

示例:

int min_sum;

int max_sum;

int add_user( BYTE *user_name );

int delete_user( BYTE *user_name );

30. 避免使用不易理解的数字,用有意义的标识来替代。涉及物理状态或者含有物理意义的常量,不应直接使用数字,必须用有意义的枚举或宏来代替。

示例:如下的程序可读性差。

if (Trunk[index].trunk_state == 0)

{

Trunk[index].trunk_state = 1;

… // program code

}

应改为如下形式

if (Trunk[index].trunk_state == TRUNK_IDLE)

{

Trunk[index].trunk_state = TRUNK_BUSY;

… // program code

}

31. 去掉没必要的公共变量。

说明:公共变量是增大模块间耦合的原因之一,故应减少没必要的公共变量以降低模块间的耦合度。

32. 仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系。

说明:在对变量声明的同时,应对其含义、作用及取值范围进行注释说明,同时若有必要还应说明与其它变量的关系。

33. 程序中不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误,但会使人误解。

34. 变量的名字应当使用“名词”或者“形容词+名词”。

  例如:

  float value;

  float oldValue;

  float newValue;

35. 全局函数的名字应当使用“动词”或者“动词+名词”(动宾词组)。类的成员函数应当只使用“动词”,被省略掉的名词就是对象本身。

    例如:

    DrawBox();  // 全局函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: