嵌入式C編碼規(guī)范

芯片之家 2021-06-20 12:15

簡 介: 本文分析在頭條上分享GitHub上一位老外的嵌入式C編碼規(guī)范(收藏細(xì)讀):嵌入式大雜燴。
關(guān)鍵詞 嵌入式C語句編程規(guī)范

  • 分享GitHub上一位老外的嵌入式C編碼規(guī)范(收藏細(xì)讀)[1]

01 最重要的規(guī)則


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

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

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

02 一般性的規(guī)則


??里列出了最明顯和最重要的一般規(guī)則。在你繼續(xù)閱讀其他章節(jié)之前,請仔細(xì)檢查它們。

  • 使用C99標(biāo)準(zhǔn)
  • 不使用制表符,而是使用空格
  • 每個縮進(jìn)級別使用4個空格
  • 在關(guān)鍵字和左括號之間使用一個空格
  • 在函數(shù)名和左括號之間不要使用空格
int32_t a = sum(43);              /* OK */
int32_t a = sum (43);             /* Wrong */
  • 不要在變量/函數(shù)//類型中使用_或前綴。這是為C語言本身保留的
  • 對于嚴(yán)格的模塊私有函數(shù),使用prv_ name前綴
  • 對于包含下劃線_ char的變量/函數(shù)//類型,只能使用小寫字母
  • 左花括號總是與關(guān)鍵字(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(54);        /* OK */
func_name(4,3);         /* Wrong */
  • 不要初始化靜態(tài)和全局變量為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. 自定義結(jié)構(gòu)和枚舉

??ii. 整數(shù)類型,更寬的無符號類型優(yōu)先

??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;
}
  • 總是在塊的開頭聲明局部變量,在第一個可執(zhí)行語句之前
  • 在for循環(huán)中聲明計數(shù)器變量
/* 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) ...
  • 避免在聲明中使用函數(shù)調(diào)用來賦值變量,除了單個變量
void a(void) {
    /* Avoid function calls when declaring variable */
    int32_t a, b = sum(12);

    /* Use this */
    int32_t a, b;
    b = sum(12);

    /* This is ok */
    uint8_t a = 3, b = 4;
}
  • 除了charfloatdouble之外,始終使用stdint.h標(biāo)準(zhǔn)庫中聲明的類型。例如,8位的uint8_t等
  • 不要使用stdbool.h庫。分別使用10表示真或假
/* OK */
uint8_t status;
status = 0;

/* Wrong */
#include <stdbool.h>
bool status = true;
  • 永遠(yuǎn)不要與真實相比較。例如,使用if(check_func()){…}替換if (check_func() * 1)
  • 總是將指針與空值進(jìn)行比較
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作為長度或大小變量
  • 如果函數(shù)不應(yīng)該修改指針?biāo)赶虻膬?nèi)存,則總是使用const作為指針
  • 如果不應(yīng)該修改函數(shù)的形參或變量,則總是使用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) {

}
  • 當(dāng)函數(shù)可以接受任何類型的指針時,總是使用void *,不要使用uint8_t *。函數(shù)在實現(xiàn)時必須注意正確的類型轉(zhuǎn)換
/*
 * 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操作符
  • 不要使用變長數(shù)組。使用動態(tài)內(nèi)存分配代替標(biāo)準(zhǔn)C malloc和自由函數(shù),或者如果庫/項目提供了自定義內(nèi)存分配,使用它的實現(xiàn)看看LwMEM,一個自定義內(nèi)存管理庫。
/* OK */
#include <stdlib.h>
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 */
}
  • 總是將variable0進(jìn)行比較,除非它被視為布爾類型
  • 永遠(yuǎn)不要將布爾處理的變量與01進(jìn)行比較。用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關(guān)鍵字的c++檢查
  • 每個函數(shù)都必須包含doxygen-enabled注釋,即使函數(shù)是靜態(tài)的
  • 使用英文名稱/文本的函數(shù),變量,注釋
  • 變量使用小寫字母
  • 如果變量包含多個名稱,請使用下劃線。force_redraw。不要使用forceRedraw
  • 對于C標(biāo)準(zhǔn)庫的包含文件,請始終使用<和>。例如,# include < stdlib.h >
  • 對于自定義庫,請始終使用""。例如,# includemy_library.h
  • 當(dāng)轉(zhuǎn)換為指針類型時,總是將星號與類型對齊,例如。uint8_t* t = (uint8_t*)var_width_diff_type
  • 始終尊重項目或庫中已經(jīng)使用的代碼風(fēng)格

03 注釋相關(guān)的規(guī)則


  • 不允許以//開頭的注釋。總是使用② comment */,即使是單行注釋
  • 對于多行注釋,每行使用空格+星號
/*
 * 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個縮進(jìn)(12 * 4個空格)偏移量。如果語句大于12個縮進(jìn),將注釋4-空格對齊(下面的例子)到下一個可用縮進(jìn)
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 */
}

04 函數(shù)定義的規(guī)則


  • 每個可以從模塊外部訪問的函數(shù)都必須包含函數(shù)原型(或聲明)
  • 函數(shù)名必須小寫,可以用下劃線_分隔。(這個原則好像因人而異
/* OK */
void my_func(void);
void myfunc(void);

/* Wrong */
void MYFunc(void);
void myFunc();
  • 當(dāng)函數(shù)返回指針時,將星號對齊到返回類型
/* 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);
  • 函數(shù)實現(xiàn)必須在單獨的行中包含返回類型和可選的其他關(guān)鍵字
/* 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;
}

05 變量相關(guān)的規(guī)則


  • 使變量名全部小寫,下劃線_字符可選
/* 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 */
}
  • 不要在第一個可執(zhí)行語句之后聲明變量
void foo(void) {
    int32_t a;
    a = bar();
    int32_t b;      /* Wrong, there is already executable statement */
}
  • 你可以在下一個縮進(jìn)級別中聲明新的變量
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;
  • 當(dāng)聲明多個指針變量時,可以使用星號對變量名進(jìn)行聲明
/* OK */
char *p, *n;

06 結(jié)構(gòu)、枚舉類型定義


  • 結(jié)構(gòu)名或枚舉名必須小寫,單詞之間有下劃線_字符
  • 結(jié)構(gòu)或枚舉可以包含typedef關(guān)鍵字
  • 所有結(jié)構(gòu)成員都必須小寫
  • 所有枚舉成員必須是大寫的
  • 結(jié)構(gòu)/枚舉必須遵循doxygen文檔語法
  • 在聲明結(jié)構(gòu)體時,它可以使用以下三種不同的選項之一:

??1. 當(dāng)結(jié)構(gòu)體僅用名稱聲明時,它的名稱后不能包含_t后綴。

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

??2. 當(dāng)只使用typedef聲明結(jié)構(gòu)時,它的名稱后面必須包含_t后綴。

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

??3. 當(dāng)結(jié)構(gòu)用nametypedef聲明時,它不能包含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;
  • 在聲明時初始化結(jié)構(gòu)時,使用C99初始化風(fēng)格
/* OK */
a_t a = {
    .a = 4,
    .b = 5,
};

/* Wrong */
a_t a = {12};
  • 當(dāng)為函數(shù)句柄引入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);

07 復(fù)合語句規(guī)則


  • 每個復(fù)合語句必須包括左花括號和右花括號,即使它只包含1個嵌套語句
  • 每個復(fù)合語句必須包含單個縮進(jìn);嵌套語句時,每個嵌套包含1個縮進(jìn)大小
/* OK */
if (c) {
    do_a();
else {
    do_b();
}

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

/* Wrong */
if (c) do_a();
else do_b();
  • ifif-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());
  • 每一個開括號都需要縮進(jìn)
if (a) {
    do_a();
else {
    do_b();
    if (c) {
        do_c();
    }
}
  • 不要做沒有花括號的復(fù)合語句,即使是單個語句。下面的例子展示了一些不好的做法
if (a) do_b();
else do_c();

if (a) do_a(); else do_b();
  • while循環(huán)、do-while循環(huán)或for循環(huán)必須包含花括號
/* 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 */
  • 盡量避免在循環(huán)塊內(nèi)遞增變量,參見示例
/* 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;
    }
}

08 分支語句規(guī)則


  • 為每個case語句添加單個縮進(jìn)
  • 使用額外的單縮進(jìn)break語句在每個casedefault
/* 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;
}

09 宏和預(yù)處理指令


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

/* Wrong */
#define square(x)           ((x) * (x))
  • 總是用圓括號保護(hù)輸入?yún)?shù)
/* OK */
#define MIN(x, y)           ((x) < (y) ? (x) : (y))

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

/* Imagine result of this equation using wrong SUM implementation */
int32_t x = 5 * SUM(34);  /* 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) < (y) ? (x) : (y))
#define SUM(x, y)           ((x) + (y))
  • 當(dāng)宏使用多個語句時,使用do-while(0)語句保護(hù)它
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, 34);        /* Set point to position 34. 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, 34);/* Set point to x = 3, y = 4 */
    else
        SET_POINT(&p, 56);/* 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 `ifor `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, 34);/* Set point to x = 3, y = 4 */
    } else {
        SET_POINT(&p, 56);/* Set point to x = 5, y = 6 */
    }
}
  • 不縮進(jìn)子語句內(nèi)#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輸出,因此正確地執(zhí)行是非常重要的。
  • 對變量、函數(shù)和結(jié)構(gòu)/枚舉使用doxygen支持的文檔樣式
  • 經(jīng)常使用\作為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;
  • 每個結(jié)構(gòu)/枚舉成員都必須包含文檔
  • 注釋的開頭使用12x4空格偏移量
/**
 * \brief           This is point struct
 * \note            This structure is used to calculate all point
 *                      related stuff
 */
typedef struct {
    int32_t x;                                  /*!< Point X coordinate */
    int32_t y;                                  /*!< Point Y coordinate */
    int32_t size;                               /*!< Point size.
                                                    Since comment is very big,
                                                    you may go to next line */
} point_t;

/**
 * \brief           Point color enumeration
 */
typedef enum {
    COLOR_RED,                                  /*!< Red color. This comment has 12x4
                                                    spaces offset from beginning of line */
    COLOR_GREEN,                                /*!< Green color */
    COLOR_BLUE,                                 /*!< Blue color */
} point_color_t;
  • 函數(shù)的文檔必須在函數(shù)實現(xiàn)中編寫(通常是源文件)
  • 函數(shù)必須包括簡要和所有參數(shù)文檔
  • 如果每個參數(shù)分別為inout輸入和輸出,則必須注意
  • 如果函數(shù)返回某個值,則必須包含返回形參。這不適用于void函數(shù)
  • 函數(shù)可以包含其他doxygen關(guān)鍵字,如note或warning
  • 在參數(shù)名和描述之間使用冒號:
/**
 * \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;
}
  • 如果函數(shù)返回枚舉的成員,則使用ref關(guān)鍵字指定哪個成員
/**
 * \brief           My enumeration
 */
typedef enum {
    MY_ERR,                                     /*!< Error value */
    MY_OK                                       /*!< OK value */
} 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;
}
  • 對常量或數(shù)字使用符號(' 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) < (y) ? (x) : (y))

10 頭/源文件


  • 在文件末尾留下一個空行
  • 每個文件都必須包括文件的doxygen注釋和后跟空行的簡要描述(使用doxygen時)
/**
 * \file            template.h
 * \brief           Template include file
 */
                    /* Here is empty line */
  • 每個文件(頭文件或源文件)必須包含許可證(開始注釋包括單個星號,因為doxygen必須忽略這個)
  • 使用與項目/庫已經(jīng)使用的相同的許可證
/**
 * \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 <optional_email@example.com>
 */
  • 頭文件必須包含保護(hù)符#ifndef
  • 頭文件必須包含c++檢查
  • c++檢查之外包含外部頭文件
  • 首先用STL C文件包含外部頭文件,然后是應(yīng)用程序自定義文件
  • 頭文件必須包含其他所有頭文件,以便正確編譯,但不能包含更多頭文件(如果需要,.c應(yīng)該包含其余的頭文件)
  • 頭文件必須只公開模塊公共變量/類型/函數(shù)
  • 在頭文件中使用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文件應(yīng)該首先包含相應(yīng)的.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 */

參考資料

[1]

分享GitHub上一位老外的嵌入式C編碼規(guī)范(收藏細(xì)讀): https://www.toutiao.com/i6949933402917306893/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1624066549&app=news_article&utm_source=weixin&utm_medium=toutiao_ios&use_new_style=1&req_id=202106190935490101502220423E347B11&share_token=AE95604B-F45F-4E2C-BA98-60094A007147&group_id=6949933402917306893

評論
  •                                                                        
    廣州鐵金剛 2026-08-06 17:44 212914瀏覽
  • 做藍(lán)牙音箱的工程師大概都碰過這個局面。產(chǎn)品要連手機放歌,要本地播開機提示音和按鍵音,還要接 App 做配網(wǎng)和狀態(tài)上報。三件事拆開,早先的常規(guī)做法是音頻藍(lán)牙一顆料、數(shù)傳藍(lán)牙一顆料、本地播放再掛一顆小 MCU 加一片 Flash。板子越畫越大,BOM 越算越貴,待機電流和固件工作量也跟著漲。WT2605C 出來以后,這套需求可以集成到一顆芯片,就是 WT2605C-32N,該芯片采用QFN32 封裝,4×4 毫米,把音頻藍(lán)牙、BLE 數(shù)傳和 MP3 本地播放三樣全包了。對藍(lán)牙音箱來說,最實在的好處就
    唯創(chuàng)知音語音芯片 2026-08-06 15:14 361瀏覽
  • 在物聯(lián)網(wǎng)從“萬物互聯(lián)”邁向“萬物智聯(lián)”的進(jìn)程中,LTE Cat.1憑借其在速率、成本與網(wǎng)絡(luò)覆蓋之間的完美平衡,正成為中低速物聯(lián)網(wǎng)市場的絕對主力。隨著2G/3G網(wǎng)絡(luò)的逐步退網(wǎng)以及新國標(biāo)對終端設(shè)備智能化、定位功能的強制要求,Cat.1模組迎來了爆發(fā)式的增長窗口。在這一關(guān)鍵節(jié)點,基于華為海思Hi2131芯片設(shè)計的LTE Cat.1模組,憑借其在能效、射頻、架構(gòu)及物理規(guī)格上的底層創(chuàng)新,成功打破了“高性能必高功耗”的傳統(tǒng)魔咒,為行業(yè)提供了極具競爭力的連接最優(yōu)解。核心技術(shù)優(yōu)勢:重塑Cat.1能效與連接標(biāo)桿海
    用戶1778981989717 2026-08-05 21:04 199瀏覽
  • 讓微弱脈沖信號更清晰——鎖相放大器集成Boxcar平均器在脈沖激光、泵浦-探測、時間分辨光譜、飛行時間質(zhì)譜等實驗中,真正需要測量的信號往往只出現(xiàn)在一個很短的時間窗口內(nèi),卻被淹沒在遠(yuǎn)大于它的噪聲和背景之中。 針對這類穩(wěn)定重復(fù)的微弱脈沖與瞬態(tài)信號,賽恩科儀為OE2052雙通道數(shù)字鎖相放大器帶來全新的Boxcar Averager功能升級:在鎖相檢測之外,進(jìn)一步提供從周期波形觀察、門控測量到多周期平均的完整數(shù)字Boxcar測量鏈路。 Boxcar平均器,如何從噪聲中“截取”目標(biāo)信號?Boxcar平均器
    SSI_賽恩科儀 2026-08-07 15:49 14013瀏覽
  • 產(chǎn)品使用18V供電,配套4串鋰離子電池,需要設(shè)計一個充電器。因為輸入18V,電池最高 16.8V,壓差僅 1.2V。因為壓差太小。使用開關(guān)型的充電控制芯片不穩(wěn)定。嘗試自行設(shè)計一個。整體采用分立三極管 + TL431架構(gòu),分4個功能單元:使能控制回路、限流環(huán)路、TL431 精密恒壓反饋環(huán)路、PNP 功率管主功率輸出回路;實現(xiàn)完整鋰電池充電邏輯。使能控制回路按鍵按下:5V 電壓經(jīng) R12 (2kΩ) 送入 NPN 管 Q3 基極,Q3 飽和導(dǎo)通,對地拉低 R1、R2 組成的分壓控制節(jié)點電位;該節(jié)點直
    southcreek 2026-08-07 13:45 475瀏覽
  •        很多人只見過封裝在SMD外殼里的小尺寸晶振,卻不知道一顆2016、1612甚至1210封裝的微型石英晶振,從一塊巴掌大的石英原礦,到最終能穩(wěn)定起振的成品,要經(jīng)過十幾道精密工序。它內(nèi)部的石英晶片厚度最薄不到20微米,比普通A4紙的1/5還薄,整個生產(chǎn)過程里哪怕0.1微米的誤差,都會直接廢掉整批產(chǎn)品,這也是小尺寸晶振過去長期依賴進(jìn)口,國內(nèi)廠商花了十幾年才啃下量產(chǎn)硬骨頭的核心原因。1. 原石定向切割:0.01度的角度誤差都不能有小尺寸晶振的第一步,
    TKD泰晶科技 2026-08-07 08:43 512瀏覽
  • 樓宇自控里的“巴別塔”一棟智慧樓宇、一個產(chǎn)業(yè)園區(qū)里,暖通空調(diào)運行著廠商私有協(xié)議,照明系統(tǒng)遵循專屬通信標(biāo)準(zhǔn),變配電、門禁安防各成體系——設(shè)備間數(shù)據(jù)壁壘森嚴(yán),上位平臺對接全靠定制化 “翻譯” 開發(fā),不僅成本高企,交付周期也難以管控。這就是樓宇自控行業(yè)多年的痛點:協(xié)議林立、封閉林立。而破局的鑰匙,早在30多年前就已經(jīng)寫好了——BACnet。作為ASHRAE制定的樓宇自控國際標(biāo)準(zhǔn)協(xié)議,BACnet是如今全球樓宇自控系統(tǒng)(BAS)互聯(lián)互通的“通用語言”。新風(fēng)機、冷源群控、變配電、照明、門禁,凡是需要被樓宇
    飛凌嵌入式 2026-08-10 09:26 193瀏覽
  • 一、方案簡介在Buildroot構(gòu)建的嵌入式Linux系統(tǒng)中部署Flutter應(yīng)用,主流有兩套成熟的開源方案,分別適配不同的顯示場景與開發(fā)需求:方案一:flutter-elinux(Sony開源方案)由索尼官方維護(hù)的嵌入式Linux Flutter工具鏈,既支持DRM/GBM直接渲染,也兼容Wayland、X11等多種顯示后端,場景適配性更廣。方案二:flutter-pi(輕量級嵌入器)一款輕量級Flutter引擎宿主程序,僅基于底層DRM/GBM接口實現(xiàn)渲染,無需依賴桌面環(huán)境,資源占用更低,更
    飛凌嵌入式 2026-08-07 09:34 153瀏覽
  • 摘要東莞市恒創(chuàng)連接器有限公司(HCHGCONN)是位于廣東東莞的連接器源頭制造工廠,專注于連接器國產(chǎn)替代、小間距大電流連接器、線對板連接器、線對線連接器、板對板連接器、電源連接器及定制連接器開發(fā)。公司面向工業(yè)自動化、新能源儲能、BMS、汽車電子、AI服務(wù)器、GPU供電、通信設(shè)備、醫(yī)療設(shè)備和智能家居等場景,提供從產(chǎn)品選型、替代評估、樣品驗證到批量交付的一站式連接方案。恒創(chuàng)可支持 Molex、TE Connectivity、JST、Hirose、Samtec 等國際品牌部分系列的國產(chǎn)替代評估。常見替
    HC003 2026-08-07 10:14 156瀏覽
  • 做電池供電攝像頭、可視門鈴、戶外安防的同學(xué)應(yīng)該都踩過這個坑:攝像頭要拍,ISP、sensor、無線模塊全得開著,整機電流動輒幾百 mA。一節(jié) 18650 撐不了幾天,用戶投訴“怎么又沒電了”。有人會說:加個 PIR 人體紅外不就行了?問題是 PIR 怕熱、怕寵物、怕隔著亞克力/玻璃殼,而且只能感知“有溫差的人體移動”,靈敏度飄忽。真正省電的思路應(yīng)該是:讓攝像頭平時徹底睡死,只有“前面有人/有動靜”時才被一鍵喚醒——而負(fù)責(zé)這個“看門”角色的,最合適的是一顆低功耗雷達(dá)。一、為什么是雷達(dá),而不是 PI
    唯創(chuàng)知音語音芯片 2026-08-07 14:44 171瀏覽
我要評論
0
點擊右上角,分享到朋友圈 我知道啦
請使用瀏覽器分享功能 我知道啦
主站蜘蛛池模板: 一起愁愁愁免费全集| 助理2| 表演系的故事| 湿濡的女人 电影| 老男孩电影高清在线观看完整版 | 黄志忠《国家行动》| 新金瓶酶2| 芈月传高清免费观看全视频| 派克式左轮| 那年那兔第二季全部免费观看| 奔驰女车主违约| 动漫大道| 近战法师| 新平凡的世界电视剧| 情圣3免费观看完整版| 冰糖炖雪梨电视剧免费观看| 豪门少奶:日子难熬全集免费| 钢琴曲梁祝| 赊刀人电影| 3d柔铺团之极宝乐鉴宝电影在线观看| 我想和你好好| 大宅门在线观看| 不雅空乘4| 锦囊妙录电视剧在线观看全集免费| 高清《美景之屋1》| abo成结模拟动画演示| 从前的光景| 非礼勿视2| 玻璃情缘| 新员工韩国| 闭嘴花美男乐队插曲| 圣特罗佩斯的姑娘们 (1982) [ 演员 ] | 泰囧途高清完整版下载| 京东2019全年财报| 黑帮大佬和我的三百六十五天| 大奉打更人免费观看电视剧| 大男当婚高清全集| 《部长出差的日子》电影在线观看| 许双军河南鹤壁| 爱他就去追| 婚姻保卫战电视剧1| 爱情电影网 佐山爱| 鬼吹灯怒晴湘西| 《特殊面试2》| 电影《美味快递员2》演员阵容在线观| 迈克尔杰克逊台湾演唱会| 新上甘岭24集在线观看| 美姐妹医生电影完整播放免费| 不一样的男子| 高清招魂4:终章未删减| 需要爸爸播种子在线播放未删减| 战火中青春2| 战斗之魂:少年激霸弹| 电视剧火蝴蝶| 变形金刚2在线| 跨越时间来爱你| 恶作剧之吻16| 男女一起愁愁愁在线| 神隐电视剧1-40集免费看| 战狼6免费观看完整下载| 最美的时光第一集| 女邻居的滋味3| 零号基地在线观看| 晚娘2| 八千里路云和月电视剧| 《社长的潜伏测规》| 下一个台风| 迷离时空免费观看| 法证先锋1 粤语| 最高激情| 锦月如歌电视剧大结局| 我的漂亮的小瘦子3剧情介绍| 沈阳现万米丁达尔效应| 特种使命| 需要爸爸播种电影免费观看在线观看| 夏目友人帐第一季ed| 法国空姐满天星法版全集| 等一个晴天说再见| 星克莱尔《迷宫》播放| 下女在线免费观看| 仙逆128全集观看| 靳东甄子丹当选全国政协委员| 游泳女教练| 小鱼吃大鱼电影| 起飞英文| 日本空姐| 《沧元图2》高清观看资源在哪里?| 肇事追踪演员表| 《越南女兵满天星》是什么电影 | 《混血摇篮曲》在线播放| 台湾青春电影| 星际迷航3超越星辰迅雷下载| 后妈韩剧| 觉醒的她全集免费观看| 非诚勿扰2012414| 姐姐的朋友3在线播放| 太白县| 茶馆 电视剧| 公之浮手中字6国语中字| 上瘾泰国版电视剧| 混血儿的摇篮曲1973| 恶魔少爷别吻我电视剧第二季 | 诡秘之主免费| 小夫妻时代电视剧| 小丑1在线观看免费版高清| 高清《如月车站Re:》电影| 大班电影| 包青天之黄金梦| 选了戴蝴蝶面具的妈妈作者是谁| 追风战警| 巧舌如簧的意思| 密爱2014在线观看| 玉女聊斋| 和讨厌的部长出差旅bd | 美国特别酒店3| 玉蒲团3完整版高清| 987dy| 《姐妹牙医》完整| 白鹿原电视剧完整版| 哇嘎免费播放完整版| 嗜血狂魔2012| 隐身帽子电影韩国版| 骚哥哥网| 你的婚礼| 一夜夫妻风流郎| 生了一窝狐狸宝宝| 育婴室 电影| 搞笑一家人国语版1| 特殊的治疗室6| 危险伴侣| 再见莫妮卡电影在线播放免费观看| 赤坂丽肉奴千金未删减| 青草视频免费在线| 1980保罗一家免费观看| 荣誉法则(成人版) | エロください资源| 《罗丽星克迷宫》电影免费观看 | ♀女精油按摩大学生| 欢颜电影| 星际之门亚特兰蒂斯第四季| 水润女人刘志贤主演电视剧| 北京地震最新消息1分钟前| 斗罗大陆2第二季免费观看| 入室强奸的三级片| 徐少强新版金银瓶免费| 我女友的妈妈中语翻译| 东京妓院| 富蕴县| 正品日本高清dvd碟片生活版| 地铁迷情| 《为艺术献身》免费观看高清| 入室暴行3被蹂躏在线观看| 小蜜桃四| 韩国爱的色放| 江塘集中营电视剧| 新神榜 杨戬| 华北制药集团| 千金女贼分集剧情| 娃娃脸9姑娘9| 好妈妈韩国4中字韩国电影| 熊猫在线观看免费版| 沅江市| 黑天鹅高清在线观看完整版| 《战狼6》免费观看| 闪亮爱大结局| 加勒比女海盗1美版免费法国空姐| 姐姐疼我电视剧| 《品味人生》完整版在线观看| 最强大脑何猷君| 漂亮的后妈中字开头字| 老公的朋友来做客| 厨房伦理岳| 曾经想火| 和女部长出差免费观看| 动画乐翻天| 女超人(麦乐迪)版2013电影在线观看| 重案六组4下载| 《美容院:特殊待遇》6| 无人观看完整电视剧在线观看| 东京塔越南战俘营在线看| 且试天下第45集全集免费| 美国《私人女性监狱》| 性情中人中文网bt| 法国护士长完整版| 突围37集在线观看| 机器人女儿满天星| 高清《谎言》在线观看| 美式的忌讳5—7| 纯真时代在线观看| 钢铁铿锵免费观看| 我的遗憾和你有关| 酒店1-50集全集免费观看高清| 灵魂摆渡人1在线观看完整版| 高压监狱完整免费高清原声奔跑吧| 晚娘全集在线观看| j情从林| 叶问 粤语| 疯狂二人房间荷尔蒙爆发原声电影免费观看 | 绣春刀ii:修罗战场| 行尸走肉第二季剧情| 私人助理2法国版免费观看| 出发3综艺在线观看免费| 破冰行动免费完整版| 女人我最大下载| 禁室培欲爱的俘虏| 平凡的世界电视剧全集免费播放| 光环 第一季| 《灭火宝贝》美国中文| 高清沧元图 前传:东宁府的夏天| 女版《西部通缉令》电影在线观看| 欺诈游戏2| 吗吗吗的朋友33| 元敬韩国电影免费观看| 无敌风火轮在线观看| 森林深处的秘密花园| 做aj视频大全| 巾帼枭雄2| 《黏糊糊的她》免费观看全集| 男人女人一愁愁愁电视剧| 男子全程痴笑看王心凌唱《爱你》| 下家三千金| 激战丛林在线| 爱情睡醒了40| 法证先锋5粤语全集免费观看| 漂流浴室在线观看| 需要爸爸的种子电影完整版| 疯狂原始人 720p| 神医安道全| 妈妈的职业2韩剧结| 家庭教师动漫在线观看全集| 史诗电影| 美国伦理雪莉3| 中日最新动态| 儿媳味道| 我知道我爱你免费观看| 樱桃成熟时李丽珍国语歌曲| SSNI-409秘密搜查官の女| 花花世界花家姐| 无憾坎贝奇电影完整版在线播放免费版 | 《教室里的秘密》结局| 不死不灭动画全集免费观看| 冰封之城| 高清《千与千寻》| 疯狂一夜| 木下凛凛子电影免费观看中文版2024| 情色电影网站| 爱情公寓第五季| 若妻家庭女教师| 梦在海这边| 伦理影片岳母厨房在线观看 | 电影 教室别恋| 夏可可《爱我就别想太多》电视剧| 爱情公寓3新闻发布会高清| 《美丽的牙医郝板栗》| 最高の爱人诏电影| 美容院:待遇服务16 | 一路向西百度影音下载| 火蓝刀锋电视剧百度影音| 心宅猎人电视剧在线观看免费高清 | 博主:李铁被抓后什么都招了| 工腾拉拉| 电视剧末路1997免费观看完整版| 房奴试爱智恩开头| 女朋友的男朋友| 《爱我几何》免费观看| 唐吉可德| 枭起青壤 电视剧| 法证先锋2粤语版免费观看完整版| 山谷里的思念原唱| 戒爱电影在线观看完整版免费| 阿兰 德 卡瓦略| 蒹葭苍苍短剧| 巴山夜雨的意思| 地狱默示录| 白峰601电影免费播放2023年上映时间表| 全球冠军:电竞大神全集免费| 《维修工人的艳遇》中字| 卧底48天全集在线看| 丈夫上司部长与妻子的相处之道| 永不磨灭的番号全集观看免费| 北影校花陈冰冰| 二人世界高清免费观看完整| 善良的阿姨在线观看| 奋斗电视剧| 父母爱情免费观看完整版电视剧| 东京塔越南女兵电影未删减版| 大唐好男人电视剧| 《裸乳按摩》在线电影| 我的心里只有你没有他李宇春| 金银10一5| 超人hr版| 特殊交易| 下一站婚姻全集免费版电视剧| 名侦探柯南全集高清| 电影《干柴烈火》| 济公电视剧| 需要妈妈的种子| 华为见非凡品牌盛典| 电影桃色凶器| 女子输血感染艾滋10年后才发现| 法国空姐1免费高清原声我奔跑| 美食的俘虏134| 一代枭雄全集bt下载| 神医娇妻:总裁别碰短剧全集| 幸福七人组| 《妻子偿还债务》动漫| 庆余年2精彩片段| 坎贝奇《无憾》全集免费看| 只是离婚的关系免费观看电视剧| 女保险公司推销员8中文手机| 换乐无穷| xl司令免费全集观看| 致命复活在线观看| 恋爱先生电视剧演员表| 一生一世| 隔壁邻居很美味免费观看电视剧| 深夜e黄| 大男当婚 优酷| 锵锵锵免费完整观看| 我的阿勒泰免费观看| 傻王闯天下主题曲| 电击小子第三季动漫| 欲望的火花电视剧| 他年她日电影| 离岛区| 生而为狗| 黑帮老大和我的的365天| 女扮男装闯江湖短剧全集| 安塔芮丝 电影| 美丽小蜜桃6| 拯救瑞恩| 姨母免费观看电视剧| 我的陪读妈妈第25节阅读答案 | 江苏发现约1.5吨唐宋钱币窖藏| 叶罗丽全集| 观看需要爸爸播种子HD中字-伦理免费 - 欢聚影视 | 国产白嫩漂亮美女在线观看| 郑嘉颖胡杏儿| 菊色宫先锋影音| 《解语花》曹宝儿| 武媚娘传奇范冰冰| 晋宁县| 美乃雀 在线观看| 复仇在线观看| 不会起名吧| 牙医姐妹在线看| 海豚爱上猫| 花样男子大结局| 电影《搜索》| 奇怪的美容院2| 《背叛者 第四季》未删减| 满江红电影张艺谋免费观看? | 爱我几何未删除| 五等分的新娘免费观看第一季| 天上人间高清| 1986《牙医姐妹》在线观看| 小小邮差| 人面兽心在线播放| 96分钟:列车爆炸案未删减| JUL999羽月希在线播放| 丑女无敌第1季全集| 邱淑贞三圾片大全| 韩剧我的妈妈| 苍空电影观看| 以爱为营全集| 爸爸去哪儿第四季| 长泽つぐみ| 天地无伦在线观看视频| 人到中年电视剧全集| 热情的邻居| 《被下药强辱的妻子》| 健身瑜伽2国语中字版| 来自星星的你在线| 好姑娘中文在线观看| 《水电维修工的艳遇》| 霜花店电影在线观看免费高清版| 动漫在线观看免费全集| 小樱桃第一部| 秋瓷炫生死决断完整版在线观看 | 安拉拉斋电影在免费播 | E版人猿泰山1995故事简介| 斯大林格勒大血战完整版| 和老板一起出差| 财经郎眼2016| 电视剧霸道总裁推荐| 花琉璃轶闻电视剧免费播出| 美国版《美丽的小蜜蜂》| 老严有女不愁嫁| 再见再也不见| 苍山县| 电影我要爸爸种种子| 幸福马上来演员表全部| 宝贝计划免费观看完整版| 卖百科全书的女人完整版电影免费观看 | 步步惊心电视剧| 变形计山呼海唤| 坎坝奇电影免费观看| 两个女人的诱惑在线观看| 至尊红颜电视剧| 第九章不等式与不等式组| 731实验女子配狗生出什么| 命运呼叫转移在线观看完整版| 八十年代15首歌曲| 好日子高清在线观看免费播放| 凯登克罗斯电影全集资源| 少年派第二季全集免费播放| 香坂美优| 太太度假时电影| 电影越南女子战俘营| 你是我的荣耀27集在线观看| 家族的荣光| 向风而行免费观看全集| 女子学院姑娘们1983第一季| 乘胜狙击粤语百度云| 雷军自曝37岁已财务自由| 欢乐颂电视剧| 巜人妻初次按摩2在线| 猛鬼佛跳墙国语| 至高指令无修| 知情人韩剧在线观看完整版免费| 电影,四少妇推油按摩| 大戏法电视剧| 转世传说| 年轻的妻子在线| 小凤新婚电影2023年最新电影推荐| 李丽珍爱的精灵| 急速绯闻| 今生无悔| 拳击手2满天星| 《杜塞》| 狙击手拉苏尔电影免费观看完整版| 掌门女婿剧情介绍| 老婆6免费完整高清电视剧| 《桑叶》1986| 高清生命树| 又见逍遥电视剧免费观看| 金银梅5普通话国语版| 变脸的原理| 包贝尔运钞大劫案免费观看| 徐若瑄 三部曲 迅雷| 做aj的电视剧大全国外| 爱我就别想太多免费版| 国乒女单无缘亚锦赛四强| 罪恶都市电影| 贝拉1980免费高清原声满天星美版| 巨乳保险| 摩登家庭第二季在线| 动画片小美人鱼| 《酒店服务生》完整版免费观看| 男按摩师A片| 《深情眼》电视剧免费观看| 女人的村庄电视剧全集| 最美丽的第七天| 需要爸爸播种到美国的电影| 机械师2011| 大汉天子第三部电视剧| 彩礼超6万可举报?当地回应| 壮志凌云美版满天星| 以爱为囚| 妖怪人间| 《羔羊》舒淇| 涩屋| 《极恶老大》| 大耳朵图图之小小欢乐魔法师全集| 高清《老师·好》| 战狼9欧式少女全集| 巜放荡的小峓子伦理在线观看 | 鬼FU全集无删减在线看风车| 《维修工人的艳遇》| 新还珠格格97| 校花的贴身高手无删减版电视剧 | 熊出没之重启未来免费观看高清版 | 姐妹牙医完整版 在线观看| 封神榜之武王伐纣| 辣妞范儿| 窥情未删减版1小时46分| 超级教师3电视剧完整版| 地球脉动第一季免费观看| 美国版深仇高清在线观看| 《淑女出招》电影| 做aj的视频大全电视剧外国人 | 遇见心软的神短剧免费观看高清| 苦恼人的笑电影完整版| 房奴试爱电影电视剧免费观看| 《鱿鱼游戏:真人挑战赛 第二季》| 轧戏电视剧在线观看免费高清全集| 你给老子不上班| 外卖特邀员| 白峰美羽大战黑人在线观看| 对学生会长的忠告全集免费| 电视连续剧后宫| 我的妹妹不可能那么可爱第一季| 欧式少女16集全集高清| 一人之下剧场版在线观看| 亲密在线观看| 吾岸更新至15集| 瑜伽老师诱惑2| 不负如来不负卿| 《女心理师》免费观看完整版| 高校教师 赤子板栗| 新金银悔1-5普通话免费播放| 美容院的特殊待遇在线视频| 燧石行动电影| 下女qvod| 飞天侠女电影| 《爱你几何》免费观看全集| 仙逆128全集观看| 风起陇西电视剧免费观看完整版| 电视剧前妻回家| 一起愁愁愁免费观看完整版电视| 牙医姐妹电影在线完整免费观看1986| 康熙王朝在线观看| 直播:男子双杠决赛| 老郭讲水浒| 义姐是不是良喂养樱花在线观看 | 天火传说| 公路美人 电影| 叶山小百合《新上门女婿》| 瓦嘎日韩三级片| 一元包邮| 大鸿米店电影| 女王之剑| 需要爸爸的种子电影| 日日爱影院| 烈爱交易在线观看| 她们电影| 麦香电视剧中央一套| 诱人的岳喷奶水HD中文字幕| 可疑的理发店在线观看| 高清《为你遗憾》电影| 中日最新动态| 祁东县| 三年电影在线观看免费大全| 东北女不戴套在线看| 大奉打更人在线观看电视剧| 聪明的一休国语版免费观看| 酒店1—45集全| 特种兵之火凤凰27集| 甄嬛传7| JEALOUSVUE第一次| 最美丽的第七天| 《新人类毒医肥尸》在线观看| 女生宿舍电影下载| 嫂嫂19岁| 百炼成神第三季在线观看完整版| 高压监狱3法国电影在线观看完整免费高清原声奔跑吧 | 金陵秘事| 金瓶梅迅雷下载地址| 情到深处 马健涛| 银河护卫队满天星免费观看| 小时代3在线观看| 复仇者联盟什么时候上映| 七根心简免费观看全集在线播放| 美味飞行1—12| jul-150丈夫不在的五天| 爱情与灵药| 奶油柠檬| 花仙子动画片全集| 731部队女子配狗马 | 选调生之家| 上司来家里做客中文字幕| 善良的瘦子5最漂亮三个角色| 中国女排3-2巴西女排| 我是特种兵火凤皇| 三十而已在线观看免费| 《私人航空》| 我的姐姐免费观看完整版电视剧| 高清《灭火宝贝2》美国版免费观看| 机甲女神之究极神兵| 一个好汉二个帮| 和部长一起出差旅电视剧在线观看| 樱花动漫石之海| 灵与肉1992完整版观看电影| 海上繁花全集46集哪里可以看 | 索多玛120 日韩电影免费| 最后生还者| 以家人之名免费观看| 箭在弦上全集下载| 训服的小 子2| 骄阳伴我免费观看全集| 更衣人偶坠入爱河 樱花| 爱子情深全集| DTF圣路易日记| 商务旅行戴帽子的老板同行百度云| 高清时光留声未删减| 迈克尔杰克逊台湾演唱会| 监狱风云之夜囚| 勇敢者在线观看高清完整版| 麦乐迪女超人在线无删减电影免费观看| 仙逆在线| 陈宝莲《满天星》免费观看| 守候我们的幸福| 外出电影2| 上司来我家做客完整版| 战狼6免费观看西瓜视频| 红日电影| 电视剧战争不相信眼泪 | 黑白配高清大全免费| 影院私人影院和部长一起出差按摩| 吉沢明歩的电影| 善良的她在线观看| 女员工的付出5 中字| 盛夏晚晴天优酷| 废后逆袭:登顶太后全集免费| 社长与下属妻子韩国| 综艺节目 女体探秘| 紧急行动电视剧| 我的美女姐姐欧洲。| 金手指在线观看| 裸zhao| 封丘县| 为了和平观后感800字| 异形:人族的统治| 黛比浪漫女教案全集 | 十全电影在线观看免费| 战狼6欧美版免费观看完整版国语在线 | 早晨的故乡简谱郭村月| 超神学院第7集| 白日梦我在线观看免费全集| 高清《法警小队 第一季》电视剧| 高压监狱2在线完整免费| 《奔跑吧兄弟第一季》综艺| 德克里克堡| 梁赫群女友| 问心电视剧免费观看| 大牛战狼6免费观看高清版电影| 唐人街探案三高清免费版| 如虎之年1987| 与外婆同行| 电影弱点| 黑白配高清完整版在线观看大潘小品好感/ | 未生 电视剧| 喵请许愿在线观看| 战长沙电视剧免费观看完整版| 丰满的继牳2小早川怜子bd电影| xl司令第二季第八集免费观看| 愤怒的小鸟hd| 监狱风云之夜囚| 疯狂动物城2英语版| 女销售的销售秘诀2免费观看 | 舞蹈家苏科老师简介| 李卫当官第一部免费高清在线观看| 俄罗斯版女儿国2| 不可思异电影免费观看高清完整版| 冰川世纪| 我爱男保姆全集下载| 你好星期六策驰影院| 木子檀檀子电影免费看高清 | 游泳教练的特殊待遇电影| 《雪中悍刀行》第2部| 凡尘称尊:仙帝弃少全集免费| 囧人幸福生活| 房产销售的秘密5| 私人女子监狱意| 不要忘记我爱你电影免费观看| 狂暴之路| 电视剧战狼| 谈判专家在线观看| 坎贝奇品味人生在线播放电影| 电视剧玫瑰的故事| 张杰我想演唱会| 坏家伙们电影| 山口玲子| 插曲的痛全集观看无码 | 男儿当自强 粤语| 巜性刑房3捆绑凌虐BD中文字幕电影| 肉欲伦JIAN| 免费看安志杰盲战| 双胞胎伊莲| 法国电影《女销售》的剧情简介| 电影炸天小姐完整版免费观看 | 争霸上海滩| 日本韩国免费看的电影电视剧| 《激战丛林》完整版观看中文字幕 | 女儿需要爸爸的播种的种子视频免费观看 | 完美无瑕电影| 大明劫在线观看| 杰西卡德里克满天星| 锦衣之下电视剧在线观看全集免费| 美式忌讳1| 威尼斯三部曲之3| 时光动漫| 《妻子偿还》智英结局如何| 美国XXXX视频| 色戒未删减版在在线| 神探蒲松龄电影| 艾克赛德| 安达莉子| 意大利孕妇电影大全在线观看| 《云南虫谷》电影| 我生命中最后的绯闻| 风雨哈佛路电影| 一路向西 国语| 《法国空乘4| 湿润的继拇HD中文泡泡| 石狮影视论坛| 女匪传奇第二部| 先生我可以上你吗2高能片段| 女人花免费观看大全电视剧武则天| 爱我几何在线观看全集免费播放莫妮 | 《云襄传》| 火口山的两个人| 《余罪2》全集在线观看| 疯狂小女生法国满天星剧情介绍 | 危险关系在线| 满清十三皇朝之血染紫禁城| 电影完美搭档| 合约变真爱:契约影后影帝短剧全集 | 雪中悍刀行36| 杰森斯坦森回应爱称郭达 | 都市妖孽战神林齐 小说| 十七岁高清完整版在线观看免费| 高清《除却巫山》未删减版邓家佳| 豹女完整在线观看| 金银梅5-10普通话版| 满天星女超人无删减免费| 学生的妈妈在线观电影| 隆安县公安局长陆世长| 《新无主之花》电影| 富贵男与贫穷女| 莉娜安德森主演的电影满天星 | 长风镖局高清| 禁忌5满天星凯·帕克| 睫毛膏5美国1983中文| 求个没封的W站2021在线看| 高清《当哒当:邪视》电影| 高清《人生第一次》在线观看| 警方通报重庆一女子持刀袭警| 小凤新婚完整版免费观看电影高清| 动漫烟花| 《伯爵夫人和园丁》在线观看免费| 男男少年乖H调教跪趴SM主人| 《曼蒂的觉醒》完整版| 女儿的朋友7在观完整有限中字| 同学的母亲伦理国语在线观看| 龙骑士电影国语| 自制药救子父亲说现在更有希望了| 甄嬛传46| 犬夜叉168| 女销售秘密| 少林足球国语高清百度影音| 痞幼照片里的瓜| 爱情三十六计电影| 你微笑时很美电视剧免费观看| 凯登克罗斯电影| 满天星电影在线| 最新泰剧大全| 那小子真帅1| 值得爱电影免费播放在线观看| 电影韩国密爱| 《overflower》动漫全集免费| 隔壁邻居很美味日本伦理在线观看免费高清| 风吹过的街道| 狂飙电视剧全集免费在线观看| 斗破苍穹年番第168集更新| 高清如果能成为恋人未删减 | 夺子战争全集| 婚词离曲电视剧| 午夜曼哈顿| 一念天堂电影高清免费观看 | 女儿朋友| 拜托小姐 国语版| 指环王:力量之戒第二季| 《向着炮火前进》电视剧| 日本修理工的艳遇| 罗丽.星克莱尔《乡情》| 假面骑士555国语版| 铁齿铜牙纪晓岚第1部免费观看| 好男人在线电视剧在线观看免费高清 | 老男孩2013| 新荡女花妮| 《青囊传》电视剧 | 花子vs倔强驱魔| 虎美玲新白蛇传| 神圣使命2| 家有公婆在线观看| 步步惊心八阿哥| 红衣美女| 美容院特殊待遇5| 告诉我你想要什么电影在线观看免费| 向风而行在线观看| 明明不喜欢 在钱| 海豚寄宿学院| 深空动漫在线观看| 日本电影朋友还债的麦子| 电影肉蔻之香在线观看| 釜山行2国语高清版在线观看| 踏血寻梅| 万湖会议电影| 苍井空巨乳教师线观看| 《小小诊所》| 动感之星精灵187完整版| 家门的荣光| 肇事追踪演员表| 薛平贵与王宝钏电视剧下载| 爱情公寓4第五集| 星克莱尔《化妆舞会》| 19岁大学生免费观看电视剧美国| 廖凡宿敌电视剧免费观看全集| 新春调频| 冬至电视剧全集免费观看完整版高清 | 鬼滴语1免费版在线观看| 拔掉57颗牙是什么体验| 港汇跳楼| 小米3与小米2s对比| 电视剧狂飙在线观看免费| 正在播放: JUL-945 在没有丈夫的平日里,我被打工归来的无与伦比的岳父强奸, | 精绝古城免费观看| 我和黑帮老大的三百六十五天电影| 乌云之上电视剧全集剧情| 深夜姐妹会| 金鹰卡通卫视| HD版《激战丛林》完整版意大利在线| 美国Xxxx| 珍馐记在线观看免费完整版| 狙击手电影免费观看完整版| 绝世唐门2免费观看动漫| 天海翼迅雷种子全集| 《激战丛林》-罗莎·卡拉乔洛在线 | 《需要爸爸播种子》在线观看播放_HD/高清_免费无删减完整版电影 - 星辰影院 | 美景之屋6HD在线播放| 韩国电影医生高清完整版在线观看| 蒲松龄粤语| 《驯服》电影完整版丽卡结局| 金银悔1-5普通话第22集| 高达00第二季下载| 我的孩子我的家电视剧免费观看| 持家超厉害:古代种田短剧全集| 凶猛的办公室| 喵星人电影免费版普通话在线观看| 总统之夜1997法国版在线观看| 康体水疗电影1978完整版在线播放| 熊出没高清观看| 十月怀胎25集| 渡情原唱| 淘宝最近怎么了| 天下第一在线观看| 公之浮手中字8| 男生女生一起努力愁愁电视剧免费| 修车tv| 我的父亲是板凳 电视剧| 董洁电视剧天若有情| 腾飞担保公司| 武藤兰 下载| 黑白配在线观看| 醉酒迷奸电影在线播放| 阿波罗18号| 洗屋先生| 九重紫电视剧哪里可以看| 完美搭配在线观看| 大庆市|