当前位置: 首页 > news >正文

山东网站建设运营网站营销推广的公司

山东网站建设运营,网站营销推广的公司,济南网站优化小黑,长春高档网站建设这是一个简短的文档#xff0c;描述了linux内核的首选代码风格。代码风格是因人而异的#xff0c;而且我 不愿意把我的观点强加给任何人#xff0c;不过这里所讲述的是我必须要维护的代码所遵守的风格#xff0c; 并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码…这是一个简短的文档描述了linux内核的首选代码风格。代码风格是因人而异的而且我 不愿意把我的观点强加给任何人不过这里所讲述的是我必须要维护的代码所遵守的风格 并且我也希望绝大多数其他代码也能遵守这个风格。请在写代码时至少考虑一下本文所述的 风格。 首先我建议你打印一份GNU代码规范然后不要读它。烧了它这是一个具有重大象征性 意义的动作。 不管怎样现在我们开始                  第一章缩进 制表符是8个字符所以缩进也是8个字符。有些异端运动试图将缩进变为4乃至2个字符 深这几乎相当于尝试将圆周率的值定义为3。 理由缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕 连续看了20小时之后你将会发现大一点的缩进会使你更容易分辨缩进。 现在有些人会抱怨8个字符的缩进会使代码向右边移动的太远在80个字符的终端屏幕上 就很难读这样的代码。这个问题的答案是如果你需要3级以上的缩进不管用何种方式你 的代码已经有问题了应该修正你的程序。 简而言之8个字符的缩进可以让代码更容易阅读还有一个好处是当你的函数嵌套太深的 时候可以给你警告。留心这个警告。 在switch语句中消除多级缩进的首选的方式是让“switch”和从属于它的“case”标签对齐于同 一列而不要“两次缩进”“case”标签。比如         switch (suffix) {         case G:         case g:                 mem 30;                 break;         case M:         case m:                 mem 20;                 break;         case K:         case k:                 mem 10;                 /* fall through */         default:                 break;         } 不要把多个语句放在一行里除非你有什么东西要隐藏         if (condition) do_this;           do_something_everytime; 也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表 达式。 除了注释、文档和Kconfig之外不要使用空格来缩进前面的例子是例外是有意为之。 选用一个好的编辑器不要在行尾留空格。                 第二章把长的行和字符串打散 代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。 每一行的长度的限制是80列我们强烈建议您遵守这个惯例。 长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句而且放置的位置 也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的 字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。 void fun(int a, int b, int c) {         if (condition)                 printk(KERN_WARNING Warning this is a long printk with                                                 3 parameters a: %u b: %u                                                 c: %u \n, a, b, c);         else                 next_statement; }                 第三章大括号和空格的放置 C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同选择或弃用某种放置策 略并没有多少技术上的原因不过首选的方式就像Kernighan和Ritchie展示给我们的是 把起始大括号放在行尾而把结束大括号放在行首所以         if (x is true) {                 we do y         } 这适用于所有的非函数语句块if、switch、for、while、do。比如         switch (action) {         case KOBJ_ADD:                 return add;         case KOBJ_REMOVE:                 return remove;         case KOBJ_CHANGE:                 return change;         default:                 return NULL;         } 不过有一个例外那就是函数函数的起始大括号放置于下一行的开头所以         int function(int x)         {                 body of function         } 全世界的异端可能会抱怨这个不一致性是……呃……不一致的不过所有思维健全的人都知道 aKR是_正确的_并且bKR是正确的。此外不管怎样函数都是特殊的在C语言中 函数是不能嵌套的。 注意结束大括号独自占据一行除非它后面跟着同一个语句的剩余部分也就是do语句中的 “while”或者if语句中的“else”像这样         do {                 body of do-loop         } while (condition); 和         if (x y) {                 ..         } else if (x y) {                 ...         } else {                 ....         } 理由KR。 也请注意这种大括号的放置方式也能使空或者差不多空的行的数量最小化同时不失可 读性。因此由于你的屏幕上的新行是不可再生资源想想25行的终端屏幕你将会有更 多的空行来放置注释。 当只有一个单独的语句的时候不用加不必要的大括号。 if (condition)         action(); 这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大 括号。 if (condition) {         do_this();         do_that(); } else {         otherwise(); }                 3.1空格 Linux内核的空格使用方式主要取决于它是用于函数还是关键字。大多数关键字后 要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__这些关键字 某些程度上看起来更像函数它们在Linux里也常常伴随小括号而使用尽管在C语言里这样 的小括号不是必需的就像“struct fileinfo info”声明过后的“sizeof info”。 所以在这些关键字之后放一个空格         if, switch, case, for, do, while 但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如         s sizeof(struct file); 不要在小括号里的表达式两侧加空格。这是一个反例         s sizeof( struct file ); 当声明指针类型或者返回指针类型的函数时“*”的首选使用方式是使之靠近变量名或者函 数名而不是靠近类型名。例子         char *linux_banner;         unsigned long long memparse(char *ptr, char **retptr);         char *match_strdup(substring_t *s); 在大多数二元和三元操作符两侧使用一个空格例如下面所有这些操作符             -      *  /  %  |    ^        !  ?  : 但是一元操作符后不要加空格           *    -  ~  !  sizeof  typeof  alignof  __attribute__  defined 后缀自加和自减一元操作符前不加空格           -- 前缀自加和自减一元操作符后不加空格           -- “.”和“-”结构体成员操作符前后不加空格。 不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白然后你 就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码有些编辑器就不 会移除已经加入的空白就像你故意留下一个只有空白的行。包含行尾空白的行就这样产 生了。 当git发现补丁包含了行尾空白的时候会警告你并且可以应你的要求去掉行尾空白不过 如果你是正在打一系列补丁这样做会导致后面的补丁失败因为你改变了补丁的上下文。                 第四章命名 C是一个简朴的语言你的命名也应该这样。和Modula-2和Pascal程序员不同C程序员不使 用类似ThisVariableIsATemporaryCounter这样华丽的名字。C程序员会称那个变量为“tmp” 这样写起来会更容易而且至少不会令其难于理解。 不过虽然混用大小写的名字是不提倡使用的但是全局变量还是需要一个具描述性的名字 。称一个全局函数为“foo”是一个难以饶恕的错误。 全局变量只有当你真正需要它们的时候再用它需要有一个具描述性的名字就像全局函 数。如果你有一个可以计算活动用户数量的函数你应该叫它“count_active_users()”或者 类似的名字你不应该叫它“cntuser()”。 在函数名中包含函数类型所谓的匈牙利命名法是脑子出了问题——编译器知道那些类型而 且能够检查那些类型这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。 本地变量名应该简短而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器 它应该被称为“i”。叫它“loop_counter”并无益处如果它没有被误解的可能的话。类似 的“tmp”可以用来称呼任意类型的临时变量。 如果你怕混淆了你的本地变量名你就遇到另一个问题了叫做函数增长荷尔蒙失衡综合症 。请看第六章函数。                 第五章Typedef 不要使用类似“vps_t”之类的东西。 对结构体和指针使用typedef是一个错误。当你在代码里看到         vps_t a; 这代表什么意思呢 相反如果是这样         struct virtual_container *a; 你就知道“a”是什么了。 很多人认为typedef“能提高可读性”。实际不是这样的。它们只在下列情况下有用 (a) 完全不透明的对象这种情况下要主动使用typedef来隐藏这个对象实际上是什么。      例如“pte_t”等不透明对象你只能用合适的访问函数来访问它们。      注意不透明性和“访问函数”本身是不好的。我们使用pte_t等类型的原因在于真的是      完全没有任何共用的可访问信息。 (b) 清楚的整数类型如此这层抽象就可以帮助消除到底是“int”还是“long”的混淆。      u8/u16/u32是完全没有问题的typedef不过它们更符合类别(d)而不是这里。      再次注意要这样做必须事出有因。如果某个变量是“unsigned long“那么没有必要         typedef unsigned long myflags_t;      不过如果有一个明确的原因比如它在某种情况下可能会是一个“unsigned int”而在      其他情况下可能为“unsigned long”那么就不要犹豫请务必使用typedef。 (c) 当你使用sparse按字面的创建一个新类型来做类型检查的时候。 (d) 和标准C99类型相同的类型在某些例外的情况下。      虽然让眼睛和脑筋来适应新的标准类型比如“uint32_t”不需要花很多时间可是有些      人仍然拒绝使用它们。      因此Linux特有的等同于标准类型的“u8/u16/u32/u64”类型和它们的有符号类型是被      允许的——尽管在你自己的新代码中它们不是强制要求要使用的。      当编辑已经使用了某个类型集的已有代码时你应该遵循那些代码中已经做出的选择。 (e) 可以在用户空间安全使用的类型。      在某些用户空间可见的结构体里我们不能要求C99类型而且不能用上面提到的“u32”      类型。因此我们在与用户空间共享的所有结构体中使用__u32和类似的类型。 可能还有其他的情况不过基本的规则是永远不要使用typedef除非你可以明确的应用上 述某个规则中的一个。 总的来说如果一个指针或者一个结构体里的元素可以合理的被直接访问到那么它们就不 应该是一个typedef。                 第六章函数 函数应该简短而漂亮并且只完成一件事情。函数应该可以一屏或者两屏显示完我们都知 道ISO/ANSI屏幕大小是80x24只做一件事情而且把它做好。 一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以如果你有一个理论上 很简单的只有一个很长但是简单的case语句的函数而且你需要在每个case里做很多很 小的事情这样的函数尽管很长但也是可以的。 不过如果你有一个复杂的函数而且你怀疑一个天分不是很高的高中一年级学生可能甚至 搞不清楚这个函数的目的你应该严格的遵守前面提到的长度限制。使用辅助函数并为之 取个具描述性的名字如果你觉得它们的性能很重要的话可以让编译器内联它们这样的 效果往往会比你写一个复杂函数的效果要好。 函数的另外一个衡量标准是本地变量的数量。此数量不应超过510个否则你的函数就有 问题了。重新考虑一下你的函数把它分拆成更小的函数。人的大脑一般可以轻松的同时跟 踪7个不同的事物如果再增多的话就会糊涂了。即便你聪颖过人你也可能会记不清你2 个星期前做过的事情。 在源文件里使用空行隔开不同的函数。如果该函数需要被导出它的EXPORT*宏应该紧贴 在它的结束大括号之下。比如 int system_is_up(void) {         return system_state SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up); 在函数原型中包含函数名和它们的数据类型。虽然C语言里没有这样的要求在Linux里这 是提倡的做法因为这样可以很简单的给读者提供更多的有价值的信息。                 第七章集中的函数退出途径 虽然被某些人声称已经过时但是goto语句的等价物还是经常被编译器所使用具体形式是 无条件跳转指令。 当一个函数从多个位置退出并且需要做一些通用的清理工作的时候goto的好处就显现出来 了。 理由是 - 无条件语句容易理解和跟踪 - 嵌套程度减小 - 可以避免由于修改时忘记更新某个单独的退出点而导致的错误 - 减轻了编译器的工作无需删除冗余代码;) int fun(int a) {         int result 0;         char *buffer kmalloc(SIZE);         if (buffer NULL)                 return -ENOMEM;         if (condition1) {                 while (loop1) {                         ...                 }                 result 1;                 goto out;         }         ... out:         kfree(buffer);         return result; }                 第八章注释 注释是好的不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的更好 的做法是让别人一看你的代码就可以明白解释写的很差的代码是浪费时间。 一般的你想要你的注释告诉别人你的代码做了什么而不是怎么做的。也请你不要把注释 放在一个函数体内部如果函数复杂到你需要独立的注释其中的一部分你很可能需要回到 第六章看一看。你可以做一些小注释来注明或警告某些很聪明或者槽糕的做法但不要 加太多。你应该做的是把注释放在函数的头部告诉人们它做了什么也可以加上它做这 些事情的原因。 当注释内核API函数时请使用kernel-doc格式。请看 Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc以获得详细信息。 Linux的注释风格是C89“/* ... */”风格。不要使用C99风格“// ...”注释。 长多行的首选注释风格是         /*          * This is the preferred style for multi-line          * comments in the Linux kernel source code.          * Please use it consistently.          *          * Description:  A column of asterisks on the left side,          * with beginning and ending almost-blank lines.          */ 注释数据也是很重要的不管是基本类型还是衍生类型。为了方便实现这一点每一行应只 声明一个数据不要使用逗号来一次声明多个数据。这样你就有空间来为每个数据写一段 小注释来解释它们的用途了。                 第十一章数据结构 如果一个数据结构在创建和销毁它的单线执行环境之外可见那么它必须要有一个引用计 数器。内核里没有垃圾收集并且内核之外的垃圾收集慢且效率低下这意味着你绝对需 要记录你对这种数据结构的使用情况。 引用计数意味着你能够避免上锁并且允许多个用户并行访问这个数据结构——而不需要担心 这个数据结构仅仅因为暂时不被使用就消失了那些用户可能不过是沉睡了一阵或者做了一 些其他事情而已。
http://www.w-s-a.com/news/700480/

相关文章:

  • 电子商务网站建设说课稿棕色网站设计
  • 怎么做律所的官方网站红塔网站制作
  • 装一网装修平台官网惠州seo按天付费
  • 湖南建设监理报名网站东莞模块网站建设方案
  • 网站建设小组个人主页html源码
  • 响应式网站检测工具营销公司业务范围
  • 网站源码如何安装做游戏课程网站
  • 选服务好的网站建设亚洲砖码砖专区2022
  • 网站快速查找wordpress 悬停 图片 文字
  • 网站续费 多久想自己做网站该学些什么
  • 可以自己做网站wordpress英文写作插件
  • 国外可以做会员网站的网站怎么查百度竞价关键词价格
  • 新站网站建设亚马逊关键词
  • 电商网站前端架构设计上海市建设工程安全生产协会网站
  • 东莞企业免费模版网站建设一般网站维护要多久
  • 著名建筑设计网站常州制作网站价格
  • 食品营销型网站广东省广州市白云区
  • 如何做网站哪个站推广描述对于营销型网站建设很重要飘红效果更佳
  • 济阳做网站公司99企业邮箱888
  • 国贸做网站的公司能接做网站的活的网站
  • 淮南建设厅网站上杭县建设局网站
  • 东莞做网站公司首选!西安注册公司费用
  • 做网站包括什么卖水果网站模板
  • 扬州网站建设外包wordpress 文章评分
  • 网站建设网站多少钱公司名字大全列表
  • 设计企业网站内容wordpress 投稿者 权限
  • seo网站推广免费价格低的成语
  • 做网站建设销售辛苦吗专题页是什么
  • 做网站的软件名字全拼wordpress可以上传文件吗
  • 建品牌网站公司关于asp_sql网站开发的书籍