哪种编码风格是你的“菜”

  英文原文:Reprogramming My Brace Style Mind

  每个程序员都有自己的编码风格,这基本上都是由他们的喜好决定的,此外,程序员还乐于争论各种编码风格的优劣,比如关于 Tab 和空格(见《Tab v.s. 空格:一个永恒的神圣战争》、《空格“异教徒”去死》)、80 列规则(见《保卫 80 列规则》),还有大括号的缩进风格等。

  一致的编码风格,更便于阅读。因此程序员都想极力说服别人认同并使用与自己一致的编码风格。下面来了解一下我的编码风格变化历程吧,哪种编码风格是你的“菜”呢?

  1980/1990 年代的紧凑风格

  当我开始编程时,我使用 tab 字符,因为使用它保存的文件更小,还可以将代码限制到 80 列。我还遵循 Kernighan 和 Ritchie 的《C Programming Language》一书中约定的“大括号放在同一行”规则,代码看起来是这样的:

int main (int argc, char *argv[]) {  
       int a = rand () % 100;  
       if (a > 25) {  
               call_a_function ();  
               call_another_function ();  
       } else {  
               call_b_function ();  
       } // end if   } // end main  

  当时 Tab 缩进默认为 8 个字符宽度,这意味着你不能缩进过多,以免打破“80 列”宽度的限制,这也迫使你写更少、更精简的函数名或代码(这是好事)。大括号在同一行上,意味着可以在一页中显示更多的代码。

  但也有一些不好的事情。我们开始使用更短的变量名,这使代码更难以阅读和维护。我们在代码行之间没有添加任何空白行,结果很难找到代码块开始和结束标记(因此我们必须在代码块结束的地方加上注释)。由于缩进太宽,留给我们的编码空间就少了。

  2000 年的宽松风格

  在 2000 年,我以及周围的程序员基本上都已经切换到了微软的C/C#约定上,即使用 4 个空格,而不是 Tab,不限制代码行的长度,大括号单独一行。如下:

int main (int argc, char *argv[])  
{  
   int a = rand () % 100;  
   
   if (a > 25)  
   {  
       call_a_function ();  
       call_another_function ();  
   }  
   else  
   {  
       call_b_function ();  
   }  
}  

  空格缩进意味着我们不必处理不同编辑器中 Tab 大小(Tab 大小可以根据用户喜好进行设置)。我们使用空行,以使代码更易于阅读。单独一行的大括号使代码块更加明显(可以很快找出开始和结束点)。

  但是,这也导致了一些问题。由于行长度(大屏幕)无限制,我们不再感觉必须要限制缩进的数量,并开始创建更大更长的代码。由于当时的编辑器无法很好地格式化代码,程序员经常会在水平滚动时无法看到左侧的代码。代码变得难以阅读,并排比较更困难。

  因此,在 2000 年初,我选择使用 4 个空格来缩进,依然遵循 80 列规则,将大括号单独放在一行中,以改善可读性。

  2010 年的典型风格

  现在,我开始使用 Xcode 4。Xcode 中默认为 4 个空格缩进,保持不变,还可以智能格式化代码,不会出现滚动到右边看不到左边代码的情况。但是,令我郁闷的是,默认代码片段中大括号竟然不一致,有时单独一行,有时和代码共用一行。

  看看默认的 initWithNibName 代码片段:

- (id) initWithNibName:(NSString *) nibNameOrNil bundle:(NSBundle *) nibBundleOrNil  
{  
   self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
   if (self) {  
       self.title = NSLocalizedString (@"Detail", @"Detail");  
   }  
   return self;  
}  

  事实证明,苹果没有弄错。它使用了正确的 Kernighan & Ritchie 风格,在早期C语言书籍中是为了节省空间才将所有大括号放在代码后面的。根据维基百科,K&R风格是:

当秉承K&R时,每一个函数左括号都应在下一行中,并与开头行有相同的缩进。括号中的语句应该缩进,右括号应该与函数开头有相同的缩进,并单独一行。对于代码块内的控制语句,左括号应与控制语句在同一行中,右括号单独一行(除非有 else 或 while 关键字)。

  事实上,这是典型的K&R风格,针对所有的C衍生语言,包括C++、C#和 Objective-C。这是语言本身的设计者所遵循的风格。

  因此,我也改变了我的括号使用风格,我仍然使用空格缩进,仍然遵循 80 列宽度原则,但现在更多依赖于编辑器来进行代码格式化。不过,我现在坚持真正的K&R括号风格。

int main (int argc, char *argv[])  
{  
   int a = rand () % 100;  
       
   if (a > 25) {  
       call_a_function ();  
       call_another_function ();  
   } else {  
       call_b_function ();  
   }  
}  

  你的编码风格是什么样?欢迎评论。

 

====================

编辑器 格式化成什么样,就用什么样。

写完代码后,习惯格式化,全部交给软件处理,它捣鼓出来什么样子就什么样子

展开阅读全文

编码风格问题求解

09-29

今天小小的写了个XX管理系统,所以就上坛子来看看,刚好看见 复制帝 写出了一手非常漂亮的代码,再对比一下我自己的,羞愧得无地自容。复制帝写的代码真的十分干净漂亮,我也希望能写出这么漂亮的代码,有什么好的编码风格方面的建议都说一下,谢谢!rn复制帝写的那个漂亮代码原帖地址:rnhttp://topic.csdn.net/u/20100927/19/913b3a3b-094d-4180-a55d-69b385dbd330.html?63190rn下面附我自己今天写的代码的一小部分,针对这个提些意见,谢谢!rn[code=C/C++]rn#include rn#include rn#include rn#include rn#include rn#include "GlobalFun.h"rnrntypedef std::list lsm;rnrnusing std::cout;rnusing std::cin;rnrnvoid OpenFile(lsm & lsM)rnrn using std::ifstream;rn cout<<"默认文件名为sav.dat\n";rn ifstream in;rn in.open("sav.dat");rn if(!in)rn rn cout<<"无默认文件!\n";rn rn elsern rn Message tempm;rn std::string temps;rn int temp=in.get();rn if(!in.eof())rn rn in.putback(temp);rn rn int count=0;rn while(!in.eof())rn rn count++;rn in>>temps;rn tempm.SetName(temps);rn in>>temps;rn tempm.SetPhone(temps);rn lsM.push_back(tempm);rn temp=in.get();rn temp=in.get();rn if(!in.eof())rn rn in.putback(temp);rn rn rn cout<<"读取完毕,共"<>temps;rn std::ifstream in(temps);rn if(!in)rn rn cout<<"无该文件!\n";rn rn elsern rn Message tempm;rn int temp=in.get();rn if(!in.eof())rn rn in.putback(temp);rn rn int count=0;rn while(!in.eof())rn rn count++;rn in>>temps;rn tempm.SetName(temps);rn in>>temps;rn tempm.SetPhone(temps);rn lsM.push_back(tempm);rn temp=in.get();rn temp=in.get();rn if(!in.eof())rn rn in.putback(temp);rn rn rn cout<<"读取完毕,共"<GetName();rn out<GetPhone();rn out<>temps;rn ofstream out;rn out.open(temps,std::ios_base::out | std::ios_base::app);rn Message tempm;rn int count=0;rn lsm templ;rn lsM.sort();rn std::unique_copy(lsM.begin(),lsM.end(),std::back_inserter(templ));rn for(lsm::const_iterator iter =templ.begin() ; iter!=templ.end() ; ++iter)rn rn ++count;rn temps=iter->GetName();rn out<GetPhone();rn out<>tempname;rn cout<<"请输入对方的号码:";rn cin>>tempphone;rn Message tempm(tempname,tempphone);rn lsM.push_back(tempm);rnrnrnbool Find (lsm & lsM,Message & msg)rnrn using std::cout;rn cout<<"请输入查找方式(输入其他字符时返回)\n"rn <<"a.按姓名查找\n"rn <<"b.按电话查找\n";rn char choice=getch();rn std::string temps;rn if('a'==choice)rn rn PrintAll(lsM);rn cout<<"请输入要删除的对象的姓名:";rn cin>>temps;rn lsm::const_iterator iter = lsM.begin();rn for(; iter!=lsM.end() ; ++iter)rn rn if(temps==iter->GetName())rn rn break;rn rn rn if(lsM.end()==iter)rn rn cout<<"找不到相应的记录!\n";rn return false;rn rn elsern rn msg=*iter;rn return true;rn rn rn else if('b'==choice)rn rn PrintAll(lsM);rn cout<<"请输入要删除的对象的电话:";rn cin>>temps;rn lsm::const_iterator iter = lsM.begin();rn for(; iter!=lsM.end() ; ++iter)rn rn if(temps==iter->GetPhone())rn rn break;rn rn rn if(lsM.end()==iter)rn rn cout<<"找不到相应的记录!\n";rn return false;rn rn elsern rn msg=*iter;rn return true;rn rn rn return false;rnrnrnvoid EarseMessage(lsm & lsM)rnrn Message temp;rn if(Find(lsM,temp))rn rn lsM.remove(temp);rn rnrnrnvoid FindMessage(lsm & lsM)rnrn Message temp;rn Find(lsM,temp);rnrnrnvoid PrintAll(lsm & lsM)rnrn using std::cout;rn if(lsM.empty())rn rn cout<<"无任何记录!\n";rn rn elsern rn int count=0;rn for(lsm::const_iterator iter = lsM.begin();iter != lsM.end() ; ++iter)rn rn count++;rn cout<GetName()<<"\t\t"<GetPhone()<rn#include rn#include rn#include rnusing namespace std;rnint main() rn char *Alphabet = "abcdefghijklmnopqrstuvwxyz" ;rn char *Vowels = "aeiou" ;rn char *AlphaNum = "0123456789abcdef" ;rn char result[45] ;rn char *last ;rnrn int lenA = strlen(Alphabet) ;rn int lenV = strlen(Vowels ) ;rn int lenAN = strlen(AlphaNum) ;rnrn cout << "Alphabet = " << Alphabet << endl ;rn cout << "Vowels = " << Vowels << endl ;rn cout << "AlphaNum = " << AlphaNum << endl ;rnrn cout << "\nusing non-predicate versions" << endl ;rnrn //non-predicate set_differencern last = set_difference(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result) ;rn *last = 0 ;rn cout << "set_difference(Alphabet, AlphaNum) = " << result << endl ;rnrn //non-predicate set_intersectionrn last = set_intersection(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result) ;rn *last = 0 ;rn cout << "set_intersection(Alphabet, AlphaNum) = " << result << endl ;rnrn //non-predicate set_symmetric_differencern last = set_symmetric_difference(Alphabet, Alphabet+lenA,rn Vowels , Vowels +lenV,rn result) ;rn *last = 0 ;rn cout << "set_symmetric_difference(Alphabet, Vowels) = " << result << endl ;rnrn //non-predicate set_unionrn last = set_union(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result) ;rn *last = 0 ;rn cout << "set_union(Alphabet, AlphaNum) = " << result << endl ;rnrn cout << "\nusing predicate versions" << endl ;rnrn //predicate set_differencern last = set_difference(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result , less()) ;rn *last = 0 ;rn cout << "set_difference(Alphabet, AlphaNum) = " << result << endl ;rnrn //predicate set_intersectionrn last = set_intersection(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result , less()) ;rn *last = 0 ;rn cout << "set_intersection(Alphabet, AlphaNum) = " << result << endl ;rnrn //predicate set_symmetric_differencern last = set_symmetric_difference(Alphabet, Alphabet+lenA,rn Vowels , Vowels +lenV,rn result , less()) ;rn *last = 0 ;rn cout << "set_symmetric_difference(Alphabet, Vowels) = " << result << endl ;rnrn //predicate set_unionrn last = set_union(Alphabet, Alphabet+lenA,rn AlphaNum, AlphaNum+lenAN,rn result , less()) ;rn *last = 0 ;rn cout << "set_union(Alphabet, AlphaNum) = " << result << endl ;rnrn return 0 ;rnrnrnrn[/code] 论坛

没有更多推荐了,返回首页