精华内容
下载资源
问答
  • 几种常见的编码格式

    千次阅读 2018-01-13 15:09:51
    我大概会按序分成篇来写这个问题,以后再也不担心中文乱码了。 个人觉得本书非常不错,尽管有些地方我还没能看懂。但对于需要进一步了解 Java内在机制的人是非常帮助的。 为什么要编码 首先必须知道计算机...

    本文来自于对许令波所著的 深入分析 Java Web 技术内幕 一书的关于编码问题的总结;我大概会按序分成几篇来写这个问题,以后再也不担心中文乱码了。

    个人觉得本书非常不错,尽管有些地方我还没能看懂。但对于需要进一步了解 Java内在机制的人是非常有帮助的。

    为什么要编码

    首先必须知道计算机是如何表示我们人类能够理解的符号的。这些符号也就是我们人类所使用的语言,由于人类语言太多,表示这些语言的符号太多,无法用计算机中一个基本的存储单元——字节(byte)来表示,因而必须要经过拆分或一些翻译工作,才能让计算机理解我们的语言。

    我们可以把计算机能够理解的语言假定为英语,其他语言要能够在计算机中使用,必须的经过一次翻译,把它翻译成英语。这个翻译的过程就是编码。

    所以编码的原因可以总结为以下几条。

    • 在计算机中存储信息的最小单元是一字节,即8个bit,所以能够表示的字符范围是 0~255个。
    • 人类要表示的符号太多,无法用一个字节来完全表示。

    要解决这个矛盾,必须要有一个新的数据结构char ,而从 char 到 byte 必须编码。

    如何翻译

    各种语言需要交流,经过翻译是必要的,那又如何来翻译呢?在计算机中提供了多种翻译方式,常见的有 ASCII、ISO-88591、GB23112、GBK、UTF-8、UTF-8、UTF-16等。它们都可以被看作字典,,它们规定了转换的规则,按照这个规则就可以让计算机正确地表示我们的字符。

    在选择编码格式来存储汉字时,一般要考虑是存储空间还是编码的效率重要。

    1. ASCII 码
      ASCII 码总共有128个,用1个字节的低七位表示,0~31 是控制字符如换行、回车、删除等,32~126 是打印字符,可以通过键盘输入并且能够显示出来。
    2. .ISO-8859-1
      128个字符显然是不够用的,于是ISO组织在ASCII 码基础上又制定了一系列标准来拓展 ASCII 编码,它们是ISO-8859-1 至 ISO-8859-15,其中 ISO-8859-1 涵盖了大多数西欧语言字符,所以应用的最广泛。ISO-8859-1 仍然是单字节编码,它总共能表示 256 个字符。
    3. GB2312
      GB2312 的全称是 《信息技术 中文编码字符集》,它是双字节编码,总的编码范围是 A1~F7,其中A1 ~ A9 是符号区,总共包含682个字符; B0~F7 是汉字区,包含6763个汉字。
    4. GBK
      全称是《汉字内码扩展规范》,它的出现是为了拓展 GB2312 ,并加入更多的汉字。它的编码是和GB2312 兼容的,也就是说用GB2312 编码的汉字可以用GBK 来解码,并且不会有乱码。
    5. UTF-16
      说到UTF 必须提到 Unicode ,ISO 试图创建一个全新的超语言字典,世界上所有的语言都可以通过这个字典来相互翻译。UTF-16 具体定义了Unicode 在计算中的存取方法。UTF-16 用两个字节来表示 Unicode 的转化格式,采用定长的表示方法,即不论什么字符都可以用两个字节表示。
    6. UTF-8
      UTF-16 存在存储空间浪费。UTF-8 采用了一种变长技术,每个编码区域有不同的字码长度。不同类型的字符可以由1~6 个字节组成。如果是一个字节,最高位为0,则表示这是 1 个 ASCII 字符,可见,所有ASCII 编码已经是UTF-8了。

    下一篇:Java 中的编码问题

    如果你觉得我的文章对你有所帮助,欢迎关注我的公众号。赞!我与风来
    认认真真学习,做思想的产出者,而不是文字的搬运工。错误之处,还望指出!

    展开全文
  • vi的编码风格

    千次阅读 2008-03-21 15:19:00
    vi的编码风格 在Linux下,比较流行的“行业”风格KR的编码风格、gnu的编码风格、linux内核的编码风格(基于KR的,缩进是8个空格)等,它们都可以通过indent命令格式化,对应的选项分别是- kr,-gnu, -i8。...

    vi的编码风格

     

    Linux下,比较流行的行业风格有KR的编码风格、gnu的编码风格、linux内核的编码风格(基于KR的,缩进8个空格)等,它们都可以通过indent命令格式化,对应的选项分别是- kr,-gnu, -i8。下面演示用indent把代码格式化成上面的三种风格。

    Quote:

    $ vim test.c
    $ cat test.c                  //
    这样糟糕的编码风格看者会让人想,太难阅读啦。
    cat test.c
    /* test.c -- a test program for using indent */
    #include<stdio.h>

    int main(int argc, char *argv[])
    {
     int i=0;
     if (i != 0) {i++; }
     else {i--; };
     for(i=0;i<5;i++)j++;
     printf("i=%d,j=%d/n",i,j);

     return 0;
    }
    $ indent -kr test.c
    $ cat test.c            //
    好看多了
    /* test.c -- a test program for using indent */
    #include<stdio.h>

    int main(int argc, char *argv[])
    {
        int i = 0;
        if (i != 0) {
            i++;
        } else {
            i--;
        };
        for (i = 0; i < 5; i++)
            j++;
        printf("i=%d,j=%d/n", i, j);
        return 0;
    }
    $ indent -gnu test.c
    $ cat test.c      //
    感觉不如kr的风格,处理if语句时增加了代码行,却并没明显改进效果
    /* test.c -- a test program for using indent */
    #include<stdio.h>

    int
    main (int argc, char *argv[])
    {
      int i = 0;
      if (i != 0)
        {
          i++;
        }
      else
        {
          i--;
        };
      for (i = 0; i < 5; i++)
        j++;
      printf ("i=%d,j=%d/n", i, j);
      return 0;
    }



       
    从演示中可看出编码风格真的很重要,但是如何养成良好的编码风格呢?经常练习,遵守某个编码风格,一如既往。不过这还不够,如果没有一个好编辑器,习惯也很难养成。而VIM提供了很多辅助我们养成良好编码习惯的功能,这些都通过它的命令模式提供。现在分开介绍几个功能;

    语法加(亮) :sytax on
    自动缩进宽度(需要set cin才有用):set sw=8
    TAB
    宽度:set ts=8
    显示行号;set number
    括号自动匹配;set sm
    C
    语言自动缩进set cin

       
    这几个对代码编写来说非常有用,可以考虑把它们全部写到~/.vimrc文件(vim启动的时候会去执行这个文件里头的内容)中,如;

    Quote:

    $ vim ~/.vimrc
    $ cat ~/.vimrc
    :set number
    :set sw=8
    :set ts=8
    :set sm
    :set cin
    :syntax on



    需要补充的几个技巧有;

    ·  在编辑模式下,可通过gqap命令对注释自动断行(每行字符个数可通过命令模式下的"set textwidth=个数"设定)

    ·  命令模式下输入数字可以直接跳到指定行,也可在打开文件时用“vim +数字 文件名实现相同的功能。

    ·  命令模式下的TOhtml命令可把C语言输出为html文件,结合syntax on,可产生比较好的web page把代码发布出去。

    ·  先切换到可视模式(编辑模式下按字母v可切换过来),用光标选中一片代码,然后通过命令模式下的命令“s#^#//#g"把某一片代码给注释掉,这非常方便调试某一片代码的功能。

    ·  命令模式下的”set paste“可解决复制本来已有缩进的代码的自动缩进问题,后可执行”set nopaste“恢复自动缩进

    ·  为了使用最新的vim特性,可用"set nocp"取消与老版本的vi的兼容。

    ·  如发现变量命名不好,想在整个代码中修改,可在命令模式下用"%s#old_variable#new_variable#g"全局替换。替换的时注意变量名是其他变量一部分的情况。

    ·  如果想把缩进TAB键替换成空格,可考虑设置expandtab,即“set et”,如果要把以前编写的代码中的缩进TAB键都替换掉,可以用retab

    ·  为实现关键字补全,输入一部分字符后,按下CTRL+P即可。比如先输入prin,然后按下CTRL+P就可以补全了。

    ·  如果想在在编辑模式下查看Linux手册,可把光标定位到在某个函数,按下Shift+k就可以调出man,很有用。

    ·  删除空行,在命令模式下输入g/^$/d,前面g命令是扩展到全局,中间是匹配空行,后面d命令是执行删除动作。用替换也可以实现,键入%s#^/ n##g,意思是把所有以换行开头的行全部替换为空。类似地,如果要把多个空行转换为一个可以输入g/^/n$/d或者%s#^/n$##g

    ·  注意使用一些有用的插件,比如ctags, cscope等,可以提高代码阅读、分析的效率。特别是open source的东西。


    更多的技巧可以看看资料[2],[6],[7]

       
    实际上,在源代码编写时还有很多需要培养的素质,例如源文件的开头注释、函数的注释,变量的命名等。这方面建议看看参考资料里的编程修养、内核编码风格、网络上流传的《华为编程规范》,以及<C Traps & Pitfalls>等。

     
    展开全文
  • #编码风格# Linux内核

    万次阅读 2019-04-13 17:34:44
    一个良好风格的程序看起来直观、美观,便于阅读,还能助于对程序的理解,特别在代码量比较大情况下更显现编码素质的重要性。相反没有良好的风格的代码读起来难看、晦涩,甚至时候一个括号没对齐就能造成对程序的...

    一个良好风格的程序看起来直观、美观,便于阅读,还能有助于对程序的理解,特别在代码量比较大情况下更显现编码素质的重要性。相反没有良好的风格的代码读起来难看、晦涩,甚至有时候一个括号没对齐就能造成对程序的曲解或者不理解。我曾经就遇见过这样的情况,花费了很多不必要的时间在程序的上下文对照上,还debug了半天没理解的程序。后来直接用indent -kr -i8给他转换格式来看了。特此转过来一个关于代码风格的帖子分享一下~

    Linux内核编码风格
     


    这是一份简短的,描述linux内核首选编码风格的文档。编码风格是很个人化的东西,而且我也不愿意把我的观点强加给任何人,不过这里所讲述的是我必须要维护的代码所遵守的风格,并且我也希望绝大多数其他代码也能遵守这个风格。所以请至少考虑一下本文所述的观点。

    首先,我建议你打印一份GNU的编码规范,然后不要读它。烧掉它,这是一个很高调的具有象征意义的姿态。

    Anyway, here goes:

                    第一章:缩进

    制表符是8个字符,所以缩进也是8个字符。有些异端运动试图将缩进变为4(乃至2)个字符深,这跟尝试着将圆周率PI的值定义为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
            }

    这适用于所有的非函数语句块(ifswitchforwhiledo。比如:

            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
            }

    全世界的异端可能会抱怨这个不一致性,呃…确实是不一致的,不过所有思维健全的人都知道(a)K&R是 正确的, 并且(b)K&R是正确的。另外,不管怎样函数都是特殊的(在C语言中,函数是不能嵌套的)。

    注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,比如说do语句中的“while”或者if语句中的“else”,像这样:

            do {
                    body of do-loop
            } while (condition);



            if (x == y) {
                    ..
            } else if (x > y) {
                    ...
            } else {
                    ....
            }

    理由:K&R。也请注意这种大括号的放置方式还能使空(或者差不多空的)行的数量最小化,同时不失可读性。因此,由于你的屏幕上的新行的供应不是可回收的资源(想想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.
             */

    注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段小注释来解释它们的用途了。


                    第九章:你已经把事情弄糟了

    这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不会创造出一个好程序)(译注:请参考Infinite Monkey Theorem)

    所以你要么放弃GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,你可以把下面这段粘贴到你的.emacs文件里。

    (defun linux-c-mode ()
      "C mode with adjusted defaults for use with the Linux kernel."
      (interactive)
      (c-mode)
      (c-set-style "K&R")
      (setq tab-width 8)
      (setq indent-tabs-mode t)
      (setq c-basic-offset 8))

    这样就定义了M-x linux-c-mode命令。当你hack一个模块的时候,如果你把字符串
    -*- linux-c -*-放在头两行的某个位置,这个模式将会被自动调用。如果你希望在你修改
    /usr/src/linux里的文件时魔术般自动打开linux-c-mode的话,你也可能需要添加

    (setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode)
                            auto-mode-alist))

    到你的.emacs文件里。

    不过就算你尝试让emacs正确的格式化代码失败了,也并不意味着你失去了一切:还可以用“indent”。

    不过,GNU indent也有和GNU emacs一样有问题的设定,所以你需要给它一些命令选项。不过,这还不算太糟糕,因为就算是GNU indent的作者也认同K&R的权威性(GNU的人并不是坏人,他们只是在这个问题上被严重的误导了),所以你只要给indent指定选项“- kr -i8”(代表“K&R,8个字符缩进”),或者使用“scripts/Lindent”,这样就可以以最时髦的方式缩进源代码。“indent”有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过记住:“indent”不能修正坏的编程习惯。


                    第十章:Kconfig配置文件

    对于遍布源码树的所有Kconfig*配置文件来说,它们缩进方式与C代码相比有所不同。紧挨在“config”定义下面的行缩进一个制表符,帮助信息则再多缩进2个空格。比如:

    config AUDIT
            bool "Auditing support"
            depends on NET
            help
              Enable auditing infrastructure that can be used with another
              kernel subsystem, such as SELinux (which requires this for
              logging of avc messages output).  Does not do system-call
              auditing without CONFIG_AUDITSYSCALL.

    仍然被认为不够稳定的功能应该被定义为依赖于“EXPERIMENTAL”:

    config SLUB
            depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT
            bool "SLUB (Unqueued Allocator)"
            ...

    而那些危险的功能(比如某些文件系统的写支持)应该在它们的提示字符串里显著的声明这一点:

    config ADFS_FS_RW
            bool "ADFS write support (DANGEROUS)"
            depends on ADFS_FS
            ...

    要查看配置文件的完整文档,请看Documentation/kbuild/kconfig-language.txt。


                    第十一章:数据结构

    如果一个数据结构,在创建和销毁它的单线执行环境之外可见,那么它必须要有一个引用计数器。内核里没有垃圾收集(并且内核之外的垃圾收集慢且效率低下),这意味着你绝对需要记录你对这种数据结构的使用情况。

    引用计数意味着你能够避免上锁,并且允许多个用户并行访问这个数据结构——而不需要担心这个数据结构仅仅因为暂时不被使用就消失了,那些用户可能不过是沉睡了一阵或者做了一些其他事情而已。

    注意上锁不能取代引用计数。上锁是为了保持数据结构的一致性,而引用计数是一个内存管理技巧。通常二者都需要,不要把两个搞混了。

    很多数据结构实际上有2级引用计数,它们通常有不同“类”的用户。子类计数器统计子类用户的数量,每当子类计数器减至零时,全局计数器减一。

    这种“多级引用计数”的例子可以在内存管理(“struct mm_struct”:mm_users和
    mm_count)和文件系统(“struct super_block”:s_count和s_active)中找到。

    记住:如果另一个执行线索可以找到你的数据结构,但是这个数据结构没有引用计数器,这里几乎肯定是一个bug。


                    第十二章:宏,列举(enum)RTL

    定义常量和列举里的标签的宏的名字需要大写。

    #define CONSTANT 0x12345

    在定义几个相关的常量时,最好用列举。

    宏的名字请用大写字母,不过形如函数的宏的名字可以用小写字母。

    一般的,如果能写成内联函数就不要写成像函数的宏。

    含有多个语句的宏应该被包含在一个do-while代码块里:

    #define macrofun(a, b, c)                      \
            do {                                   \
                    if (a == 5)                    \
                            do_this(b, c);         \
            } while (0)

    使用宏的时候应避免的事情:

    1) 影响控制流程的宏:

    #define FOO(x)                                 \
            do {                                   \
                    if (blah(x) < 0)               \
                            return -EBUGGERED;     \
            } while(0)

    非常不好。它看起来像一个函数,不过却能导致“调用”它的函数退出;
    don't break the internal parsers of those who will read the code.


    2) 依赖于一个固定名字的本地变量的宏:

    #define FOO(val) bar(index, val)

    可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起来不相关的改动带来错误。

    3) 作为左值的带参数的宏: FOO(x) = y;如果有人把FOO变成一个内联函数的话,这种用法就会出错了。

    4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数的宏也要注意此类问题。

    #define CONSTANT 0x4000
    #define CONSTEXP (CONSTANT | 3)
    cpp手册对宏的讲解很详细。Gcc internals手册也详细讲解了RTL(译注:register
    transfer language),内核里的汇编语言经常用到它。


                    第十三章:打印内核消息

    内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、
    明了、无歧义。

    内核信息不必以句点结束。

    在小括号里打印数字(%d)没有任何价值,应该避免这样做。

    <linux/device.h>里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(),
    dev_info()等等。对于那些不和某个特定设备相关连的信息,<linux/kernel.h>定义了pr_debug()和pr_info()。

    写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候就会成为极大的帮助。当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里(也就是说,默认地,它们不应该被包含在内)。如果你使用dev_dbg()或者pr_debug(),就能自动达到这个效果。很多子系统拥有Kconfig选项来启用-DDEBUG。还有一个相关的惯例是使用VERBOSE_DEBUG来添加dev_vdbg()消息到那些已经由DEBUG启用的消息之上。


                    第十四章:分配内存

    内核提供了下面的一般用途的内存分配函数:kmalloc(),kzalloc(),kcalloc()和
    vmalloc()。请参考API文档以获取有关它们的详细信息。
    传递结构体大小的首选形式是这样的:

            p = kmalloc(sizeof(*p), ...);

    另外一种传递方式中,sizeof的操作数是结构体的名字,这样会降低可读性,并且可能会引入bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的sizeof的结果不变。

    强制转换一个void指针返回值是多余的。C语言本身保证了从void指针到其他任何指针类型的转换是没有问题的


                    第十五章:内联弊病

    有一个常见的误解是内联函数是gcc提供的可以让代码运行更快的一个选项。虽然使用内联函数有时候是恰当的(比如作为一种替代宏的方式,请看第十二章),不过很多情况下不是这样。inline关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核会占用更多的指令高速缓存(译注:一级缓存通常是指令缓存和数据缓存分开的)而且会导致pagecache的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址,将耗时5毫秒。5毫秒的时间内CPU能执行很多很多指令。

    一个基本的原则是如果一个函数有3行以上,就不要把它变成内联函数。这个原则的一个例外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在编译时能优化掉你的函数的大部分代码,那仍然可以给它加上inline关键字。kmalloc()内联函数就是一个很好的例子。

    人们经常主张给static的而且只用了一次的函数加上inline,不会有任何损失,因为这种情况下没有什么好权衡的。虽然从技术上说,这是正确的,不过gcc可以在没有提示的情况下自动使其内联,而且其他用户可能会要求移除inline,此种维护上的争论会抵消可以告诉gcc来做某些事情的提示带来的潜在价值。不管有没有inline,这种函数都会被内联。


                    第十六章:函数返回值及命名

    函数可以返回很多种不同类型的值,最常见的一种是表明函数执行成功或者失败的值。这样的一个值可以表示为一个错误代码整数(-E**=失败,0=成功)或者一个“成功”布尔值(0=失败,非0=成功)。

    混合使用这两种表达方式是难于发现的bug的来源。如果C语言本身严格区分整形和布尔型变量,那么编译器就能够帮我们发现这些错误……不过C语言不区分。为了避免产生这种bug,请遵循下面的惯例:

            如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代码
            整数。如果是一个判断,那么函数应该返回一个“成功”布尔值。

    比如,“add work”是一个命令,所以add_work()函数在成功时返回0,在失败时返回
    -EBUSY。类似的,因为“PCI device present”是一个判断,所pci_dev_present()函数在成功找到一个匹配的设备时应该返回1,如果找不到时应该返回0。

    所有导出(译注:EXPORT)的函数都必须遵守这个惯例,所有的公共函数也都应该如此。私有(static)函数不需要如此,但是我们也推荐这样做。

    返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的,他们通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,他们使用NULL或者ERR_PTR机制来报告错误。


                    第十七章:不要重新发明内核宏

    头文件include/linux/kernel.h包含了一些宏,你应该使用它们,而不要自己写一些它们的变种。比如,如果你需要计算一个数组的长度,使用这个宏

      #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

    类似的,如果你要计算某结构体成员的大小,使用

      #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

    还有可以做严格的类型检查的min()和max()宏,如果你需要可以使用它们。你可以自己看看那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应在你的代码里自己重新定义。


                    第十八章:编辑器模式行和其他需要罗嗦的事情

    有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs能够解释被标记成这样的行:

    -*- mode: c -*-

    或者这样的:

    /*
    Local Variables:
    compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
    End:
    */

    Vim能够解释这样的标记:

    /* vim:set sw=8 noet */

    不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模式,或者使用其他可以产生正确的缩进的巧妙方法。

    展开全文
  • 作为助力企业经营决策的大数据可视化应用,对于的企业发展起着至关重要的作用,但是如何利用大数据可视化,如何做好大数据可视化,今天小编就给大家介绍款实用的工具,帮助大家在大数据的海洋里开发出一片宝藏。...

      俗话说的好,逆水行舟,不进则退,在快速发展的今天,紧跟时代的步伐,抓住时代的脉搏,才能助力企业激流勇进,抢占先机。作为助力企业经营决策的大数据可视化应用,对于的企业发展起着至关重要的作用,但是如何利用大数据可视化,如何做好大数据可视化,今天小编就给大家介绍几款实用的工具,帮助大家在大数据的海洋里开发出一片宝藏。

      1、ChartBlocks

      如果你用够了PS、AI,ChartBlocks对你来说或许是个不错的选择,这是一个易于使用在线工具,你无须进行下载安装,同样也不需要你进行编码,通过它,你可以从电子表格,数据库中构建可视化图表。整个过程可以在图表向导的指导下完成。你的图表将在HTML5的框架下使用强大的JavaScript库D3.js创建图表。你的图表是响应式的,并且可以和任何的屏幕尺寸及设备兼容。你还可以将图表嵌入任何网页中,分享在Twitter和Facebook上。

      2、D3.js

      最为一个资深的前端工程师,对你来说D3.js无疑是最好的数据可视化工具库。d3厉害的地方在于它建立了一整套数据到SVG属性的计算框架,常用Datavisualization模型,大多都可以再d3.layout里面找到,。D3.js运行在JavaScript上,并使用HTML,CSS和SVG。D3.js是开源工具,使用数据驱动的方式创建漂亮的网页。D3.js可实现实时交互。这个库非常强大和前沿,所以它带有没有预置图表也不支持IE9。

      3、Tableau

      Tableau公司将数据运算与美观的图表完美地嫁接在一起。它的程序很容易上手,各公司可以用它将大量数据拖放到数字"画布"上,转眼间就能创建好各种图表。这一软件的理念是,界面上的数据越容易操控,公司对自己在所在业务领域里的所作所为到底是正确还是错误,就能了解得越透彻。其两种不同的变体是基于云计算的TableauOnline和TableauServer。

      它们都是为与大数据有关的组织设计的。企业使用这个工具非常方便,而且提供了闪电般的速度。还有一件事对这个工具是肯定的,Tableau具有用户友好的特性,并与拖放功能兼容。

      4、RssVoyage

      给大家推荐一个小编个人比较喜欢的,且确实有助于形象化各地数据的网络数据的网站。如果您登录到RssVoyage,你可以导入自定义RSS供稿到您的帐户一整个数据图。在他们的网页,你可以点击"开始"与默认提供的应用程序。在这种情况下RssVoyage将拉动几个流行的博客,如纽约时报,瘾科技,卫报,等等。

      如果您通过移动图形,点击一个特定的文章的观点时,他将固定在屏幕上。这包括标题,简短描述,元数据连同它的URL出版日期。如果在任何时候你想开始创建自己的RSS可视化,所有你需要做的就是创建一个帐户!

      注册是完全免费的,你可以在页面的底部创建通过注册表格您的帐户。作为另一奖励功能

      RssVoyage可以让你轻松设置全屏模式浏览风格的RSS源。

      5、TagGalaxy

      TagGalaxy是一个非常独特的可视化工具。他们的主页干净且易于理解,因为标签Flickr上有单独的一个搜索表单。此外左下角设有为新用户一些流行的建议。只需输入一个词,然后按Enter,通过Flickr的照片就可在TagGalaxy查询。

      他们的渲染引擎复制我们的太阳系的中心,太阳代表主要搜索项的外观,外部行星的轨道代表类似的标签。这是我见过的最酷的可视化演示渲染和Flash之一。

      注意,当您在每个星球上悬停它会为你提供一个小的预览数。这是发现在Flickr的该标签的询问的照片总数。点击太阳将打开相关照片缩略图的球体,而旋转的行星会增加他们的搜索字词的查询。当然,你可以找到更多有关照片通过点击弹出完整视图。

      6、GoogleChart

      GoogleCharts以HTML5和SVG为基础,充分考虑了跨浏览器的兼容性,并通过VML支持旧版本的IE浏览器。所有您将创建的图表是交互式的,有的还可缩放。GoogleCharts是非常人性化和他们的网站拥有一个非常好的,全面的模板库,你可以从中找到所需模板。

      不言而喻,它绝对是企业可以使用的可视化大数据集的最简单的工具。GoogleChart中有一大堆图表库,从线图到分层结构,可以满足任何需求。如果企业想深入挖掘,甚至可以寻求某种技术上的帮助。

      作为大数据可视化应用的工具,其实不光以上说的6种,还有很多很多,在这里我们不可能全部列举,但是关键是适合自己就好,所以,小伙伴,你用的是哪款软件呢?


    1.大数据的五大核心技术,给大数据同行入门研究参考的小知识

    http://www.duozhishidai.com/article-2242-1.html

    2.大数据时代,主要需要什么类型的人才?

    http://www.duozhishidai.com/article-1554-1.html

    3.云计算、大数据和物联网三者之间,有哪些区别和联系?

    http://www.duozhishidai.com/article-1171-1.html

     

    展开全文
  • Linux C编码风格

    千次阅读 2012-02-10 10:14:52
    代码风格好不好就像字写得好不好看一样,如果一个公司招聘秘书,肯定不要字写得难看的,同理,代码风格糟糕的程序员肯定也是不称职的。虽然编译器不会挑剔难看的代码,照样能编译通过,但是和你一个team的其他程序员...
  • Android代码贡献者编码风格指南

    千次阅读 2014-05-07 10:28:46
    当使用这些代码的时候,遵循已风格也是可以的。当写一些新的组件时,不要再使用过时的类库。   Java 风格规范   1  使用 Javadoc 标准注释   所有的文件都应该在顶部一个版权声明。紧...
  • ROS的编码风格和命名约定

    千次阅读 2018-03-09 17:09:35
    参考:http://wiki.ros.org/CppStyleGuide可以使用clang-format来自动格式化(不要理解错了,formatting)你的代码.1、命名规则以下几种命名格式:CamelCased:名称以大写字母开头,每个新单词都大写字母,不带...
  • 阿里腾讯都在用的Restful编码风格

    千次阅读 多人点赞 2020-05-12 21:24:52
    基于这个风格设计的软件可以更简洁,更层次,更易于实现缓存等机制。 REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。它首次出现在 2000 年 Roy ...
  • 一些人喜欢在编码时一个挨一个地同时打开个窗口,而80个字符的宽度正好可以摆放这些窗口。80字符宽度似乎已成为大多数开发人员开发环境的最大窗口宽度,那还改变它干吗呢? 弊:求变者认为更长的代码行可以增加...
  • Linux Kernel编码风格(中文版)

    千次阅读 2011-12-22 21:07:59
    代码风格好不好就像字写得好不好看一样,如果一个公司招聘秘书,肯定不要字写得难看的,同理,代码风格糟糕的程序员肯定也是不称职的。虽然编译器不会挑剔难看的代码,照样能编译通过,但是和你一个team的其他程序员...
  • 注:转自... 关于endia参考上一篇。 问题一:  ...使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码
  • [CodingStyle]中关于空白字符并没有特别规定,因为基本上所有的C代码风格对于空白字符的规定都差不多,主要以下条。 1、关键字if、while、for与其后的控制表达式的(括号之间插入一个空格分隔,但括号内的...
  • 编码风格指南写在 Melange 项目的 Wiki 上,可以遵循已的 文档复查流程 ? 进行修改。但不应该轻易修改本文,因为 一致性 是本指南的一个关键目标,而且不能因为新的风格指南变化而需要更新旧代码。 ...
  • 问题一: 使用Windows记事本的“另存为”,可以在GBK、Unicode、Unicode big endian和UTF-8这 几种编码方式间相互转换。同样是txt文件,Windows是怎样识别编码方式的呢? 我很早前就发现Unicode、Unicode big ...
  • Code Style Guidelines forContributors 版本:Android 4.0r1 ... 以下规则并非指导或推荐的性质,而是必须遵守的规定。如果不遵守这些规定,...已的代码未必全部遵守了这些规定,但是新的代码全部都应该遵守。
  • 几种常用的设计模式介绍

    万次阅读 多人点赞 2013-11-16 18:17:27
    几种常用的设计模式介绍 1.  设计模式的起源 最早提出“设计模式”概念的是建筑设计大师亚力山大Alexander。在1970年他的《建筑的永恒之道》里描述了投计模式的发现,因为它已经存在了千百年之久,而现代才被...
  • Kotlin入门(20)几种常见的对话框

    千次阅读 2018-09-27 22:58:55
    手机上的App极大地方便了人们的生活,很多业务只需用户拇指一点即可轻松办理,然而这也带来了一定的风险,因为时候用户并非真的想这么做,只是不小心点了一下而已,如果App不做任何提示的话,继续吭哧吭哧兀自办完...
  • 信源编码的三方式与实现

    万次阅读 多人点赞 2019-01-15 02:01:21
    信源编码的三方式与实现一、本文概述二、编码原理1. 哈夫曼编码2. 算术编码3. LZ编码三、算法设计思路1. 哈夫曼编码a. 设置功能结构体和函数b. 压缩文件初始化统计表频度读入文件并统计频度对统计表频度排序建立...
  • 由delphi 转向c++开发,虽然不是简单的语法格式问题,但在delphi底下积累起来的年的OO经验,也让我养成了自己还算看得顺眼的编码风格。但是,近日在看一些公司内部文档以及网上的一些开源代码,对这些代码的编写...
  • Android开发——去掉系统自带标题栏的几种方式

    万次阅读 多人点赞 2017-07-24 10:34:51
    隐藏系统自带标题栏的几种方法
  • 几种常见数据库连接池

    万次阅读 2017-06-30 07:54:01
    感觉在介绍之前必要阐述一下连接池的个概念,助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库 都...
  • 调用WebService的几种方式

    万次阅读 2017-12-22 10:43:44
    JAVA 中共WebService 规范,分别是 JAX-WS (JAX-RPC)、JAXM&SAAJ、JAX-RS。 1. Jaxws( 掌握 ) JAX-WS 的全称为 Java API for XML-Based Webservices ,早期的基于SOAP 的JAVA 的Web 服务规范JAX...
  • 常用的几种文件封装格式

    千次阅读 2016-12-30 15:33:10
    所谓文件封装格式也称多媒体容器(Multimedia Container),与DivX、MP3这类编码格式不同的是,它只是为多媒体编码提供了一个“外壳”,也就是将所有的处理好的视频、音频都包装到一个文件容器内呈现给观众,这个...
  • 原文:Six programming...译者注:本文介绍了六编程范式,提到了不少小众语言,作者希望借此让大家更多的了解一些非主流的编程范式,进而改变对编程的看法。以下为译文:时不时地,我会发现一些编程语言所做的一些...
  • Android 编码规范

    千次阅读 2016-06-30 15:10:27
    这份文档参考了 Google Java 编程风格规范和 Google 官方 Android 编码风格规范。该文档仅供参考,只要形成一个统一的风格,见量知其意就可。 1.1 术语说明在本文档中,除非另有说明:术语 class 可表示一个普通类...
  • 几种常用的加密方式简单介绍

    千次阅读 2017-07-13 15:46:31
    1 Base64加密方式(可逆) ...Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一散列函数,用以提供消息的完整性保护 是计算机广泛使用的杂凑算法之一(又译摘
  • 几种常见数据库连接池的使用比较

    万次阅读 多人点赞 2016-11-23 20:35:32
    感觉在介绍之前必要阐述一下连接池的个概念,助于后边一些文字的理解。 最原始的数据库使用就是打开一个连接并进行使用,使用过后一定要关闭连接释放资源。由于频繁的打开和关闭连接对jvm包括数据库 都...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 85,753
精华内容 34,301
热门标签
关键字:

编码风格有哪几种