C/C++ 代码风格推荐

C/C++ 代码风格推荐

代码风格的重要性

你听说过大括号圣战吗?

没错,就是指大括号是否换行。

虽然到底换不换行双方各执一词,但其各自内部的风格统一性却不可否认。

一个风格混乱的代码,首先就会让阅读程序的人感到厌烦,而且也会造成理解上的困难(包括写程序的人)。

C/C++ 常见代码风格介绍

一、代码缩进

这个非常重要,因为缩进有助于理解代码的结构。

缩进主要是由大括号带来的代码块带来,但是对于 ifforwhile 等只有一个语句但换行的情况,也应有对应缩进。

可以看一下示例(大括号换行版本):

#include <bits/stdc++.h>
using namespace std;
struct node
{
public: //这类标识符建议不缩进
    int l,r; //结构体、类、命名空间的缩进
private:
    int len;
};
int x,y; //全局变量定义不缩进
int get(int x)
{
    //函数代码块缩进
}
int main()
{
    int n,m; //局部变量定义与普通语句无差别
    cin>>x>>y;
    if (x>y)
    {
        for (int i=y;i<=x;i++)
            get(i); //单个语句换行依然需要缩进
    }
    else //else 应该跟对应的 if 缩进相同
    {
        for (int i=x;i<=y;i++)
        {
            get(i); //for 语句代码块的缩进
            //do something..
        }
    }
    return 0;
}

特别地,对于缩进使用制表符还是空格,取决于个人喜好。(这又是另一个圣战了)

二、大括号问题

主要分为两派:

#include <bits/stdc++.h>
using namespace std;
struct node
{
    int l,r;
};
int x,y;
int get(int x)
{
    //do something..
}
int main()
{
    cin>>x>>y;
    if (x>y)
    {
        for (int i=y;i<=x;i++)
        {
            get(i);
            //do something..
        }
    }
    else
    {
        for (int i=x;i<=y;i++)
        {
            get(i);
            //do something..
        }
    }
    return 0;
}

这是典型的大括号换行写法。

#include <bits/stdc++.h>
using namespace std;
int x,y;
struct node {
    int l,r;
};
int get(int x) {
    //do something..
}
int main() {
    cin>>x>>y;
    if (x>y) {
        for (int i=y;i<=x;i++) {
            get(i);
            //do something..
        }
    }
    else {
        for (int i=x;i<=y;i++) {
            get(i);
            //do something..
        }
    }
    return 0;
}

这是典型的大括号不换行写法(建议大括号与前面的代码中隔开一个空格)。

两者优劣我们暂且不讨论(也不敢讨论),选择哪种都可以,但关键是要从一而终,也就是要换行就都换行,不能两种风格相互夹杂,不伦不类。

当然有时候当函数或者代码块过于简短,有可能整个放在一行,比如:

int min(int x,int y) {return x>y?y:x;}

(但我从来不这么干)

(吐槽不忘自己,我好像都是 C++ 用前一种,JavaScript 跟 PHP 用后一种,所以好像我自己都不知道推荐哪种。)

三、多语句同行问题

很多人喜欢进行这么写代码:

c=a;a=b;b=c;

这种一行多个 ; 的写法十分不美观,纯粹是为了缩短代码,“充分”利用一行的空间。

所以我们提供两种方案:

c=a;
a=b;
b=c;
c=a,a=b,b=c;

因为 , 在 C/C++ 中也是一种运算符,所以第二种可以被看作一个语句,我个人认为更美观。

四、变量定义方式问题

有很多人喜欢对于每个变量都在需要使用时才定义。

然而有些变量本应是全局变量,却定义在了 main 函数中,这一是有可能增加代码编写复杂度,二是可能导致出错。

所以我们建议要严格区分局部跟全局变量。

比如一道题输入里涉及的 $n,m$ 这种变量,一般定义为全局变量,因为往往在整个代码中都会被使用到,而循环变量 $i,j,k$ 以及一些只在 iffor 代码块中临时用到的变量(比如交换用变量,临时读入变量,较大较小变量)则适合在对应位置局部定义,毕竟在不同的地方可能会被重复用到,这样方便于内存的释放。

而对于以后可能接触的一些工程代码的编写,这主要体现在 classstructpublicprivateprotected 这些不同的限定,可以用于防范一些变量的不合理调用。

五、空格问题

首先除了缩进以外,请不要出现连续的空格。

比如 int x; 正常情况下千万不要写成 int x;。(我相信大家也看得出来有多丑)

然后个人建议对于 ifwhilefor 等关键字和其之后的 ( 之间尽量打一个空格。

并且 #include 跟后面的头文件之间最好也加一个空格,比如 #include <cmath>#include "stdio.h" 这样。

顺便讲一下常见的头文件的引用问题:

  • 一般系统头文件应该用 #include <>,并且引用先于自定义头文件。
  • 自定义头文件应该用 #include ""
  • 不需要的头文件尽量不引用。

六、常量定义、类型别名问题

一般常量定义建议使用:

const int N=100009;

另一种我个人选择尽量不用:

#define M 233

类型别名同理:

typedef long long ll;

一般不用:

#define pii pair<int,int>

七、冗余代码的减少

对于重复代码尽量使用循环或者函数的方法减少。

比如某土豆的作业里面的两个点坐标之间的判断就可以写个函数。

还有一些废话可以缩短,比如:

//1
if (F) c=a;
else c=b;

//2
if (F) return true;
else false;

//3
b+=a;
a++;

//4
if (a>b) b=a;

分别可以缩短为:

//1
c=F?a:b;

//2
return F;

//3
b+=(a++);

//4
b=max(a,b);

还有很多种,具体情况需要你对代码有一个清晰的理解。

八、变量定义问题

这个国际上有很多种标准。

对于做题(非工程),主要讲求一个能让自己和别人看懂。

比如 cnt 用于计数,Max 用于最大值,val 表示值,nextprev 表示前后一个(指针)。

当然对于工程,有更多的要求,这个主要要适应他人的命名规则。

比如说用下划线分别连接变量类型、变量从属范围、变量含义,i_List_length 可能就表示一个 List 类(结构体)的 int 型变量 length(长度)。

总结

代码风格存在的必要性是为了可读性的增强。

很多时候并不是代码写对就是好的,只要自己看懂就是好的,更重要的是增强代码可理解性,可移植性,而这些都是优良的代码风格可以带来的。

所以千万不能轻视代码风格

 

点赞 4

Comments: 5

  1. MatrixBi MatrixBi说道:

    海蜇棒棒!

  2. Thorin Thorin说道:

    王海我男神!!!!!!!!

  3. 头像 skylee03说道:

    int x;int x;有什麼區別?

Add your comment