寫出漂亮規范的代碼!分享一份嵌入式C編碼規范(收藏細讀)

芯片之家 2025-01-23 20:58
英文原文:https://github.com/MaJerle/c-code-style#structures-enumerations-typedefs
譯文來源:嵌入式大雜燴

最重要的一條規則

編寫代碼時最重要的一條規則是:檢查周圍的代碼并嘗試模仿它。

作為維護人員,如果收到的補丁明顯與周圍代碼的編碼風格不同,這是令人沮喪的。這是不尊重人的,就像某人穿著泥濘的鞋子走進一間一塵不染的房子。

因此,無論本文推薦的是什么,如果已經編寫了代碼并且您正在對其進行修補,請保持其當前的樣式一致,即使它不是您最喜歡的樣式。

一般規則

這里列出了最明顯和最重要的一般規則。在你繼續閱讀其他章節之前,請仔細檢查它們。

  • 使用C99標準

  • 不使用制表符,而是使用空格

  • 每個縮進級別使用4個空格

  • 在關鍵字和左括號之間使用一個空格

  • 在函數名和左括號之間不要使用空格

int32_t?a?=?sum(4,?3);??????????????/*?OK?*/
int32_t?a?=?sum?(4,?3);?????????????/*?Wrong?*/
  • 不要在變量/函數/宏/類型中使用__或_前綴。這是為C語言本身保留的

  • 對于嚴格的模塊私有函數,使用prv_ name前綴

  • 對于包含下劃線_ char的變量/函數/宏/類型,只能使用小寫字母

  • 左花括號總是與關鍵字(for, while, do, switch, if,…)在同一行

size_t?i;
for?(i?=?0;?i?5;?++i)?{???????????/*?OK?*/
}
for?(i?=?0;?i?5;?++i){????????????/*?Wrong?*/
}
for?(i?=?0;?i?5;?++i)?????????????/*?Wrong?*/
{
}
  • 在比較操作符和賦值操作符之前和之后使用單個空格
int32_t?a;
a?=?3?+?4;??????????????/*?OK?*/
for?(a?=?0;?a?5;?++a)?/*?OK?*/
a=3+4;??????????????????/*?Wrong?*/
a?=?3+4;????????????????/*?Wrong?*/
for?(a=0;a<5;++a)???????/*?Wrong?*/
  • 每個逗號后用單空格
func_name(5,?4);????????/*?OK?*/
func_name(4,3);?????????/*?Wrong?*/
  • 不要初始化靜態和全局變量為0(或NULL),讓編譯器為您做
static?int32_t?a;???????/*?OK?*/
static?int32_t?b?=?4;???/*?OK?*/
static?int32_t?a?=?0;???/*?Wrong?*/

void
my_func(void)?
{
????static?int32_t*?ptr;/*?OK?*/
????static?char?abc?=?0;/*?Wrong?*/
}
  • 在同一行中聲明所有相同類型的局部變量
void
my_func(void)?
{
????char?a;?????????????/*?OK?*/
????char?b;?????????????/*?Wrong,?variable?with?char?type?already?exists?*/
????char?a,?b;??????????/*?OK?*/
}
  • 按順序聲明局部變量

i.自定義結構和枚舉

ii.整數類型,更寬的無符號類型優先

iii.單/雙浮點

int
my_func(void)?
{
????/*?1?*/
????my_struct_t?my;?????/*?First?custom?structures?*/
????my_struct_ptr_t*?p;?/*?Pointers?too?*/

????/*?2?*/
????uint32_t?a;
????int32_t?b;
????uint16_t?c;
????int16_t?g;
????char?h;
????/*?...?*/

????/*?3?*/
????double?d;
????float?f;
}
  • 總是在塊的開頭聲明局部變量,在第一個可執行語句之前
  • 在for循環中聲明計數器變量
/*?OK?*/
for?(size_t?i?=?0;?i?10;?++i)

/*?OK,?if?you?need?counter?variable?later?*/
size_t?i;
for?(i?=?0;?i?10;?++i)?{
????if?(...)?{
????????break;
????}
}
if?(i?==?10)?{

}

/*?Wrong?*/
size_t?i;
for?(i?=?0;?i?10;?++i)?...
  • 避免在聲明中使用函數調用來賦值變量,除了單個變量
void
a(void)?
{
????/*?Avoid?function?calls?when?declaring?variable?*/
????int32_t?a,?b?=?sum(1,?2);

????/*?Use?this?*/
????int32_t?a,?b;
????b?=?sum(1,?2);

????/*?This?is?ok?*/
????uint8_t?a?=?3,?b?=?4;
}
  • 除了char、float或double之外,始終使用stdint.h標準庫中聲明的類型。例如,8位的uint8_t等

  • 不要使用stdbool.h庫。分別使用1或0表示真或假

/*?OK?*/
uint8_t?status;
status?=?0;

/*?Wrong?*/
#include?
bool?status?=?true;
  • 永遠不要與真實相比較。例如,使用if(check_func()){…}替換if (check_func() == 1)

  • 總是將指針與空值進行比較

void*?ptr;

/*?...?*/

/*?OK,?compare?against?NULL?*/
if?(ptr?==?NULL?||?ptr?!=?NULL)?{

}

/*?Wrong?*/
if?(ptr?||?!ptr)?{

}
  • 總是使用前增量(和遞減),而不是后增量(和遞減)
int32_t?a?=?0;
...

a++;????????????/*?Wrong?*/
++a;????????????/*?OK?*/

for?(size_t?j?=?0;?j?10;?++j)?{}??/*?OK?*/
  • 總是使用size_t作為長度或大小變量

  • 如果函數不應該修改指針所指向的內存,則總是使用const作為指針

  • 如果不應該修改函數的形參或變量,則總是使用const

/*?When?d?could?be?modified,?data?pointed?to?by?d?could?not?be?modified?*/
void
my_func(const?void*?d)?
{

}

/*?When?d?and?data?pointed?to?by?d?both?could?not?be?modified?*/
void
my_func(const?void*?const?d)?
{

}

/*?Not?required,?it?is?advised?*/
void
my_func(const?size_t?len)?
{

}

/*?When?d?should?not?be?modified?inside?function,?only?data?pointed?to?by?d?could?be?modified?*/
void
my_func(void*?const?d)?
{

}
  • 當函數可以接受任何類型的指針時,總是使用void *,不要使用uint8_t *。函數在實現時必須注意正確的類型轉換
/*
?*?To?send?data,?function?should?not?modify?memory?pointed?to?by?`data`?variable
?*?thus?`const`?keyword?is?important
?*
?*?To?send?generic?data?(or?to?write?them?to?file)
?*?any?type?may?be?passed?for?data,
?*?thus?use?`void?*`
?*/

/*?OK?example?*/
void
send_data(const?void*?data,?size_t?len)?
{?/*?OK?*/
????/*?Do?not?cast?`void?*`?or?`const?void?*`?*/
????const?uint8_t*?d?=?data;/*?Function?handles?proper?type?for?internal?usage?*/
}

void
send_data(const?void*?data,?int?len)?
{????/*?Wrong,?not?not?use?int?*/
}
  • 總是使用括號和sizeof操作符

  • 不要使用變長數組。使用動態內存分配代替標準C malloc和自由函數,或者如果庫/項目提供了自定義內存分配,使用它的實現

    看看LwMEM,一個自定義內存管理庫。

/*?OK?*/
#include?
void
my_func(size_t?size)?
{
????int32_t*?arr;
????arr?=?malloc(sizeof(*arr)?*?n);?/*?OK,?Allocate?memory?*/
????arr?=?malloc(sizeof?*arr?*?n);??/*?Wrong,?brackets?for?sizeof?operator?are?missing?*/
????if?(arr?==?NULL)?{
????????/*?FAIL,?no?memory?*/
????}

????free(arr);??/*?Free?memory?after?usage?*/
}

/*?Wrong?*/
void
my_func(size_t?size)?
{
????int32_t?arr[size];??/*?Wrong,?do?not?use?VLA?*/
}
  • 總是將variable與0進行比較,除非它被視為布爾類型

  • 永遠不要將布爾處理的變量與0或1進行比較。用NOT(!)代替

size_t?length?=?5;??/*?Counter?variable?*/
uint8_t?is_ok?=?0;??/*?Boolean-treated?variable?*/
if?(length)?????????/*?Wrong,?length?is?not?treated?as?boolean?*/
if?(length?>?0)?????/*?OK,?length?is?treated?as?counter?variable?containing?multi?values,?not?only?0?or?1?*/
if?(length?==?0)????/*?OK,?length?is?treated?as?counter?variable?containing?multi?values,?not?only?0?or?1?*/

if?(is_ok)??????????/*?OK,?variable?is?treated?as?boolean?*/
if?(!is_ok)?????????/*?OK,?-||-?*/
if?(is_ok?==?1)?????/*?Wrong,?never?compare?boolean?variable?against?1!?*/
if?(is_ok?==?0)?????/*?Wrong,?use?!?for?negative?check?*/
  • 對于注釋,總是使用/* comment */,即使是單行注釋
  • 在頭文件中總是包含帶有extern關鍵字的c++檢查
  • 每個函數都必須包含doxygen-enabled注釋,即使函數是靜態的
  • 使用英文名稱/文本的函數,變量,注釋
  • 變量使用小寫字母
  • 如果變量包含多個名稱,請使用下劃線。force_redraw。不要使用forceRedraw
  • 對于C標準庫的包含文件,請始終使用<和>。例如,# include < stdlib.h >
  • 對于自定義庫,請始終使用""。例如,# include“my_library.h”
  • 當轉換為指針類型時,總是將星號與類型對齊,例如。uint8_t* t = (uint8_t*)var_width_diff_type
  • 始終尊重項目或庫中已經使用的代碼風格

注釋

  • 不允許以//開頭的注釋。總是使用/* comment */,即使是單行注釋
//This?is?comment?(wrong)
/*?This?is?comment?(ok)?*/
  • 對于多行注釋,每行使用空格+星號
/*
?*?This?is?multi-line?comments,
?*?written?in?2?lines?(ok)
?*/


/**
?*?Wrong,?use?double-asterisk?only?for?doxygen?documentation
?*/


/*
*?Single?line?comment?without?space?before?asterisk?(wrong)
*/


/*
?*?Single?line?comment?in?multi-line?configuration?(wrong)
?*/


/*?Single?line?comment?(ok)?*/
  • 注釋時使用12個縮進(12 * 4個空格)偏移量。如果語句大于12個縮進,將注釋4-空格對齊(下面的例子)到下一個可用縮進
void
my_func(void)?
{
????char?a,?b;

????a?=?call_func_returning_char_a(a);??????????/*?This?is?comment?with?12*4?spaces?indent?from?beginning?of?line?*/
????b?=?call_func_returning_char_a_but_func_name_is_very_long(a);???/*?This?is?comment,?aligned?to?4-spaces?indent?*/
}

函數

  • 每個可以從模塊外部訪問的函數都必須包含函數原型(或聲明)

  • 函數名必須小寫,可以用下劃線_分隔

/*?OK?*/
void?my_func(void);
void?myfunc(void);

/*?Wrong?*/
void?MYFunc(void);
void?myFunc();
  • 當函數返回指針時,將星號對齊到返回類型
/*?OK?*/
const?char*?my_func(void);
my_struct_t*?my_func(int32_t?a,?int32_t?b);

/*?Wrong?*/
const?char?*my_func(void);
my_struct_t?*?my_func(void);
  • 對齊所有的功能原型(使用相同/相似的功能)以提高可讀性
/*?OK,?function?names?aligned?*/
void????????set(int32_t?a);
my_type_t???get(void);
my_ptr_t*???get_ptr(void);

/*?Wrong?*/
void?set(int32_t?a);
const?char?*?get(void);
  • 函數實現必須在單獨的行中包含返回類型和可選的其他關鍵字
/*?OK?*/
int32_t
foo(void)?
{
????return?0;
}

/*?OK?*/
static?const?char*
get_string(void)?
{
????return?"Hello?world!\r\n";
}

/*?Wrong?*/
int32_t?foo(void)?{
????return?0;
}

變量

  • 使變量名全部小寫,下劃線_字符可選
/*?OK?*/
int32_t?a;
int32_t?my_var;
int32_t?myvar;

/*?Wrong?*/
int32_t?A;
int32_t?myVar;
int32_t?MYVar;
  • 按類型將局部變量分組在一起
void
foo(void)?
{
????int32_t?a,?b;???/*?OK?*/
????char?a;
????char?b;?????????/*?Wrong,?char?type?already?exists?*/
}
  • 不要在第一個可執行語句之后聲明變量
void
foo(void)?
{
????int32_t?a;
????a?=?bar();
????int32_t?b;??????/*?Wrong,?there?is?already?executable?statement?*/
}
  • 你可以在下一個縮進級別中聲明新的變量
int32_t?a,?b;
a?=?foo();
if?(a)?{
????int32_t?c,?d;???/*?OK,?c?and?d?are?in?if-statement?scope?*/
????c?=?foo();
????int32_t?e;??????/*?Wrong,?there?was?already?executable?statement?inside?block?*/
}
  • 用星號聲明指針變量與類型對齊
/*?OK?*/
char*?a;

/*?Wrong?*/
char?*a;
char?*?a;
  • 當聲明多個指針變量時,可以使用星號對變量名進行聲明
/*?OK?*/
char?*p,?*n;

結構、枚舉類型定義

  • 結構名或枚舉名必須小寫,單詞之間有下劃線_字符

  • 結構或枚舉可以包含typedef關鍵字

  • 所有結構成員都必須小寫

  • 所有枚舉成員必須是大寫的

  • 結構/枚舉必須遵循doxygen文檔語法

在聲明結構體時,它可以使用以下三種不同的選項之一:

1、當結構體僅用名稱聲明時,它的名稱后不能包含_t后綴。

struct?struct_name?{
????char*?a;
????char?b;
};

2、當只使用typedef聲明結構時,它的名稱后面必須包含_t后綴。

typedef?struct?{
????char*?a;
????char?b;
}?struct_name_t;

3、當結構用name和typedef聲明時,它不能包含_t作為基本名稱,它必須在它的名稱后面包含_t后綴作為typedef部分。

typedef?struct?struct_name?{
????char*?a;
????char?b;
????char?c;
}?struct_name_t;

錯誤聲明的例子及其建議的糾正:

/*?a?and?b?must?be?separated?to?2?lines?*/
/*?Name?of?structure?with?typedef?must?include?_t?suffix?*/
typedef?struct?{
????int32_t?a,?b;
}?a;

/*?Corrected?version?*/
typedef?struct?{
????int32_t?a;
????int32_t?b;
}?a_t;

/*?Wrong?name,?it?must?not?include?_t?suffix?*/
struct?name_t?{
????int32_t?a;
????int32_t?b;
};

/*?Wrong?parameters,?must?be?all?uppercase?*/
typedef?enum?{
????MY_ENUM_TESTA,
????my_enum_testb,
}?my_enum_t;
  • 在聲明時初始化結構時,使用C99初始化風格
/*?OK?*/
a_t?a?=?{
????.a?=?4,
????.b?=?5,
};

/*?Wrong?*/
a_t?a?=?{1,?2};
  • 當為函數句柄引入new typedef時,使用_fn后綴
/*?Function?accepts?2?parameters?and?returns?uint8_t?*/
/*?Name?of?typedef?has?`_fn`?suffix?*/
typedef?uint8_t?(*my_func_typedef_fn)(uint8_t?p1,?const?char*?p2);

復合語句

  • 每個復合語句必須包括左花括號和右花括號,即使它只包含1個嵌套語句

  • 每個復合語句必須包含單個縮進;嵌套語句時,每個嵌套包含1個縮進大小

/*?OK?*/
if?(c)?{
????do_a();
}?else?{
????do_b();
}

/*?Wrong?*/
if?(c)
????do_a();
else
????do_b();

/*?Wrong?*/
if?(c)?do_a();
else?do_b();
  • 在if或if-else-if語句的情況下,else必須與第一條語句的右括號在同一行
/*?OK?*/
if?(a)?{

}?else?if?(b)?{

}?else?{

}

/*?Wrong?*/
if?(a)?{

}
else?{

}

/*?Wrong?*/
if?(a)?{

}
else
{

}
  • 在do-while語句的情況下,while部分必須與do部分的右括號在同一行
/*?OK?*/
do?{
????int32_t?a;
????a?=?do_a();
????do_b(a);
}?while?(check());

/*?Wrong?*/
do
{
/*?...?*/
}?while?(check());

/*?Wrong?*/
do?{
/*?...?*/
}
while?(check());
  • 每一個開括號都需要縮進
if?(a)?{
????do_a();
}?else?{
????do_b();
????if?(c)?{
????????do_c();
????}
}
  • 不要做沒有花括號的復合語句,即使是單個語句。下面的例子展示了一些不好的做法
if?(a)?do_b();
else?do_c();

if?(a)?do_a();?else?do_b();
  • 空while循環、do-while循環或for循環必須包含花括號
/*?OK?*/
while?(is_register_bit_set())?{}

/*?Wrong?*/
while?(is_register_bit_set());
while?(is_register_bit_set())?{?}
while?(is_register_bit_set())?{
}
  • 如果while(或for、do-while等)為空(嵌入式編程中也可能是這種情況),請使用空的單行括號
/*?Wait?for?bit?to?be?set?in?embedded?hardware?unit
uint32_t*?addr?=?HW_PERIPH_REGISTER_ADDR;

/*?Wait?bit?13?to?be?ready?*/

while?(*addr?&?(1?<13))?{}????????/*?OK,?empty?loop?contains?no?spaces?inside?curly?brackets?*/
while?(*addr?&?(1?<13))?{?}???????/*?Wrong?*/
while?(*addr?&?(1?<13))?{?????????/*?Wrong?*/

}
while?(*addr?&?(1?<13));??????????/*?Wrong,?curly?brackets?are?missing.?Can?lead?to?compiler?warnings?or?unintentional?bugs?*/
  • 盡量避免在循環塊內遞增變量,參見示例
/*?Not?recommended?*/
int32_t?a?=?0;
while?(a?10)?{
????.
????..
????...
????++a;
}

/*?Better?*/
for?(size_t?a?=?0;?a?10;?++a)?{

}

/*?Better,?if?inc?may?not?happen?in?every?cycle?*/
for?(size_t?a?=?0;?a?10;?)?{
????if?(...)?{
????????++a;
????}
}

分支語句

  • 為每個case語句添加單個縮進
  • 使用額外的單縮進break語句在每個case或default
/*?OK,?every?case?has?single?indent?*/
/*?OK,?every?break?has?additional?indent?*/
switch?(check())?{
????case?0:
????????do_a();
????????break;
????case?1:
????????do_b();
????????break;
????default:
????????break;
}

/*?Wrong,?case?indent?missing?*/
switch?(check())?{
case?0:
????do_a();
????break;
case?1:
????do_b();
????break;
default:
????break;
}

/*?Wrong?*/
switch?(check())?{
????case?0:
????????do_a();
????break;??????/*?Wrong,?break?must?have?indent?as?it?is?under?case?*/
????case?1:
????do_b();?????/*?Wrong,?indent?under?case?is?missing?*/
????break;
????default:
????????break;
}
  • 總是包含default語句
/*?OK?*/
switch?(var)?{
????case?0:
????????do_job();
????????break;
????default:?break;
}

/*?Wrong,?default?is?missing?*/
switch?(var)?{
????case?0:
????????do_job();
????????break;
}
  • 如果需要局部變量,則使用花括號并在里面放入break語句。將左花括號放在case語句的同一行
switch?(a)?{
????/*?OK?*/
????case?0:?{
????????int32_t?a,?b;
????????char?c;
????????a?=?5;
????????/*?...?*/
????????break;
????}

????/*?Wrong?*/
????case?1:
????{
????????int32_t?a;
????????break;
????}

????/*?Wrong,?break?shall?be?inside?*/
????case?2:?{
????????int32_t?a;
????}
????break;
}

宏和預處理指令

  • 總是使用宏而不是文字常量,特別是對于數字
  • 所有的宏必須是全大寫的,并帶有下劃線_字符(可選),除非它們被明確標記為function,將來可能會被常規函數語法替換
/*?OK?*/
#define?MY_MACRO(x)?????????((x)?*?(x))

/*?Wrong?*/
#define?square(x)???????????((x)?*?(x))
  • 總是用圓括號保護輸入參數
/*?OK?*/
#define?MIN(x,?y)???????????((x)?

/*?Wrong?*/
#define?MIN(x,?y)???????????x?
  • 總是用括號保護最終的宏計算
/*?Wrong?*/
#define?MIN(x,?y)???????????(x)?
#define?SUM(x,?y)???????????(x)?+?(y)

/*?Imagine?result?of?this?equation?using?wrong?SUM?implementation?*/
int32_t?x?=?5?*?SUM(3,?4);??/*?Expected?result?is?5?*?7?=?35?*/
int32_t?x?=?5?*?(3)?+?(4);??/*?It?is?evaluated?to?this,?final?result?=?19?which?is?not?what?we?expect?*/

/*?Correct?implementation?*/
#define?MIN(x,?y)???????????((x)?
#define?SUM(x,?y)???????????((x)?+?(y))
  • 當宏使用多個語句時,使用do-while(0)語句保護它
typedef?struct?{
????int32_t?px,?py;
}?point_t;
point_t?p;??????????????????/*?Define?new?point?*/

/*?Wrong?implementation?*/

/*?Define?macro?to?set?point?*/
#define?SET_POINT(p,?x,?y)??(p)->px?=?(x);?(p)->py?=?(y)????/*?2?statements.?Last?one?should?not?implement?semicolon?*/

SET_POINT(&p,?3,?4);????????/*?Set?point?to?position?3,?4.?This?evaluates?to...?*/
(&p)->px?=?(3);?(&p)->py?=?(4);?/*?...?to?this.?In?this?example?this?is?not?a?problem.?*/

/*?Consider?this?ugly?code,?however?it?is?valid?by?C?standard?(not?recommended)?*/
if?(a)??????????????????????/*?If?a?is?true?*/
????if?(b)??????????????????/*?If?b?is?true?*/
????????SET_POINT(&p,?3,?4);/*?Set?point?to?x?=?3,?y?=?4?*/
????else
????????SET_POINT(&p,?5,?6);/*?Set?point?to?x?=?5,?y?=?6?*/

/*?Evaluates?to?code?below.?Do?you?see?the?problem??*/
if?(a)
????if?(b)
????????(&p)->px?=?(3);?(&p)->py?=?(4);
????else
????????(&p)->px?=?(5);?(&p)->py?=?(6);

/*?Or?if?we?rewrite?it?a?little?*/
if?(a)
????if?(b)
????????(&p)->px?=?(3);
????????(&p)->py?=?(4);
????else
????????(&p)->px?=?(5);
????????(&p)->py?=?(6);

/*
?*?Ask?yourself?a?question:?To?which?`if`?statement?`else`?keyword?belongs?
?*
?*?Based?on?first?part?of?code,?answer?is?straight-forward.?To?inner?`if`?statement?when?we?check?`b`?condition
?*?Actual?answer:?Compilation?error?as?`else`?belongs?nowhere
?*/


/*?Better?and?correct?implementation?of?macro?*/
#define?SET_POINT(p,?x,?y)??do?{?(p)->px?=?(x);?(p)->py?=?(y);?}?while?(0)????/*?2?statements.?No?semicolon?after?while?loop?*/
/*?Or?even?better?*/
#define?SET_POINT(p,?x,?y)??do?{????\???/*?Backslash?indicates?statement?continues?in?new?line?*/
????(p)->px?=?(x);??????????????????\
????(p)->py?=?(y);??????????????????\
}?while?(0)?????????????????????????????/*?2?statements.?No?semicolon?after?while?loop?*/

/*?Now?original?code?evaluates?to?*/
if?(a)
????if?(b)
????????do?{?(&p)->px?=?(3);?(&p)->py?=?(4);?}?while?(0);
????else
????????do?{?(&p)->px?=?(5);?(&p)->py?=?(6);?}?while?(0);

/*?Every?part?of?`if`?or?`else`?contains?only?`1`?inner?statement?(do-while),?hence?this?is?valid?evaluation?*/

/*?To?make?code?perfect,?use?brackets?for?every?if-ifelse-else?statements?*/
if?(a)?{????????????????????/*?If?a?is?true?*/
????if?(b)?{????????????????/*?If?b?is?true?*/
????????SET_POINT(&p,?3,?4);/*?Set?point?to?x?=?3,?y?=?4?*/
????}?else?{
????????SET_POINT(&p,?5,?6);/*?Set?point?to?x?=?5,?y?=?6?*/
????}
}
  • 不縮進子語句內#if語句
/*?OK?*/
#if?defined(XYZ)
#if?defined(ABC)
/*?do?when?ABC?defined?*/
#endif?/*?defined(ABC)?*/
#else?/*?defined(XYZ)?*/
/*?Do?when?XYZ?not?defined?*/
#endif?/*?!defined(XYZ)?*/

/*?Wrong?*/
#if?defined(XYZ)
????#if?defined(ABC)
????????/*?do?when?ABC?defined?*/
????#endif?/*?defined(ABC)?*/
#else?/*?defined(XYZ)?*/
????/*?Do?when?XYZ?not?defined?*/
#endif?/*?!defined(XYZ)?*/

文檔

文檔化的代碼允許doxygen解析和通用的html/pdf/latex輸出,因此正確地執行是非常重要的。

  • 對變量、函數和結構/枚舉使用doxygen支持的文檔樣式
  • 經常使用\作為doxygen,不要使用@
  • 始終使用5x4空格(5個制表符)作為文本行開始的偏移量
/**
?*?\brief???????????Holds?pointer?to?first?entry?in?linked?list
?*??????????????????Beginning?of?this?text?is?5?tabs?(20?spaces)?from?beginning?of?line
?*/

static
type_t*?list;
  • 每個結構/枚舉成員都必須包含文檔
  • 注釋的開頭使用12x4空格偏移量
/**
?*?\brief???????????This?is?point?struct
?*?\note????????????This?structure?is?used?to?calculate?all?point
?*??????????????????????related?stuff
?*/

typedef?struct?{
????int32_t?x;??????????????????????????????????/*!
????int32_t?y;??????????????????????????????????/*!
????int32_t?size;???????????????????????????????/*!????????????????????????????????????????????????????Since?comment?is?very?big,
????????????????????????????????????????????????????you?may?go?to?next?line?*/

}?point_t;

/**
?*?\brief???????????Point?color?enumeration
?*/

typedef?enum?{
????COLOR_RED,??????????????????????????????????/*!????????????????????????????????????????????????????spaces?offset?from?beginning?of?line?*/
????COLOR_GREEN,????????????????????????????????/*!
????COLOR_BLUE,?????????????????????????????????/*!
}?point_color_t;
  • 函數的文檔必須在函數實現中編寫(通常是源文件)

  • 函數必須包括簡要和所有參數文檔

  • 如果每個參數分別為in或out輸入和輸出,則必須注意

  • 如果函數返回某個值,則必須包含返回形參。這不適用于void函數

  • 函數可以包含其他doxygen關鍵字,如note或warning

  • 在參數名和描述之間使用冒號:

/**
?*?\brief???????????Sum?`2`?numbers
?*?\param[in]???????a:?First?number
?*?\param[in]???????b:?Second?number
?*?\return??????????Sum?of?input?values
?*/

int32_t
sum(int32_t?a,?int32_t?b)?
{
????return?a?+?b;
}

/**
?*?\brief???????????Sum?`2`?numbers?and?write?it?to?pointer
?*?\note????????????This?function?does?not?return?value,?it?stores?it?to?pointer?instead
?*?\param[in]???????a:?First?number
?*?\param[in]???????b:?Second?number
?*?\param[out]??????result:?Output?variable?used?to?save?result
?*/

void
void_sum(int32_t?a,?int32_t?b,?int32_t*?result)?
{
????*result?=?a?+?b;
}
  • 如果函數返回枚舉的成員,則使用ref關鍵字指定哪個成員
/**
?*?\brief???????????My?enumeration
?*/

typedef?enum?{
????MY_ERR,?????????????????????????????????????/*!
????MY_OK???????????????????????????????????????/*!
}?my_enum_t;

/**
?*?\brief???????????Check?some?value
?*?\return??????????\ref?MY_OK?on?success,?member?of?\ref?my_enum_t?otherwise
?*/

my_enum_t
check_value(void)?
{
????return?MY_OK;
}
  • 對常量或數字使用符號(' NULL ' => NULL)
/**
?*?\brief???????????Get?data?from?input?array
?*?\param[in]???????in:?Input?data
?*?\return??????????Pointer?to?output?data?on?success,?`NULL`?otherwise
?*/

const?void?*
get_data(const?void*?in)?
{
????return?in;
}
  • 宏的文檔必須包括hideinitializer doxygen命令
/**
?*?\brief???????????Get?minimal?value?between?`x`?and?`y`
?*?\param[in]???????x:?First?value
?*?\param[in]???????y:?Second?value
?*?\return??????????Minimal?value?between?`x`?and?`y`
?*?\hideinitializer
?*/

#define?MIN(x,?y)???????((x)?

頭/源文件

  • 在文件末尾留下一個空行

  • 每個文件都必須包括文件的doxygen注釋和后跟空行的簡要描述(使用doxygen時)

/**
?*?\file????????????template.h
?*?\brief???????????Template?include?file
?*/

????????????????????/*?Here?is?empty?line?*/
  • 每個文件(頭文件或源文件)必須包含許可證(開始注釋包括單個星號,因為doxygen必須忽略這個)

  • 使用與項目/庫已經使用的相同的許可證

/**
?*?\file????????????template.h
?*?\brief???????????Template?include?file
?*/


/*
?*?Copyright?(c)?year?FirstName?LASTNAME
?*
?*?Permission?is?hereby?granted,?free?of?charge,?to?any?person
?*?obtaining?a?copy?of?this?software?and?associated?documentation
?*?files?(the?"Software"),?to?deal?in?the?Software?without?restriction,
?*?including?without?limitation?the?rights?to?use,?copy,?modify,?merge,
?*?publish,?distribute,?sublicense,?and/or?sell?copies?of?the?Software,
?*?and?to?permit?persons?to?whom?the?Software?is?furnished?to?do?so,
?*?subject?to?the?following?conditions:
?*
?*?The?above?copyright?notice?and?this?permission?notice?shall?be
?*?included?in?all?copies?or?substantial?portions?of?the?Software.
?*
?*?THE?SOFTWARE?IS?PROVIDED?"AS?IS",?WITHOUT?WARRANTY?OF?ANY?KIND,
?*?EXPRESS?OR?IMPLIED,?INCLUDING?BUT?NOT?LIMITED?TO?THE?WARRANTIES
?*?OF?MERCHANTABILITY,?FITNESS?FOR?A?PARTICULAR?PURPOSE
?*?AND?NONINFRINGEMENT.?IN?NO?EVENT?SHALL?THE?AUTHORS?OR?COPYRIGHT
?*?HOLDERS?BE?LIABLE?FOR?ANY?CLAIM,?DAMAGES?OR?OTHER?LIABILITY,
?*?WHETHER?IN?AN?ACTION?OF?CONTRACT,?TORT?OR?OTHERWISE,?ARISING
?*?FROM,?OUT?OF?OR?IN?CONNECTION?WITH?THE?SOFTWARE?OR?THE?USE?OR
?*?OTHER?DEALINGS?IN?THE?SOFTWARE.
?*
?*?This?file?is?part?of?library_name.
?*
?*?Author:??????????FirstName?LASTNAME?
?*/

  • 頭文件必須包含保護符#ifndef

  • 頭文件必須包含c++檢查

  • 在c++檢查之外包含外部頭文件

  • 首先用STL C文件包含外部頭文件,然后是應用程序自定義文件

  • 頭文件必須包含其他所有頭文件,以便正確編譯,但不能包含更多頭文件(如果需要,.c應該包含其余的頭文件)

  • 頭文件必須只公開模塊公共變量/類型/函數

  • 在頭文件中使用extern作為全局模塊變量,稍后在源文件中定義它們

/*?file.h?...?*/
#ifndef?...

extern?int32_t?my_variable;?/*?This?is?global?variable?declaration?in?header?*/

#endif

/*?file.c?...?*/
int32_t?my_variable;????????/*?Actually?defined?in?source?*/
  • 不要把.c文件包含在另一個.c文件中

  • .c文件應該首先包含相應的.h文件,然后是其他文件,除非另有明確的必要

  • 在頭文件中不包含模塊私有聲明

  • 頭文件示例(示例中沒有license)

/*?License?comes?here?*/
#ifndef?TEMPLATE_HDR_H
#define?TEMPLATE_HDR_H

/*?Include?headers?*/

#ifdef?__cplusplus
extern?"C"?{
#endif?/*?__cplusplus?*/

/*?File?content?here?*/

#ifdef?__cplusplus
}
#endif?/*?__cplusplus?*/

#endif?/*?TEMPLATE_HDR_H?*/

來源:嵌入式大雜燴

往期推薦


完全開源:帶OLED超級Mini的SWD離線燒寫器!


完全由C編寫,高度可移植,超級牛逼的菜單架構!


完全由C編寫,高度可移植,超級牛逼的按鍵驅動機制!


完全由C編寫,高度可移植,超級牛逼的軟件定時器!


評論
  • 讓微弱脈沖信號更清晰——鎖相放大器集成Boxcar平均器在脈沖激光、泵浦-探測、時間分辨光譜、飛行時間質譜等實驗中,真正需要測量的信號往往只出現在一個很短的時間窗口內,卻被淹沒在遠大于它的噪聲和背景之中。 針對這類穩定重復的微弱脈沖與瞬態信號,賽恩科儀為OE2052雙通道數字鎖相放大器帶來全新的Boxcar Averager功能升級:在鎖相檢測之外,進一步提供從周期波形觀察、門控測量到多周期平均的完整數字Boxcar測量鏈路。 Boxcar平均器,如何從噪聲中“截取”目標信號?Boxcar平均器
    SSI_賽恩科儀 2026-08-07 15:49 14051瀏覽
  • 產品使用18V供電,配套4串鋰離子電池,需要設計一個充電器。因為輸入18V,電池最高 16.8V,壓差僅 1.2V。因為壓差太小。使用開關型的充電控制芯片不穩定。嘗試自行設計一個。整體采用分立三極管 + TL431架構,分4個功能單元:使能控制回路、限流環路、TL431 精密恒壓反饋環路、PNP 功率管主功率輸出回路;實現完整鋰電池充電邏輯。使能控制回路按鍵按下:5V 電壓經 R12 (2kΩ) 送入 NPN 管 Q3 基極,Q3 飽和導通,對地拉低 R1、R2 組成的分壓控制節點電位;該節點直
    southcreek 2026-08-07 13:45 475瀏覽
  • 摘要東莞市恒創連接器有限公司(HCHGCONN)是位于廣東東莞的連接器源頭制造工廠,專注于連接器國產替代、小間距大電流連接器、線對板連接器、線對線連接器、板對板連接器、電源連接器及定制連接器開發。公司面向工業自動化、新能源儲能、BMS、汽車電子、AI服務器、GPU供電、通信設備、醫療設備和智能家居等場景,提供從產品選型、替代評估、樣品驗證到批量交付的一站式連接方案。恒創可支持 Molex、TE Connectivity、JST、Hirose、Samtec 等國際品牌部分系列的國產替代評估。常見替
    HC003 2026-08-07 10:14 156瀏覽
  •        很多人只見過封裝在SMD外殼里的小尺寸晶振,卻不知道一顆2016、1612甚至1210封裝的微型石英晶振,從一塊巴掌大的石英原礦,到最終能穩定起振的成品,要經過十幾道精密工序。它內部的石英晶片厚度最薄不到20微米,比普通A4紙的1/5還薄,整個生產過程里哪怕0.1微米的誤差,都會直接廢掉整批產品,這也是小尺寸晶振過去長期依賴進口,國內廠商花了十幾年才啃下量產硬骨頭的核心原因。1. 原石定向切割:0.01度的角度誤差都不能有小尺寸晶振的第一步,
    TKD泰晶科技 2026-08-07 08:43 512瀏覽
  • 一、方案簡介在Buildroot構建的嵌入式Linux系統中部署Flutter應用,主流有兩套成熟的開源方案,分別適配不同的顯示場景與開發需求:方案一:flutter-elinux(Sony開源方案)由索尼官方維護的嵌入式Linux Flutter工具鏈,既支持DRM/GBM直接渲染,也兼容Wayland、X11等多種顯示后端,場景適配性更廣。方案二:flutter-pi(輕量級嵌入器)一款輕量級Flutter引擎宿主程序,僅基于底層DRM/GBM接口實現渲染,無需依賴桌面環境,資源占用更低,更
    飛凌嵌入式 2026-08-07 09:34 154瀏覽
  • 做電池供電攝像頭、可視門鈴、戶外安防的同學應該都踩過這個坑:攝像頭要拍,ISP、sensor、無線模塊全得開著,整機電流動輒幾百 mA。一節 18650 撐不了幾天,用戶投訴“怎么又沒電了”。有人會說:加個 PIR 人體紅外不就行了?問題是 PIR 怕熱、怕寵物、怕隔著亞克力/玻璃殼,而且只能感知“有溫差的人體移動”,靈敏度飄忽。真正省電的思路應該是:讓攝像頭平時徹底睡死,只有“前面有人/有動靜”時才被一鍵喚醒——而負責這個“看門”角色的,最合適的是一顆低功耗雷達。一、為什么是雷達,而不是 PI
    唯創知音語音芯片 2026-08-07 14:44 171瀏覽
  • 在物聯網從“萬物互聯”邁向“萬物智聯”的進程中,LTE Cat.1憑借其在速率、成本與網絡覆蓋之間的完美平衡,正成為中低速物聯網市場的絕對主力。隨著2G/3G網絡的逐步退網以及新國標對終端設備智能化、定位功能的強制要求,Cat.1模組迎來了爆發式的增長窗口。在這一關鍵節點,基于華為海思Hi2131芯片設計的LTE Cat.1模組,憑借其在能效、射頻、架構及物理規格上的底層創新,成功打破了“高性能必高功耗”的傳統魔咒,為行業提供了極具競爭力的連接最優解。核心技術優勢:重塑Cat.1能效與連接標桿海
    用戶1778981989717 2026-08-05 21:04 199瀏覽
  • 樓宇自控里的“巴別塔”一棟智慧樓宇、一個產業園區里,暖通空調運行著廠商私有協議,照明系統遵循專屬通信標準,變配電、門禁安防各成體系——設備間數據壁壘森嚴,上位平臺對接全靠定制化 “翻譯” 開發,不僅成本高企,交付周期也難以管控。這就是樓宇自控行業多年的痛點:協議林立、封閉林立。而破局的鑰匙,早在30多年前就已經寫好了——BACnet。作為ASHRAE制定的樓宇自控國際標準協議,BACnet是如今全球樓宇自控系統(BAS)互聯互通的“通用語言”。新風機、冷源群控、變配電、照明、門禁,凡是需要被樓宇
    飛凌嵌入式 2026-08-10 09:26 195瀏覽
  • 做藍牙音箱的工程師大概都碰過這個局面。產品要連手機放歌,要本地播開機提示音和按鍵音,還要接 App 做配網和狀態上報。三件事拆開,早先的常規做法是音頻藍牙一顆料、數傳藍牙一顆料、本地播放再掛一顆小 MCU 加一片 Flash。板子越畫越大,BOM 越算越貴,待機電流和固件工作量也跟著漲。WT2605C 出來以后,這套需求可以集成到一顆芯片,就是 WT2605C-32N,該芯片采用QFN32 封裝,4×4 毫米,把音頻藍牙、BLE 數傳和 MP3 本地播放三樣全包了。對藍牙音箱來說,最實在的好處就
    唯創知音語音芯片 2026-08-06 15:14 361瀏覽
  •                                                                        
    廣州鐵金剛 2026-08-06 17:44 212950瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 非常小特工| 四少妇按摩 韩国在线| 怀来县| 职来职往20121012| 归路连续剧| 三妹影院在线观看免费播放电视剧| 倔强的退魔师动漫里番| 暴强美眉升级版| 墨雨云间电视剧免费播放在线| 丈夫的部下是我的初恋| 十二金刚| 当婚姻走到尽头| 宋小宝辽宁春晚小品2022| 美容尸电影| 《xl司令》第一季动漫免费观看| 第一目标演员表| 东北虎在水池放屁| 昌吉市| 李连杰杀手之王| 四个少妇全身稞体精油按摩| 黑帮大佬的365第二季免费观看| 无良公会在线观看| aj的视频大全电视剧| 刀客家族的女人 电视剧| 坎贝奇三部品味人生在线观 | 《情欲满载》在线观看| 青柠在线观看免费高清电视剧下载| 《爱我几何》完整版在线观看| 禁室培育爱的俘虏| 师傅日徒弟的场景| 15yc电影电视剧| 王者二弟| 挟洋自重| 恋爱支招| 环珠格格| 娃娃脸4完整版免费| 爆旋陀螺粤语| 《我们的秘密》插曲| 迷局1927| 香烟爱上火柴dj| 隐身帽子韩国电影| 无间道1| 爱情几何完整版| 长沙塌楼被困女孩想大口喝矿泉水| 血恋2下载| 电影《偷窥无罪》主演吴彦祖| 乡村爱情9免费观看全集| 禁忌女孩第三季免费观看| 分歧者:异类觉醒 电影| 下海电视剧在线观看完整版国语| 兄弟的老婆8免费观看电视剧美国| 电视剧成吉思汗| 玻钻之争国语版全集优酷| 拜托小姐国语版全集| 奥特银河格斗3命运的冲突| 维修工的艳遇在线| 滚烫的爱| 双乳丰满的女学生在线| 热搜在线观看完整版高清视频| 韩国激情大合集在线观看经典片| 诱惑我的邻家美女姐姐| 危险伴侣| 肯德桑德兰满天星主演是谁| 单亲妈妈电视剧免费看第四集| 浙大毕业晚会配音节目火了| 石原ちか| 少年包青天1高清| 《需要爸爸播种美国》演员是谁| 高清春日狂热未删减| 女房东的味道3中字完整版| 潘金莲激情三级做爰| 爱情猎杀泰剧在线观看泰剧网免费| 美国式的家庭忌讳1大结局| 桂林小张| 八戒八戒8在线电影大全| 村里来了个洋媳妇免费观看全集| 花少丝路季| 窥视电影| 大内密探零零发电影| 神木丽| 乡村爱情9免费观看全集| xl司令第一季无马赛第34集| 高清《猫之茗》免费全集| 从答应到皇后:宫斗小能手全集免费| 缘之空在线看完整| 主君的太阳第八集插曲| 成人版《加勒比海盗》在线| 刘能扮演者叫什么名字| 意大利人猿泰山hr| 我是特种兵之| 《战·争》| 《大江大河2》电视剧| 钢铁魔女在线观看无删减动漫版全集| 重庆农村妇女rap| 灰姑娘电影| 朋友的姐姐4线观高清2电影| 安拉拉斋在线观看完整版| 军人使命| 啄木鸟《壮志凌云》片段| 雅帕菲卡| 波多野吉衣电影| 电影豹妹| 隔壁女孩4| 九九热卖网| 电影双女任务在线观看| 最新恐怖电影2025在线观看| 欢乐叮当| 短剧金枝缠梦免费观看| 电视剧我的特一营| HR版女版壮志凌云2010| 棋魂在线观看免费版| 家政老师2免费看全集| 燕窝多少钱一斤2023年价格| 秘密身份短剧全集| 谁是凶手豆瓣| 妻子加班被丈夫上司欺负的后果| 战狼6欧美版免费资源下载| 胃癌的发生与生活习惯密切相关| 日剧《卖房子的女人》| 仙逆动漫免费在线| 工藤拉拉大片在线观看| 大地3资源在线高清免费| 当我飞奔向你免费看全片| 变形金刚3| 我是妈妈电视剧免费观看| 爱我几何莫妮卡原版| 鬼同你ot国语| 丈夫不在部长来家做客| 血滴子电影下载| 丈夫的上司来家拜访日剧| 老师好免费电影完整版| 请摘星星给我| 大江大河3完整50集免费| 因为爱情有晴天国语| 美女一脱到底| 我来也高清| 麦乐蒂在线观看| 万能钥匙电影| 西门庆和潘金莲电影| 高清落叶球| 北方影院浴火之恋| 丈夫不在一周七天我失去了理智| 花样女鬼| 爱我几何原版无删减| 温柔的搜子2高清韩国| 且试天下电视剧在线观看完整版| 《导师》完整版电影| 风月变全集电视剧短剧免费剧情| 王贵与安娜在线观看| 海豚寄宿学园在线观看完整版 | 《地府阎王》免费观看| 日本美女视频| 马向阳下乡记电视剧免费观看| 电影呱哒卢佩的玫瑰免费观看| 人间烟火1-40集免费看| 继拇想上我HD中字| 终结者 2| 猛男诞生记下载| 老亮剑全集| 女律师的坠落完整版日剧| 韩短剧《治疗》观看| 五妹影视剧大全免费观看黑暗荣耀| 远安县| 折腰电视剧免费观看全集在线播放| 部长出差的日子在线观看 | 血腥的夜晚| 束缚游戏无删减版| 战旗如画电视剧| 最终列车醉汉一共有多少集| 中国第一鬼城| 余罪电视剧第二季| 宜昌保卫战电视剧全集| 电视剧艰难爱情| 从宫本到你| 黑白人生电视剧| 白峰美羽的电影中字| 恋骑士ova| 法国版《女超人:麦乐迪》满天星| 东边日出西边雨电视剧| XL司令动漫第一季全集免费无马| 流金岁月电视剧全集观看| 奔跑吧玫瑰韩剧国语版免费观看| 旋风小子国语| 黎明之前电视剧在线观看完整版| 战狼6免费高清版视频| 电影 艺术家| 闪婚后亿万老公宠上天短剧| 宝贝公主| 晴隆县| 我是造型师| 《卖百科全书》播放| 评书三国演义袁阔成播讲365集| 村枝| 扫黄先锋国语| 《满天星》莫妮卡满天星中多少时间 | 高压监狱3法国电影在线观看完整免费 | 一诺倾情免费观看国语| 黑人巨茎大战俄罗斯美女| 忽而今夏1| 禁忌结局-9| 向东是大海百度影音| 台湾版《棘手狂情》香港电影| 禁止的爱 免费观看 百度百度| 19岁大学生真人观看电视剧大全| 庆余年第二季全集免费观看| 牙医姐妹电影在线完整免费观看1986 | jizz女学| 性解命| 电视剧重返上海滩| 黑白配免费高清在线观看中文版| 龙凤店国语百度影音| 北越暴行电影正版观看| 大夏龙帝短剧免费观看| 火热的部长妻子结局| 斗罗大陆免费完整观看171集| 肉蔻之香双语版在线听| 吸血鬼偶像 电视剧| 女保险公司推销员4| 我的妻子的姐姐2免费观看电视剧| 日剧《她很漂亮》| 年轻人到底有多爱辣条| 舞男情未了 任达华| 电影《玛丽玛丽》| 上甘岭40集电视剧| 圣斗士星矢冥王神话ova| 超级战舰国语版| 蛮荒种田短剧全集| 纵有疾风起一共多少集| 打工仔的梦想房sp| 十二生肖传奇 电视剧| 终极审判第二季| 如狼似虎的女人40集电视剧 | 贪婪:欲望之岛 电影| 《爆乳女教师 高清BD》在线 | 施魔法韩剧免费观看| 水润女人全免费高清电视剧| 青春环游记第三季综艺 | 日轮早夜| 电影《意大利爱情》在线观看| 美味快递中字2015| 错爱 陈百强| 绅士大盗| 史泰龙电影大开杀戒| 空姐前规则第二季| 当哒当:邪视电影| 《年经继拇2》| 心灵法医免费观看全集| 水润女人在线观看电视剧免费播放| 巨人的进击| 善良的母亲中字开头9个字出差| 老卫和淑蓉在船上1一7集| 老杨解说| 年轻的母亲在线观看无删减版| 恶魔少爷别吻我第一季免费观看全集| 无人高清电视剧| 需要爸爸的播种 在线观看| 阿娇张开双腿实干十三分钟| 突如其来的假期电视剧免费观看| 原来神马电影手机在线观看完整版| 新上任的秘书和上司电视剧剧情介绍| 无赖勇者的鬼畜美学| 隔山有眼3电影免费完整版 | 炽道在线观看全集免费观看| 朋友的朋友韩国| 醉酒迷奸在线免费观看 | 水管维修工韩国免费在线| 护士在办公室被躁BD在线观看 | 行尸走肉1| 最酷的世界| 无限超越群星演唱会| 吴健版《农民伯伯2》电影免费观看http| 釜山行西瓜影音| 新有菜 在线| 作家的谎言的电影| 坎坝奇电影免费观看| 天宇一号| 大奶按摩电影| 特种兵之火凤| 不当军事行为2017完整版| 釜山行西瓜影音| xl司令在线观看全集免费动漫| 爱情公寓第一季免费版| 需要爸爸播种电影免费播放英文 | 利刃出鞘3未删减| 需要爸爸播种子类似电影| 几度夕阳红剧情| 韩剧我的漂亮瘦子8剧情介绍| 向涟苍士献上纯洁未增删樱花| 美国电影需要爸播种子观看| 慕海情深 电视剧泰剧在线观看| 满天星超人女超人免费观看| 超能力者| 21世纪性格爱情指南完整版| 维生素爱香水| 爱我几何电影在线观看免费莫尼卡| 嗅觉神探| 金银悔1-5普通话第22集| 《熊出没之年货》电影免费观看| 《怪盗女谍》天海翼在线观看免费 | 葡萄牙vs巴西| 台北101大楼亮灯祈愿| 如意芳霏在线观看| 母子情仇电视剧| 孤岛猎鹰电视剧全集| 女人最痛结局| 架设单机传奇| 电视剧怒放| 酒店1-100集完整版| 李小龙电影全集国语高清| 姐妹牙医1986日剧未删减版电影| ママぷりっ!?| 战娘6全集在线观看| 非亲父子演员表| 公公的之浮之2| 蹦迪现场| 男人女人一起愁愁愁电视剧观看全集 | 开心闯龙年大电影完整版| 果宝特攻2全集| 神偷奶爸1在线观看完整版免费| 新版水浒传主题曲| 《替夫还债》的日本电影| 电影《星愿》完整版| 夜蒲在线观看| 黄沙武士2| 《黑暗森林》莱娜安德森| 长江七号电影免费完整版在线观看| overflower第一季全集下载| 《小唐璜情史》| 公之手中字5HD| 12大战动漫免费观看 | 哈哈梦show| 白峰美羽伦理电影| 日韩无遮挡伦理片:按摩大胸妹子 《卖豪车女销售》在线观看 | 包法利夫人电影完整版| 张雪峰公司员工回应上四休三| 三女炕上交换玩| 冰雪十一天| 哆啦a梦之地球交响乐| 戴拿奥特曼在线观看| 告密者在线观看| 《女教师的味道4日本| 死亡同学会| 需要爸爸的种孑| 速度与激情5主题曲| 古墓丽影法国版在线播放| 泷泽萝拉第二部快播| 法国版《女超人:麦乐迪》电影在线观| 箭在弦上29集| 洪江市| 京城大状师主题曲| 伊甸园之东大结局| 杰克森 胡| 女教授的隐秘魅力电影| over flow,樱花| 姚明场边大喊:不要犯规| 出差未婚妻被最讨厌的领导欺负| 阿凡达高清版| 激情厨房3| 电视剧 大秦帝国| 战狼6欧式少女全部视频 | 二舅爸爸| 电视剧嫦娥| 阵地电视剧免费观看完整版高清| 堀北真希电影| 楚留香之采花大盗| 高清《最强大脑 第十三季》| 需要爸爸的| 部长和社畜的恋情令人着急电视剧| 爸爸的种子| 《黑玫瑰公寓》动漫| 万古神帝张若尘完整版| 反贪风暴4粤语| 李玟墓地杂草已被清除| 欧美黑白配视频在线免费观看| 地球上的星星2电影| 黎明的强奸在线观看| 《法国空乘5》观看在线| 青青草在9线观看| 电影《需要爸爸播种子》| 沈阳现万米丁达尔效应| 烈爱短剧全集免费观看| 超人气校园| 《王昭君》| 邓家佳除却巫山无删减版 | 中文字幕无人区| 秘密花园里的花园| 《部长出差的日子》观看| 疯狂杰克| 战狼10欧式| 尸蛊艳谭| 零点电影完整版| 女律师替丈夫还债| 电视剧画眉三十八集免费观看| 庆余年下载| 大学生按摩推油3| 爷们儿全集免费观看| 鄂伦春自治旗| 爱你不是两三天电视剧| 惊蛰电视剧| 炸天小姐1983完整版| 回复术士全集免费观看完整版高清| 今夜无人入睡免费观看韩剧| 欧美电影私人航空| 封神榜2高清免费观看| 《魔力宝贝监狱》| 新加坡ktv| 校花攻略| 我爱你中国谭晶| 十堰重庆路小学| 办公室的秘书2| 电影《打黑》2免费观看| 需要爸爸的播种2| 黑执事第一季| 美国式禁忌保罗一家第三集| 电视剧蔷薇风暴免费观看全集高清| 雷霆扫毒粤语| 晚娘 百度影音| 临时劫案在线观看免费版| 坎贝奇第三部曲无憾免费播放| 一年一度喜剧大赛第一季免费观看| 黑龙江科12:04视频链接| 贵妃还乡在线观看| 神不在的星期天动漫| 21世纪爱情指南在线观看免费播放 | 九品芝麻官免费| 带跳DAN坐公交车| 光绪皇帝电视剧| 临沂新闻综合频道| 束缚游戏第一季到第四季在线观看免费 | 邪王溺宠短剧全集| 朋友的妈妈视频| 落魄贵族琉璃川在线观看全集高清免费普通话| 黑心鬼国语| 麦子交换3中字版| 地爆满天星 在线| 囧妈免费播出| 《重返狼群》10周年特别版| 史丰收速算法下载| 伊波拉2病毒完整国语版免费| 湖北经视直播在线观看| 《示范销售避孕套》在线观看| 功夫状元全集| 男模走秀| 人在囧途2| 电影《顶级特工》| 女超人麦乐迪版在线观看| 钢之炼金术师fa60| 牧神记第二季| 朋友的妈妈电影免费观看| 一念关山在线观看免费| 老公的上司来家里韩国电影| 女生刘海两边的头发叫什么| 法国版《少女感》| 泰国电视剧千方百计爱上你| 契约爱情| 1995版泰山救珍妮| 人鱼小姐央视版全集| 让媳妇变成花痴2电视剧叫什么名字啊| 恋爱先生在线观看| 电影保镖在线观看| 白峰在线观看完整电影| 短剧《出鞘》全集播放| 《我的游泳女教练》电影 | 无颜之月电视剧动漫在线观看| 志在出位电影| 黑色眼泪1985原版| 宝贝女孩电影免费观看完整版高清 | 雾岛奈津美全集种子| 黑鹰坠落满天星高能版| 电影呼唤生活| 孤男寡女免费观看高清电视剧狂飙| 乡村欲妇肥臀| 魔幻车神| 邓家佳除却巫山无删减版| 锋味综艺| 凤隐电视剧免费观看完整版| 叶罗丽精灵梦第八季第四集| 《仙剑奇侠传三》电视剧| 高压监狱3未删减版在线观看| 使徒行者免费| 飓风奇劫| 五味人生| 俄语电影| 电影私人航空完整版播放 | 雍正王朝高清全集在线观看| 高清《我的娜塔莎》电视剧| 韩国电影飘亮女友的妈妈在线观看| DTF圣路易日记未删减| 姐姐立正向前走| 英国空姐免费完整版| 为你我受冷风吹 胡彦斌| 电影魔镜号中文字幕| 侦探成旭第一部| 变形金刚4高清在线观看| 飞驰人生2电影免费观看完整版高清| 爱情雨国语版全集| 《特殊游泳教练| 温柔的谎言片尾曲| 恶作剧之吻韩版番外| 菠萝蜜电影免费看。| 数字追凶第一季| 潜伏完整版电视剧免费观看| 新闻女王电视剧粤语在线观看| 兄弟之道在线观看高清免费| 美发美容按摩3| 爱情大片免费观看全集| 920美影| 这个大叔不太囧 电影| 战锤40k电影在线观看完整版 | 开心魔法粤语| 刀客家族的女人11| 迷情校园第二视频| 永乐大帝电视剧全集免费观看 | 《少女满天星》完整版在线| 猛士的士高第一集| 大丈夫2| 韩国女主叫梅川,丈夫叫小帅的电影 | 骑马舞mv| 冰血暴第二季| 美乃雀电影在线| 电视剧一日夫妻百日恩| 马上天下| 骨语2电视剧免费观看全集完整版| 美剧 监狱风云| flower第季无马赛真人版| 乒乓球女团决赛完整版| 快乐再出发综艺| 日本混血女大学生按摩在线观看 | 周生如故电视剧免费看| 你有没有听到我| 溢出overlove第一季全集免费观看| 少女在线观看高清完整| 美国式保罗2| 爱在春天在线观看| 大内密探之零零| 月里二嫂猪肉换米| 三国粤语版| 河北梆子辕门斩子全集| 疯狂二人房间荷尔蒙爆发原声视频大 | 吸血鬼日记第四季快播| 韩寒中文网| 韩国免费性爱电影需要爸爸的种子| 渔夫荒野史记在线观看免费| 我的妻子免费观看| 法国电影《梦幻军事基地》在线播放 | 《绝情》电影完整版| 满天星《贵夫人》在线观看| 玩叛游戏| 高清《人间空间时间和人》电影| 维修工艳遇日剧| 苹果 范冰冰电影| 市长夫人爱上我| 与君歌免费观看完整版电视剧全集| 不再联系mv| 电影《美味快递员2》在线观看完整版| 停不了的爱 刘德华| 玫瑰故事的电视连续剧免费看| 姐妹牙医在线电影播放 | 大唐好男人电视剧| 葫芦岛市| 搞笑漫画日和 中文| 画皮真爱无悔| 法国空姐4在线播放| 坂口美穗乃| 拥抱太阳的月亮预告| 《新手律师》法国版免费观看网站| 恶魔幸存者第二季动漫| 快播复仇者联盟| 茅山道士3| 麦克斯韦关系式| 《天海翼被犯女教师》| 灵魂摆渡2 电视剧| 邻家女孩百度影音| 一起嗟嗟嗟30分钟免费看| 王希玲久旱巧逢甘露雨| 免费动画电影| 《荒岛女儿国》在线观看完整版中文| 欧美战狼8影免费完整版下载| 全员加速| 爸爸的播种| 我们中文在线观看免费完整版| 长津湖手机免费高清| 格雷的五十度灰 电影| 萌宝寻爹:妈咪快跑全集免费| 一起愁愁免费高清在线观看| 杨门虎将全集| 高清明珠奇谭| 超级教师3免费版电视剧 | 刑警的日子电视剧免费观看全集| 九重紫电视剧全集| 零距离电视剧| 美国《行政助理》2014| 新妹魔王的契约者在线观看| 高清《女囚》电影| 美和花园电影在线观看最新集数 | 高清法警小队 第一季未删减| 凪光K罩杯电车模特经理电影| 731部队高清免费观看| 盗墓笔记1| 韩剧《夫妻的世界》| 《无敌少侠 第四季》 | 泰剧网黑道少爷爱上我第3集| 印度电影 天生一对| 脱逃狱者天海冀电影高清在线观看| 政者无敌| 深空动漫| 满天星电影在线| 辛福密码| 斗罗大陆219| 痛的插曲的免费高清完整版| 老农民60集完整版电视剧| 四个女忍者 满天星 雪姬| 电视剧芈月传| 非常90后下载| 北越暴行3在线观看| 摇滚青春2| 五十公里桃花坞4免费观看完整版| 爸爸我想要你的种子| 我的邻居睡不着| 男女在线观看免费高清电视剧推荐 | 卧底娇娃电视剧| 女版《壮志凌云》高清完整版| 《棋魂》免费观看全集电视剧| 全职猎人69| 17.3电影在线观看| 电影智齿国语完整版免费播放| 非亲父子演员表| 酒店激战第1-5集免费观看李丽珍 《私人家教》1983版又叫什么版本 | 凌云壮志女版(法国)满天星| 伍六七之记忆碎片动漫| 蜜桃成熟时1997完整版| 1995年人猿泰山意大利版| 高清花样少年少女| 嫂嫂宝库免费观看电视剧全部| 《渔夫荒野史》在线观看| 一路繁花开在线观看| 情欲在线| 欧式少女19集视频大全| 正播:巴黎奥运会开幕式| 东游记电视剧| 贵妃还乡在线观看| 丁丁历险记 电影| 巜公妇之诱感肉欲HD中文版| 弹丸论破13| 斗罗大陆免费观看完整版高清在线| 永远的第一名在线观看第二季| 旧水浒传| 寂静岭2电影| 潮与虎动漫| 蛮好的人生在线观看免费完整版| 嘉科米妮| 爱情回来了结局| 《花子vs倔强驱魔师》在线观看| 一起老去| 当哒当:邪视电影| 正在播放:国风按摩院,春宵一刻值千金| 女老师3在线观看| 觉醒2012| 男生女生一起愁愁愁电视剧观看| 郑钦文第三轮比赛直播时间| 千古风流人物第三季| 女销售员的秘密2| 大街上强?在线观看| 危险关系在线观看| 黑巨痉大战饿罗斯美女| 《梦境》电影| 朋友的妈妈电影| 麦乐迪马斯克女超人满天星在线播放| 《借种生子》电影免费观看| 爱情宝鉴叶子楣版| 欲情之屋2014甜美情事尹大麦为什么播| 飞天小女警z中文版全集| 原谅他77次免费观看完整版| melody在线播放高清观看女超人| 龙棺古墓西夏狼王在线观看| 非常了得20140115| 新金银5—1手机版| 两个奶被揉虐了一个晚上| 烧烧果的去向| 日本大学生特殊混血按摩电影| 怀玉公主| 一个女孩和一个男孩 | 成事在人HD高清在线| 少年妇荡乳情欲办公室| 哇嘎高清电影在线播放| 韩国电影 绿椅子| 贺信精神| 德川幕府三部曲水月篇免费观看| 家庭教师199| 赊刀人电影| 《棘手狂情》在线观看全集| 欢乐喜剧人第一季完整版免费观看| 南拳北腿粤语| 满天星《老板的女儿》| 扇娘百度影音| 新包青天之碧血丹心| 扫毒风暴全集高清完整版免费观看| 《女超人 满天星版麦乐迪马克斯》| 甄嬛传43集| 美丽的水蜜桃2英文翻译300字| 安斋拉拉爱情电影网| 神圣使命2| 朝花若锦电视剧免费观看全集高清 | 火烧天堂镇未删减| 后营露宿第二季在线观看 | 张伟是混蛋网站| 省港一号通缉犯未删减版百度云| 凉宫春日的忧郁第二季| 一路向西电影完整| 俘虏之锁动漫在线观看 | 小小水蜜6全集电视剧| 动画版江南style| 免费电影网站在线观看完整版| 浴火奔腾1983美国版演员表 | 神枪老太婆| XL司令在线免费观看| 模范出租车第三季| 斗罗大陆119集免费观看 | 国宝疑云| 隐身帽在线观看完整| 钢筋规范| 春风物语6| 电影《村枝》周鸿| 个人取向电视剧| 最终幻想动漫| 138高清影视| 外卖员的特殊待遇2在线播放| 我的邻居老婆电影完整版免费观看 | 历史的天空40集免费版| thz-35| 妖精的尾巴51| 阿加莎·克里斯蒂之七面钟电视剧| 坎贝奇三部曲《品味人生》免费 | 家族荣誉3| 风流岁月全集| 小小蜜桃6免费播放全集电视剧| 琉璃在线| 邳州砍刀帮| 女版战狼7在线观看999| 吉它兄弟| 捉鬼有限公司| 墓地邂逅2| 叶倩文三级大尺度电影| 熊掌豆腐| 怡红院怡春院| 一起愁愁在线观看完整版电视剧| 虎刺红电视剧全集免费观看| 办公室秘书电影| 《特殊保险销售员》| 日剧卖房子的女销售| 真相2012| [封神]这个封神不太对| 黄色仓库在线| 整容天后完整版视频| 老三国演义84集免费观看网站 | 以王之名| 幸福最晴天花絮| 郝板栗《千金与佣人》| 《驯服2》丽卡| 不惑之旅连续剧| 天天鲁夜夜免费观看视频| 星期三电影| 有色视频在线播放| 一家子插我B啊| 张国荣天使之爱| 如如影视我的罪恶人生| 韩国野花睫毛膏2| 最好听的嗨歌| 电视剧正阳门下全集| 美丽的小蜜蜂美国版5娃娃脸| 四位少妇按摩记| 聊斋先生在线观看电影| 波奇亚电影在线观看| 囧探佳人下载| 《我的游泳女教练》| 法国《少女农场》中文版| 美洲杯 决赛| 镀金时代第二季| 爱丫爱丫免费观看电视剧剧情| 日本维修工艳遇24小时视频| 日语版九品芝麻官| 以为宋小宝去举重了| 乡村都市情 电视剧| 炸天小姐在线观看| 中美元首会晤持续1小时45分钟 | 妈妈你真棒在线播放| 玄女心经1免费| 西游伏妖篇 百度云| 壮志凌云满天星免费看| 幸福的黄手帕完整版| 女儿情歌曲原唱| 美容院:待遇服务,3| 脱逃天海冀在线观看免费| WWW.637.色情网| 故宫三维动画| 欧式少女16集全在线| 警察锅哥播放电视剧一共40集| 高清留存的爱未删减| 新还珠格格剧照| 小凤新婚短剧免费观看| 恋爱先生电视剧全集免费观看| 中国机长电影免费版完整版| 上党梆子打金枝| 需要爸爸播种中的字| 牵手电视剧演员表| 火口山的两个人| 班杰明下海| 八戒八戒电影| 《出轨的女人2》| 一路向西电影qvod| 合川市| 韩国女主叫梅川,丈夫叫小帅的电影| 吐槽西游记后传| 女神降临第三集| 法国女版《壮志凌云》高清免费哪儿| 田村正和去世| 天狱飞龙| 安然丑闻| 坎贝奇第二部曲《品味人生》免费观看| 穿越火线在线观看免费完整版| 电影灰姑娘的故事2| 饥渴的邻居HD| 我的女友妈妈韩字的ID是谁电影 | 律师堕落日本| 登山的目的韩剧| 临时劫案在线观看免费版| 怎样画彩妆| 啄木鸟《荣誉守则》2013 | 龙猫电影| 台剧榜2025最新热播剧| 鬼五虐电影完整版在线观看| 《修理工的艳遇电影| 完美有多美| 头脑特工队2电影| 金枝玉孽2| 三人第一次体检电影免费观看| 半生缘林心如| 两个人观看的视频| 我叫赵甲第电视剧| 四名少妇精油按摩| 聊斋艳谭2| 赌圣之上海滩粤语| 甄子丹锦衣卫| 《家庭矛盾4》麦乐迪观看视频| 成龙历险记免费观看全集完整版| 龙门客栈在线观看免费完整版| 高压监狱2法版| 沈樵第二部闺蜜20分钟| 暴躁46集全在线观看免费高清 | 每日妈妈粤语| 歌声飘过三十年全集|