以下内容来自GNOME的开发文档,https://developer.gnome.org/documentation/guidelines/programming/coding-style.html 。
缩进 Linux 内核风格是一个tab缩进8个字符,GNU风格是一个tab 2个字符,这两种都可以,但要统一。
括号 if else,如果只有一条语句,可以不写大括号,如下:
1 2 3 4 5 if (condition) single_statement (); else another_single_statement (arg1);
但也有例外。
第一种,if语句有大括号,else语句也要有大括号。
1 2 3 4 5 6 7 8 9 10 if (condition) { foo (); bar (); } else { baz (); }
第二种,单个语句写了多行,也要用大括号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 if (condition) { a_single_statement_with_many_arguments (some_lengthy_argument, another_lengthy_argument, and_another_one, plus_one); } else another_single_statement (arg1, arg2); if (condition) { a_single_statement_with_many_arguments (some_lengthy_argument, another_lengthy_argument, and_another_one, plus_one); } else { another_single_statement (arg1, arg2); }
第三种,如果if的条件有多行,也需要用大括号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (condition1 || (condition2 && condition3) || condition4 || (condition5 && (condition6 || condition7))) { a_single_statement (); } if (condition1 || (condition2 && condition3) || condition4 || (condition5 && (condition6 || condition7))) { a_single_statement (); }
第四种情况,if嵌套,这时也需要用大括号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 if (condition) { if (another_condition) single_statement (); else another_single_statement (); } if (condition) { if (another_condition) single_statement (); else another_single_statement (); }
函数 函数返回值类型独占一行
1 2 3 4 5 void my_function (void ) { }
函数参数一行一个,参数名称左对齐
1 2 3 4 5 6 7 8 void my_function (some_type_t type, another_type_t *a_pointer, double_ptr_t **double_pointer, final_type_t another_type) { }
空格 在括号前加空格,不要在括号后加空格
1 2 3 4 5 if (condition) do_my_things (); switch (condition) {}
定义结构体时,使用空行,将不同类型的数据隔开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 struct _GtkWrapBoxPrivate { GtkOrientation orientation; GtkWrapAllocationMode mode; GtkWrapBoxSpreading horizontal_spreading; GtkWrapBoxSpreading vertical_spreading; guint16 spacing[2 ]; guint16 minimum_line_children; guint16 natural_line_children; GList *children; };
不要 随便删除空行或空格,下面是错误的示范
1 2 if (condition) foo (); else bar ();
switch 每个case的缩进级别应该相同,而且case的缩进应该与switch的大括号级别一致,一个case结束后,加一个空行,再开始下一个case。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 switch (condition) {case FOO: do_foo (); break ; case BAR: do_bar (); break ; } switch (condition) { case FOO: do_foo (); break ; case BAR: do_bar (); break ; default : do_default (); }
头文件 头文件中函数定义要用三列。
1 2 3 return_type function_name (type argument, type argument, type argument) ;
每列最大的宽度要以每列中最大的宽度为准。
1 2 3 4 void gtk_type_set_property (GtkType *type, const char *value, GError **error) ;const char *gtk_type_get_property (GtkType *type) ;
如果要定义一个公共库,把小的头文件包括到单一的一个公共库头文件中,而不是在应用中导入多个小的头文件。比如,GTK库定义了一些头文件,但是能直接调用的,就是gtk.h,其他的库不能在应用中直接调用。
1 2 3 4 5 6 #if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION) #error "Only <gtk/gtk.h> can be included directly." #endif
对于库,所有的头文件都要有inclusion guards。下面这串代码演示了如何使用#ifndef和#endif来避免头文件被重复引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #pragma once #ifndef TIME_H #define TIME_H class time { public: Time(); void setTime (int , int , int ) ; void printUniversal () const ; void printStandard () const ; private: unsigned int hour; unsigned int minute; unsigned int second; }; #endif
GObject 类 类型声明应该放在文件最开始的位置
1 2 typedef struct _GtkBoxedStruct GtkBoxedStruct ;typedef struct _GtkMoreBoxedStruct GtkMoreBoxedStruct ;
下面的没看懂什么意思……
内存申请 在堆栈中动态申请内存,用g_new(), 公共的结构类型要填充0,或是使用g_new0()来申请内存。
宏Macros 尽量避免用私有宏,返回的时候,记得#undef它们,最好是使用inline函数。公共宏除非是返回一个常值,否则不要使用。