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

小麥大叔 2025-01-23 19:30

英文原文: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?*/

來源:嵌入式大雜燴



往期推薦



再見了,深圳

推薦一個開源的輕量級任務調度器!TaskScheduler!

新手必看!C語言精華知識:表驅動法

9條必學的嵌入式C語言調試技巧!宏定義的妙用



小麥大叔 一位熱衷技術的攻城獅,懂點技術,會講故事,交個朋友?
評論
  • 在物聯網從“萬物互聯”邁向“萬物智聯”的進程中,LTE Cat.1憑借其在速率、成本與網絡覆蓋之間的完美平衡,正成為中低速物聯網市場的絕對主力。隨著2G/3G網絡的逐步退網以及新國標對終端設備智能化、定位功能的強制要求,Cat.1模組迎來了爆發式的增長窗口。在這一關鍵節點,基于華為海思Hi2131芯片設計的LTE Cat.1模組,憑借其在能效、射頻、架構及物理規格上的底層創新,成功打破了“高性能必高功耗”的傳統魔咒,為行業提供了極具競爭力的連接最優解。核心技術優勢:重塑Cat.1能效與連接標桿海
    用戶1778981989717 2026-08-05 21:04 199瀏覽
  •                                                                        
    廣州鐵金剛 2026-08-06 17:44 212979瀏覽
  • 樓宇自控里的“巴別塔”一棟智慧樓宇、一個產業園區里,暖通空調運行著廠商私有協議,照明系統遵循專屬通信標準,變配電、門禁安防各成體系——設備間數據壁壘森嚴,上位平臺對接全靠定制化 “翻譯” 開發,不僅成本高企,交付周期也難以管控。這就是樓宇自控行業多年的痛點:協議林立、封閉林立。而破局的鑰匙,早在30多年前就已經寫好了——BACnet。作為ASHRAE制定的樓宇自控國際標準協議,BACnet是如今全球樓宇自控系統(BAS)互聯互通的“通用語言”。新風機、冷源群控、變配電、照明、門禁,凡是需要被樓宇
    飛凌嵌入式 2026-08-10 09:26 195瀏覽
  • 摘要東莞市恒創連接器有限公司(HCHGCONN)是位于廣東東莞的連接器源頭制造工廠,專注于連接器國產替代、小間距大電流連接器、線對板連接器、線對線連接器、板對板連接器、電源連接器及定制連接器開發。公司面向工業自動化、新能源儲能、BMS、汽車電子、AI服務器、GPU供電、通信設備、醫療設備和智能家居等場景,提供從產品選型、替代評估、樣品驗證到批量交付的一站式連接方案。恒創可支持 Molex、TE Connectivity、JST、Hirose、Samtec 等國際品牌部分系列的國產替代評估。常見替
    HC003 2026-08-07 10:14 156瀏覽
  • 做藍牙音箱的工程師大概都碰過這個局面。產品要連手機放歌,要本地播開機提示音和按鍵音,還要接 App 做配網和狀態上報。三件事拆開,早先的常規做法是音頻藍牙一顆料、數傳藍牙一顆料、本地播放再掛一顆小 MCU 加一片 Flash。板子越畫越大,BOM 越算越貴,待機電流和固件工作量也跟著漲。WT2605C 出來以后,這套需求可以集成到一顆芯片,就是 WT2605C-32N,該芯片采用QFN32 封裝,4×4 毫米,把音頻藍牙、BLE 數傳和 MP3 本地播放三樣全包了。對藍牙音箱來說,最實在的好處就
    唯創知音語音芯片 2026-08-06 15:14 361瀏覽
  • 導語在現代高速數字電路設計中,信號的完整性已不僅是理想波形推演,而是一場與物理非理想特性正面博弈的工程實踐。濾波器芯片作為凈化傳輸鏈路的關鍵屏障,其核心挑戰在于:能否有效識別并濾除那些隱匿在電平跳變過程中的亞納秒級瞬態脈沖干擾,這類干擾持續極短,卻足以在高速鏈路中引發誤觸發。然而,傳統函數發生器受限于采樣率與邊沿速率,根本無法忠實復現如此狹窄且陡峭的異常波形。針對此困境,德思特TS-AWG7000系列任意波形發生器以17 GS/s采樣率與50 ps原生邊沿速度,為瞬態脈沖提供精細刻畫,配合SPG
    德思特測試測量 2026-08-05 14:06 5瀏覽
  • 做電池供電攝像頭、可視門鈴、戶外安防的同學應該都踩過這個坑:攝像頭要拍,ISP、sensor、無線模塊全得開著,整機電流動輒幾百 mA。一節 18650 撐不了幾天,用戶投訴“怎么又沒電了”。有人會說:加個 PIR 人體紅外不就行了?問題是 PIR 怕熱、怕寵物、怕隔著亞克力/玻璃殼,而且只能感知“有溫差的人體移動”,靈敏度飄忽。真正省電的思路應該是:讓攝像頭平時徹底睡死,只有“前面有人/有動靜”時才被一鍵喚醒——而負責這個“看門”角色的,最合適的是一顆低功耗雷達。一、為什么是雷達,而不是 PI
    唯創知音語音芯片 2026-08-07 14:44 171瀏覽
  • 讓微弱脈沖信號更清晰——鎖相放大器集成Boxcar平均器在脈沖激光、泵浦-探測、時間分辨光譜、飛行時間質譜等實驗中,真正需要測量的信號往往只出現在一個很短的時間窗口內,卻被淹沒在遠大于它的噪聲和背景之中。 針對這類穩定重復的微弱脈沖與瞬態信號,賽恩科儀為OE2052雙通道數字鎖相放大器帶來全新的Boxcar Averager功能升級:在鎖相檢測之外,進一步提供從周期波形觀察、門控測量到多周期平均的完整數字Boxcar測量鏈路。 Boxcar平均器,如何從噪聲中“截取”目標信號?Boxcar平均器
    SSI_賽恩科儀 2026-08-07 15:49 14085瀏覽
  •        很多人只見過封裝在SMD外殼里的小尺寸晶振,卻不知道一顆2016、1612甚至1210封裝的微型石英晶振,從一塊巴掌大的石英原礦,到最終能穩定起振的成品,要經過十幾道精密工序。它內部的石英晶片厚度最薄不到20微米,比普通A4紙的1/5還薄,整個生產過程里哪怕0.1微米的誤差,都會直接廢掉整批產品,這也是小尺寸晶振過去長期依賴進口,國內廠商花了十幾年才啃下量產硬骨頭的核心原因。1. 原石定向切割:0.01度的角度誤差都不能有小尺寸晶振的第一步,
    TKD泰晶科技 2026-08-07 08:43 512瀏覽
  • 產品使用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瀏覽
  • 文:杜杰編輯:侯煜當地時間7月28日,美國特朗普政府落地最新科技封鎖政策,美國聯邦通信委員會(FCC)正式更新《受管制清單》,新增兩大類設備——境外生產的先進機器人設備、境外生產的聯網電力逆變器。FCC在官方情況說明書中明確,該類境外制造產品,“會對美國國家安全或美國民眾的人身安全構成無法承受的風險”。本次新規設置明確豁免機制:經美國國防部(DoW)、電力逆變器品類經美國國土安全部(DHS)審核并授予“有條件批準”,認定對應設備品類不存在重大安全風險,即可獲得準入豁免。同時政策嚴格執行新老劃斷原
    華爾街科技眼 2026-08-03 21:28 361瀏覽
  • 一、方案簡介在Buildroot構建的嵌入式Linux系統中部署Flutter應用,主流有兩套成熟的開源方案,分別適配不同的顯示場景與開發需求:方案一:flutter-elinux(Sony開源方案)由索尼官方維護的嵌入式Linux Flutter工具鏈,既支持DRM/GBM直接渲染,也兼容Wayland、X11等多種顯示后端,場景適配性更廣。方案二:flutter-pi(輕量級嵌入器)一款輕量級Flutter引擎宿主程序,僅基于底層DRM/GBM接口實現渲染,無需依賴桌面環境,資源占用更低,更
    飛凌嵌入式 2026-08-07 09:34 154瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 柯南剧场版国语版全集| 盗墓笔记剧照| 昔有琉璃瓦全集免费看| 北京辉子哥| 新乱世佳人电影完整版| 《战狼6》免费观看完整版高清| 古惑仔4国语高清| 韩日R| 姐姐妹妹站起来舞蹈| 我的后半生电视剧40集免费| 环太平洋国语高清完整版| 《推油》完整版播放时间| 腾飞担保公司| 鬼吹灯之精绝古城西瓜| 娘家的故事| 漂亮女校医免费观看电视剧剧情 | 人间中毒未删减完整版| 迷案1937演员表| 木下澶澶子电影| 神龙赌圣| 韩式翘睫| 爱情公寓3迅雷| 极度兽性在线观看| 21世纪在线观看免费播放| 我最喜欢的一堂课| 足球小将欧洲篇国语版| 和部长出差被下药的电影在线看完整 | 传闻中的七公主 电视剧| 韩国电影美容院的待遇| 被四个人折磨8小时| 银河护卫队3超清完整免费观看| 美容院待遇电影| 爱情动作免费观看全集完整版| 天启 二战| 几度夕阳红电视剧| 韩国演员金承佑| 欧式少女16大结局全集| 夏晚晴天电视剧| 大陆剧以法之名在线观看| 俄罗斯女超人麦乐迪| 经典传奇| 苏醒电视剧| 台湾黛比的浪漫女教师| 缉毒精英全集| 春雨在线观看全集高清免费播放| 青天衙门第二部| 坎贝奇《品味人生》在线观看完整版| 年轻的小婊5线观高清5中字电影| 50岁阿姨观看电视剧日本| 高压监狱2免费满天星法版完整版2019 | 双面娇娃| 酒店1-80集| 松本若菜 下海| 一路上有你2| 《花与蛇3》| 99热视| 大明风华在线观看免费下载播放| 日剧《穿睡衣下楼取快递》 | 漂白免费观看完整版| 邻家娇妻文秋| 私人医院的特殊待遇2| 小日子全部免费播放电视剧| 千山暮雪 续集| 掌中宝电影西班牙| 少年派2电视剧免费观看高清| 《妻子2》在线观看免费版电视剧| 木下凛凛子邻居电影完整版在线观看 | 男性按摩师按摩私处电影| 弃女归家:家产归我完整版观看| 8090三个人的冬季恋歌| 双人调情按摩术在线伦理片| 电视剧免费观看高清全集| 替夫还债十日| 飞天小猪| 完美世界全集免费| 15yc| 中国为什么这么软弱| 南北少林电影| 美丽的桃子5大结局| 有希望的男人电影| 伏妖白鱼镇3除魔卫道| 姜恩惠《特殊诊所》完整版 | 苍空电影全集中文| 女军医免费全集在线看| 男子发明喂鸡神器 网友:费鸡头| 三分野电视剧西瓜免费观看全集 | 美丽妻子替丈夫还债电影完整版免费 | 重口味英剧| 全职高手动漫第二集| 宅门里的丫鬟| 勇敢的心 配乐| 《牙医姊妹》完整版1986| 电视剧母亲的战争| 胜女的代价2在线观看| 梁佳芯国风按摩院在线观看| 欢乐元帅第2部| 家庭老师| 星克莱尔《妄想症》| 新金瓶玉梅玥菲完整版| 莎 劳伦| 小瘦子2国语版免费观看优酷| 苹果完整版在线观看| 放弃抵抗吧亚当君接档| 金牌销售秘密5HD中字| 网球王子全国大赛国语版| 公之扶手4中文版免费观看 | 高清未婚男女的效率恋爱未删减| 激战从林2电影免费观看| 娜塔莎 劳佳姆| 同学聚会2电影完整版结局在线看免费| 樱桃小丸子粤语版| 《爱我几何》免费观看完整版电影法| 电影《剑雨》免费观看| 国王的勇士3| 男人女人愁愁愁电视剧免费播放| 《秘密囚禁》完整版| 哇嘎在线观看完整版| 电击小子第2部全集| 花间提壶第一部免费看| 美女被入室侵犯电影网站免费观看| 全职猎人88| 迪迦奥特曼1| 壮志凌云2法国满天星播放技巧| 如懿传在线看| 公之浮手中字9| 《我的后半生》全集免费观看| 俘虏之锁1-2集在线观看| 风从海面吹过来| 暗宅之迷| 小波影院| 《迷宫》罗丽星克莱尔| 随唐演义 全集| 巜人妻初次按摩2电影| 极限挑战之皇家宝藏bt| 李伯清散打评书| 柳岩热舞| 电视剧邻居也疯狂| 侠岚第4季全集| 鬼剧院之惊青艳女郎| 理伦片驯服小峓子3| 现在我们相爱吗| 奇妙的发型屋| 嘿咻嘿咻| 电视剧《三十而立》| 黑暗荣耀 第二季 电视剧| 少儿节目小猪佩奇| 金瓶梅电视剧全集电视剧在线看免费观看香港 | 游击兵工厂全集| 美女在线观看免费高清电视剧奔跑吧ep| 秘密花园 日剧| 《爱我几何》完整版| 成都大熊猫玩菜刀| 跑男第九季| 倔强驱魔人の花子在线免费观看| 龙者罗拉| 激战丛林观看完整版| 电视剧22条婚规| 缘之空在线观看动漫高清免费| 大闹天宫甄子丹在线观看| 藏海花在线| 菲律宾女同恋爱剧富家千金| 聊斋艳谭之艳魔大战| 荣誉法则(成人版)英文2012| 八角笼中免费观看在线| 变种女狼| 呼吸过度电影| 短剧《权宠天下》| 强奸2在线免费电影| 武动乾坤第四季动漫免费观看| 跟部长出差的温泉之旅在线观看 | 纵有疾风起在线播放| 左手视频免费观看| 法国监狱女狱警2免费观看| 高清留存的爱未删减| 电影《法国空少》免费观看| 学生的妈妈2中韩双字多鱼1| 电影爱的色放在线观看| 四个少妇去按摩在线观看| 《魔法少女伊莉雅》| 时间静止器电影完整版| 勾魂恶梦在线观看免费完整国语| 紫菜汤和清蒸鱼哪个蛋白质高| 光的棍完整手机观看免费| 囧探查过界| 双面胶 电视剧| 调教美女们| 高清《厨房》| 侠岚动画片全集| 台剧《黛比浪漫女家教2》有几集 凌云壮志(法国)满天星 | 大胆美鲍| 任宏恩哭坟| 卢旺达的玫瑰满天星| 小姬无人宠| 渔家三个姑娘1| 慈禧秘密生活 国语| 兄弟的老婆| 我的名字叫可汗| 高潮电影免费观看中| 千山暮雪| 哈尔滨1994电视剧全集免费| 第一滴血6全集免费完整| 老公的朋友来做客| 快递员的特殊待遇2 | 巨茎挺进李淑芬的体内视频| 望向太阳电影| 美国《无憾》坎贝奇| 名侦探柯南694| 鹿鼎记之神龙教| 韩剧妻子的情人| 淮剧珍珠塔| xL司令第二季无马赛免费观看高清| 极限审判| 高清《俄版女儿国》高清版| 美国式家庭忌讳| 蜜桃成熟时百度百科| 高清《笑刃荒途》电影| 特殊的治疗2李采潭主演是谁 | 小镇姑娘国语免费观看| 黑白配高清中文全集免费观看| 怪奇物语第一季免费观看完整版| 隔山有眼2| 沉迷公5全集在线观看免费| 胡歌版的射雕英雄传| 除却巫山2007邓家佳版本| 一世好命| 插曲的痛30集全集免费播| 新十字街头| xl先生真人版免费观看| 吃代餐减肥肝衰竭| 日本维修工人的艳遇| 罗丽星克莱尔《X迷宫》在线 | 流光之下电视剧在线观看| 吉吉电影| 好姑娘2在线播放免费观看电视剧下载| 守望相助| 埃博拉前线电视剧免费观看 | 《快递员的艳遇》中字| 《楼梯间的秘密》结局电影| 男按摩师电影完整版免费观看| 女生宿舍视频| 温泉艳遇| 历劫惊途 第二季全集观看| 爱我几何免费版| 火柴女孩| 三级《偷妻》| 孝昌县| 老炮儿在线| 开放刺激的一对一视频交友| 娃娃脸4完整版在线观看免费 | 《水润人生》刘智贤| 天乩之白蛇传| 《卖房子的女销售| 我 机器人| 重庆最美女孩原视频| 玩火的女孩| 第二农场姑娘| 徐若瑄终极猎杀| 朴亚珍短剧《隐形帽》免费观看 | 罗百吉老婆| 钢铁记忆| 康家电视| 险恶绣感未册版在线观看| 我们这一辈| 江苏两名男子在公园落水身亡| 后宫风韵传之霓裳玉女| 知否知否应是绿肥红瘦吧| 奇妙的美发沙龙在线播放| 漂亮娇妻被社长驯服| 高清《我的娜塔莎》电视剧| 《美丽女儿替父亲还债》| 满江红免费观看| 我才是真豪门:身份互换全集免费| 仁肉叉烧| 亲爱的妈妈4韩国在线看| 电影《马女》完整版在线观看| 轨道小火车34p| 疯狂小说家电影| 花的勇气ppt| 高压监狱完整版在线观看完整免费高清原声满天星感恩 y | 酒店1—80全集免费完整版| 学生大雨中军训老师打伞围观| 爱我几何电影在线观看免费 | 高清胡乱的深见君未删减| 日本电影和部长一起出差| 我们在黑暗中相拥短剧免费观看| 龙棺古墓西夏狼王在线观看| 三年大片免费观看国语完| 朱棣电视剧50集免费观看| 电视直播频道| 高清御赐小仵作2未删减| 新僵尸先生国语高清| 现在的是哪一个多闻! ?| 酒店1—50全集观看| 当头炮的走法| 若你安好便是晴天全集| 仁心俱乐部全集免费播放| 《繁花》免费播放在线观看全集 | 下水道美人鱼在线| 细妹按靓| 影音先锋 日本资源| 日本搞笑整人节目| 越狱第三季全集下载| 铠甲勇士之帝皇侠全集| 《丈夫不在家维修工人上门维修》| 成何体统第二季| 《瓜达卢佩的玫瑰》在线观看| 广场舞故乡的云| 度华年在线观看免费高清| 壮乡小莫现实的老婆| 九尾狐姐姐传电视剧| 《21世纪爱情指南》| 黑暗荣耀2无删减韩剧在线播放| 谈情说案电视剧| 浪花男神| 叶罗丽光浮沉| 可疑的美容院2| 日本战狼10免费完整| 樱兰高中男公关部| 坏鸟电影| PPPD-258在线| 毒战1韩版免费完整观看| 一本到高清视频免费观看| 《偷天宝鉴》叶子楣免费观看| 武装特警电视剧| 修理工的欲望| 好迪代言人李玟| 隔壁女孩5中字id| 完美世界dj| 丰满的临时工HD| 有罪之身| 扫黑决战28集全免费| 12大战动漫免费观看| 徐州市| 绿萝花电视剧免费观看| 寒战2免费| 美国电影想要爸爸播种| 数字追凶第一季| 三级片善良的同学| 雷神百度影音高清| 激战HD| 双电子琴音乐下载| 部长来家做客无删减版中文 | 欢乐颂3免费观看| 万州区| 特命战队动漫| 乡村三姐妹保姆医药| 河南男子与猪结婚引争议| 丛林武士| 门弟电视连续剧| 虎虎是只喵| 暴躁妹妹国语版bgm视频下载免费| 肉蒲团高清| 法国空乘13| 高清正在缩小的男人| 百变金刚| 我天命大反派动漫在线观看第二季| 高清《为有暗香来》 | WWW.00271.色情网| overflower第一季在线观看免费全集| 孙杨事件| 交换游戏2中国话| 星克莱尔第一夫人免费播放| 朴亚珍《隐形帽》原版在线观看| 女人香韩国电影| 进击的巨人完结篇| 第二个农场的姑娘们| 百万新娘第一部| 赴汤蹈火2025免费观看 | 惊弦电视剧在线观看全集| 三个女人给男人精油按摩三级片 | 交换温柔| 韩国电影雏妓| 战狼6妈大牛| 高清《美景之屋1》| 电影警报战在线观看| 还珠格格第三部天上人间| 画皮2电影| 别墅轮换5攻略免费观看| 新世界孙红雷电视剧| 陪部长出差韩国电影| 人生之路电影免费观看| 泛而不精的我被逐出勇者队伍未删减| 电影韩国姐姐完整版在线观看| 古堡女仆的服务电影免费观看| 电视剧青青河边草| 黑白配高清完整版免费观看中文版 | 昭觉县| 学生会的一己之见第二季| 瑞尔精灵| 插曲的痛45全集免费观看高清版| 带领村民奔小康:返乡创业全集免费 | 高清《周年纪念日》电影| 轻轻告诉你简谱| 善良的阿姨在线观看| 海之声如如| 百万遗产 韩剧全集| 男子全身沾满水泥被路人当成雕像| 哈利波特6免费观看| 禁止的爱善良的小姨在线播放免费| 黄尚武私房作品合集| 做aj电视剧在线观看| 电视剧风筝全集观看| 尖峰时刻3下载| 和部长出差电影中字| 胡歌版鹿鼎记| 永时影院| 被闺蜜强啪百合小说H| 水门桥在线观看完整版高清 | 宋雨琦张薇电视剧| 电视剧时尚女编辑| 荷尔蒙6第一集| 《圣特罗佩姑娘们1982》电影在线观看| 末路电视剧| 电影完整版免费观看| 天使的契约| 高清重启未删减| 死亡之花| 我的私人女家教老师理论片| 法国《少女农场》中文版| 《特别的酒店》免费观看中文版全集| 坎贝奇《无憾人生》| 闺蜜决电视剧全集免费观看| 原野免费| 太阳的后裔演员表| 派出所的故事| 欧美1-5在线观看| 追风行动电视剧全集免费观看| 灵域电视剧免费观看全集在线| 播放泰罗奥特曼| 免费观看法国空乘4| 高清《桃恋者》电视剧| 电视剧驻站免费观看| 蒹葭苍苍短剧| 美味快递在线| 双龙出手百度影音| 遥远的距离电视剧| 姥姥免费视频在线| 美容院·特珠待遇2| 邻家女人丈夫不在家电视剧| 带领村民奔小康:返乡创业全集免费 | 老阿姨在线观看免费版电视剧| 电视剧妈妈在等你全集免费播放 | 女保险公司推销员8| 梦想成为魔法少女2| 正中下怀的意思| 廖学秋潘金莲| 农民下乡免费观看完整版| 解禁男女在线观看| 警察故事2| 飘香在线观看免费完整版| 别扒了我身份藏不住了短剧| 网购迪士尼套餐最终民警护送入园 | 好姑娘8完整版在线观看全集| 爱的躯壳在线观看| 蜘蛛侠1电影国语| 伦理《高压监狱2》法国版| 木乃伊1高清完整版电影在线观看| 黎明前的暗战电视剧| 妈妈爱上儿子同学的电影叫什么| 速递惊魂| 莫莉特别酒店3| 无心法师金晨| 伞娘传奇电视剧全集剧情| 《北上》全集在线观看| 王多鱼打扑克视频在线免费观看| 高清《朋友的妻子》5| 放羊的星星| 少女初体验电影免费观看完整版| 新版金银梅5普通话免费观看| 西西GOGOGO高清在线完整版| 金刚狼2 字幕| 《艳女伦交》| 归路电视剧免费完整版观看高清| 黑白配1080完整版在线观看| 春夜染明月短剧免费观看| 刑警 粤语| 维修师傅的艳遇HD在线| 致命弯道5完整版在线观看视频| 男模走秀| 《被下药强辱的妻子》免费看 | 延禧攻略70集免费播放完整版| 《弗兰茨》| 高清《我的反派男友》免费观看| 疯狂厨房| 打扑克视频免费观看| 《检察官》全集观看| 天狼星行动电视剧全集免费观看| 凌云壮志2(欧美)满天星| 不死者之王在线观看| 宜昌保卫战电视剧| 九龙城寨2| 爱情有烟火免费观看| 一起愁愁愁30集全免费版在线观看| 不差钱电影| 心宅猎人电视剧在线观看免费高清| (丰满的继牳3)理伦片在线观看 | 爱你几何在线观看| 上锁的房间在线观看免费高清| 法证先锋6电视剧全集在线观看| 母亲爱上儿子的同学》电影| 无所畏惧2正版免费播放| tobu4美国免费| 女扮男装当校草全集免费| 生化危机终章在线观看| 战狼四| 魔鬼公交车上的小黄说说| 圣杯之战游戏| 上思县| 努努秘密花园免费观看电视剧| 女销售的销售秘密2| 深夜航班 第二季| 学生的朋友3| 隔壁邻居很美味电影在线观看免费高清| 珍馐记在线观看免费完整版| 波奇亚电影在线观看| 美景之屋5未增减板| 修理工的艳遇三级片| 万年牢ppt| 看我从镜子里怎么查你| 性电影免费| 浮生影视在线观看免费高清| 赤裸羔羊| 妈妈爱上儿子免费播放电视剧大全| 古墓荒斋电影免费观看完整版| 肉肉的小黄车| 总统夫人星克莱尔1997满天星| 釜山行电影完整版| 侠客红尘图片大全| 战神传说百度影音| 非诚勿扰泰国女嘉宾| 韩国电影r在线观看| 两个人国语高清在线观看| 《激战丛林》无删除版| 电视剧冰锋剧情介绍| 朋友的妈妈在线免费| 法国版《女超人:麦乐迪》在线观看http | 记忆传授人| 激情丛林男主角还演过什么电影 | 女学生被爆视频在线观看| 你给我的喜欢免费观看全集完整版| 《睫毛膏3》美国| 凌晨两点半| 高清明珠奇谭| 哥哥的老婆韩国电影| 麦迪乐女超人在线播放视频| 大道朝天动漫免费在线观看全集| 性情中人中文网bt| 高清《法国空乘5》无删减版| 王曼昱对张本美和的比赛| 福宝团宠:农家日常短剧全集| 满天星电影免费观看高清在线播放| 高清《一路向北》完整版| 动漫二人生猴子免费观看动漫视频| 《需要爸爸播种子》电影免费在线观看,高清完整版美国倫理片_努努影院 | 丁度《我怀念索妮娅》在线播放| 床上里拉| 礼物电影完整版在线看| 天降财神国语高清| 《激战丛林》海泽摩尔电影在线观看| 女帝江山:美男环绕完整版观看| 晚娘 电影完整版1| 女律师替夫还债| 我怒了电影免费播放| 激战丛林未删减完整版在线观看| 满分追爱公式| 《真相》在线观看免费| 漂亮的妈妈7开头字| 《情事》莫妮卡无删减版| 战国basara石田三成| 高清《赤壁》电影| 肉蔻之香免费观看| 仙踪林 在线观看| 全球最让人害羞的时装比赛| 《乳房按摩》免费观| 高清《清宫性史》香港在线观看| 不能说的秘密| 女子特工队满天星1973版在线观看| 老枪电影完整版| 新月格格电视剧全集播放免费观看| 铠甲勇士铠传免费观看| 生活中马玛丽| 从失乐园开出的地铁| 良医第一季在线观看免费完整版| 女超人法国| 千年血战篇| 庶女逆袭:嫡姐别嚣张全集免费| 《萌萌的妈妈》动漫播放| 麦乐蒂马克思满天星| 新金瓶梅3d 龚玥菲| 只是结婚的关系免费观看| 美式的忌讳5-| 李二不哈| 财源滚滚小厨神| 电视剧天眼| 电视剧妻子免费观看| 入殓师电影完整版在线播放| 红灯记伴奏| 浮之公手3| 快餐车免费| 猫和老鼠传奇2| 韩国漂亮妈妈5观整有限中字| 《美容院特殊待遇》电影| 小蜜桃5观看免费高清版电视剧| 花样女鬼| 当着丈夫面被耍| 《分娩按摩》2图片视频| ママぷりっ!?| 雷霆扫毒粤语| 三妻四妾免费观看完整版高清,皇家女| 水浒传武松打虎是第几集| 家有艳妻| 朝国年经的继4免费观看时间一| 汪汪队立大功| 《大军阀》| 禁忌女孩第1季| av无| 分手大师西瓜影音| 女神降临第三集| 操俄罗斯美女| 帝王攻略动漫| 傻儿军长| 向井蓝之特殊治疗医护最新消息| 电影在线免费观看修理工的艳遇 | 姐妹牙医电影手机在线| 刺刀电视剧| 螳螂捕蝉电影| 《情不自禁》叶玉卿在线| 插曲的痛免费播放完整中国| 无心法师全集免费观看| 燃烧电视剧免费完整版| 黑暗荣耀未删减版| 天子寻龙| 罗丽星克莱尔在线观看 | 女匪传奇| 木下檀檀子《邻居》| 卢旺达的玫瑰满天星| 我朋友的丈夫3| 魔王学院的不适合者动漫免费观看| 剑侠电视剧| 中字HD丈夫的下属中字| 美乃雀的电影免费观看| 电影在线观看视频| 电视剧海天之恋| 《月光变奏曲》电视剧| 麦乐迪《家庭矛盾》百度网盘免费观| 在线播放国风按摩院 春宵一克值千金 第1集 - 高清资源 - 大鸟视频 | 鬼神童子主题曲| 白峰美羽伦理片| 硝烟散尽| 篮球飞人| 婆婆来了26| 李多海的电视剧| 千金赤子板栗在线观看免费高清| 墨西哥电视剧《la rosa de guadalupe》(瓜达卢佩的玫瑰/奇迹玫瑰 在线 | 《黛比大战达拉斯》| 灾女变福妻:全家都宠我全集免费| 燃烧电视剧全集30集| 空姐3在线观看完整免费高清原声满天星奔跑吧ep| 骨王第一季免费观看完整版| 扫毒粤语| 魔法灰姑娘在线观看| a人片在线观看| 真命小和尚| 满满喜欢你免费观看| 徐少强版金玉梅完整版免费观看| 有希望的男人无删减版| 圣母在上第一季| 和喜玉兰免费观看完整版高清| 罗马尼亚电影复仇| 安庆二模| 巴萨战胜曼联| 杀人者的购物目录| 美国式家庭的忌讳1-7在线观看| 熊出没之夺宝熊兵电影| 通辽市| 母亲爱上儿子同学的美剧| 上海上海电视剧| 有情饮水饱国语| 19岁大学生免费看电视剧| 向爱而生全集免费播放视频| 走向共和哪里可以看| 白夜行日剧| 53酒店1-60集| 性生活1| 美发屋特别待遇2| 身不由己国语| metarthunter| 湛江市| 双人调情按摩师免费观看| 摩天轮dj| 回响电视剧剧情介绍| 网红逆袭全集免费| 电视剧da师完整版免费播放| 凯帕克主演的电影在线观看 | 谎言的诱惑| 少女大人免费完整版高清| 斗罗大陆在线观看完整版免费观看| 电影勇敢的心| 看暴操老妈46集完整片| 风铃动漫在线观看完整版与| 柯南剧场版全集免费观看| 欲望爱人未删减版在线观看影片| 小泽玛莉亚电影| 美国版荷尔蒙6日本版| 八楼的二路汽车| 烽火佳人电视剧免费观看完整版| 唐伯唬vlog在线观看免费版| 白峰美羽电影免费版高清| 最美的时候遇见你在线观看完整版| 肯德桑德兰满天星免费观看| 阿黛尔的生活未删| 真实处破疼哭在线播放| 兵临城下电视剧下载| 禁忌2年一代禁忌| 新还珠格格下载地址| 老李头的春天第九集| 金瓶双艳杨思群版全集| 《美丽妻子替弟还债》剧情| 特殊精油按摩电影| 漂白在线播放| 新闻女王全集免费观看| 美国式的家庭禁忌2大结局人与动物| 一路向北电影免费观看在线高清| 地牢女孩| 上书房电视剧| 娜妲莉的情人百度影音| 年轻儿媳妇电影日本| 考比网站| 守护者联盟| 三秒后野兽住在联谊会角落| 1985G点原版完整版| 光能使者国语版全集| 年轻的家长3| 温柔的背叛杨桃| 《酒店》1-100集免费观看在线| 除却巫山| 金钱之味快播| 请成为我的家人一共多少集| 《炸天小姐》完整版| 满天星麦乐迪电影在线观看| 老头一级片| 《好东西》剧情介绍| 宜都市| 夫妻俩一起按摩精油在线观看 | 净最新影片在线看| 战神王妃:夫君战场护我短剧全集| 小凤新婚台湾剧在线观看色情| 香港特别行政区长官| 《漂白》电视剧在线播放| 人鱼小姐全集| 《女超人:麦乐迪》| 妈妈的职业2韩剧中文翻译| 春节起源于哪个朝代| 免费看安志杰盲战| 电视剧三国演义全集| 渔女实战2免费观看正版电影 | 《坎贝奇》视频| 电影猛龙过江| 和老板在办公室BD 中文| 林宥嘉厦门演唱会| 金银梅5至10普通话| 电影《法国牛郎》| 新版还珠格格之燕儿翩翩飞| 人在囧途2票房| 血战到底全集| 坠落的女律师日剧免费观看| 现在是和相爱的人一起生活吗 | 美国的忌讳1-6| 策驰影院免费| 永远在路上第二集| 力王之王国语免费观看完整版| 妻子8免费完整高清电视剧在线| 意大利爱我几何电影完整版播放 | 刀剑神域07| 邱淑贞三圾片大全| 超级司机凌杰| 在丈夫面前被别人欺负日语| 《教室里的激情》韩国电影| 披荆斩棘2| 入室劫财劫色国语版 | 美国禁忌式家庭结局4k| 情人的365天| 电视剧外姓兄弟| 战狼6免费版高清播放在线观看| 小叔子看我喂奶他硬了| 欢颜电影| 梦精爱2在线观看| 姐妹牙医电影完整版在线看| 向熊猫福菀泼水3游客身份未确定| 沧元图动漫60| 叶问1电影| 爸爸播种第二部电影| 聚会的目的在线观看完整版迅雷星辰| 超级大坏蛋国语版免费观看| 孙红雷打黑风暴在线观看| 法国私人航空电影| 人猿泰山意大利| 史上最强太子爷短剧全集| 海贼王480| 半是蜜糖半是伤免费观看在线| 369你懂得电影在线观看| 小小安妮第三季| 吸血鬼检察官| 电视剧血色浪漫全集免费版| 也平凡电视剧在线观看| 韩惠珍演过的满天星三部曲| 3对1四人一次性体检电影| 一个人免费完整在线观看HD| 第一滴血5 国语版| 下属的妻子电影| 飞哥大英雄40全集免费| 朝鲜实施多项军事活动| 刘欢 国际歌| 《蓝色隐形帽子完整版| 雷军说第一个接受采访有点小紧张| 龙珠大魔免费观看| 樱兰高校男公关部电影| 妈妈的职业5观看全集免费 | 讲的笔顺| 莫小棋三级| XL司令第一季真人版在线看| 征途电影国语版免费观看| 高福:长新冠是基本事实| 隔壁的邻居免费完整版电视剧| 《需要爸爸播种子》HD高清完整版在线观看 - 热门电影播放 - 优看影选网 | 蓟县核桃| 母亲主动给孩子降火好吗| 电视剧百万新娘之爱无悔| 纪光莉替夫还债的电影免费观看| 漂亮的妈妈7中字开头7个字! | 中国新说唱第一集| 如此婚姻电视剧免费观看| 私人女人| 深喉吞精日本| 水浒之英雄本色| 妻子的新世界免费看电视剧| 兵临城下电影在线观看| 希要爸爸种子免费观看视频| 蝙蝠侠:黑暗骑士电影| 说出你的秘密| 杨坤无所谓| 女销售2| 菲律宾电影《私人教练》的创作背景| 赘婿当道全集免费| 智取威虎山电影下载| 古典吉他曲谱| 希要爸爸的种子| 这公司有我喜欢的人动漫完整版 | 姐姐的朋友在线视频| 混血儿的摇篮曲电影未删减版| 高清相反的你和我未删减|