In diesem Dokument wird der C -Code -Stil beschrieben, der von Tilen Majerle in seinen Projekten und Bibliotheken verwendet wird.
Beginnen wir mit dem Zitat von Gnome Developer Site.
Die wichtigste Regel beim Schreiben von Code lautet: Überprüfen Sie den umgebenden Code und versuchen Sie, ihn zu imitieren .
Als Betreuer ist es bestürzt, einen Patch zu erhalten, der offensichtlich in einem anderen Codierungsstil als umgebende Code befindet. Dies ist respektlos, wie jemand, der sich in ein makellos geplantes Haus mit schlammigen Schuhen befindet.
Was auch immer dieses Dokument empfiehlt, wenn bereits geschriebener Code vorhanden ist und Sie ihn pflücken, halten Sie seinen aktuellen Stil konsistent, auch wenn es nicht Ihr Lieblingsstil ist.
VSCODE ist mit einem vorinstallierten clang-format
Tool (Teil des LLVM-Pakets) ausgestattet, das Entwicklern mit automatischem Format-Tool während der Codeentwicklung unterstützt.
Daher ermöglicht es Benutzern, Code in der Dateiänderung zu formatieren (und zu speichern). Wenn die Datei gespeichert wird, versucht VSCODE, den Clang-Format aufzurufen und den Code zu formatieren. Verwendungsregeln sind in der Datei .clang-format
. Wenn das Clang-Format die Regeln im Pfad der aktuellen Datei nicht finden kann, wird es bis zum Stammverschluss bis zum gefundenen Weg gehen. Wenn immer noch keiner verfügbar ist, werden dann Standardregeln verwendet.
Dieses Repository enthält immer aktuelle .clang-format
Datei mit den erklärten Regeln. Sie können den Ordner im Stamm oder in Ihrem Projekt oder sogar in der Stammin Ihrer Softwareentwicklungsprojekte einsetzen -> Verwenden Sie eine Datei für alle!
Einige Konfigurationen müssen aktiviert sein:
Die Schlüsselwörter dürfen , nicht erforderlich , dürfen , dürfen , sollten , nicht empfohlen , nicht empfohlen , Mai und optional in diesem Dokument wie in BCP 14 beschrieben sein dürfen und nicht in BCP 14 [RFC2119] [RFC8174]
Hier sind die offensichtlichsten und wichtigsten allgemeinen Regeln aufgeführt. Bitte überprüfen Sie sie sorgfältig, bevor Sie mit anderen Kapiteln fortfahren.
clang-format
sollte mit der an dieses Repository angehängten Formatierungsdatei verwendet werden (Version 15.x
ist ein Minimum)C11
-Standard4
Leerzeichen pro Einrückungsstufe1
Speicherplatz zwischen Keyword und Öffnungshalterung /* OK */
if ( condition )
while ( condition )
for ( init ; condition ; step )
do {} while ( condition )
/* Wrong */
if ( condition )
while ( condition )
for ( init ; condition ; step )
do {} while ( condition )
int32_t a = sum ( 4 , 3 ); /* OK */
int32_t a = sum ( 4 , 3 ); /* Wrong */
__
oder _
Präfix für Variablen/Funktionen/Makros/Typen. Dies ist für die C -Sprache selbst reserviertprv_
Name Präfix für streng modulprivate (statische) Funktionenlibname_int_
libnamei_
_
charfor
, 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 */
global
Variablen nicht in einen Standardwert (oder NULL
), implementieren Sie sie in der dedizierten init
-Funktion (falls erforderlich). static int32_t a ; /* Wrong */
static int32_t b = 4 ; /* Wrong */
static int32_t a = 0 ; /* Wrong */
In eingebetteten Systemen ist es sehr häufig, dass RAM -Erinnerungen über verschiedene Speicherorte im System verstreut sind. Es wird schnell schwierig, alle Fälle zu behandeln, insbesondere wenn der Benutzer benutzerdefinierte RAM -Abschnitte deklariert wird. Das Startskript ist verantwortlich, um Standardwerte (.data und .bss) festzulegen, während andere benutzerdefinierte Abschnitte möglicherweise nicht mit Standardwerten gefüllt werden, was zu Variablen mit Init-Wert führt, hat keinen Einfluss.
Um unabhängig von einem solchen Problem zu sein, erstellen Sie die Init -Funktion für jedes Modul und setzen Sie sie mit der Festlegung von Standardwerten für alle Ihre Variablen fest, wie SO:
static int32_t a ; /* OK */
static int32_t b = 4 ; /* Wrong - this value may not be set at zero
if linker script&startup files are not properly handled */
void
my_module_init ( void ) {
a = 0 ;
b = 4 ;
}
void
my_func ( void ) {
/* 1 */
char a ; /* OK */
/* 2 */
char a , b ; /* OK */
/* 3 */
char a ;
char b ; /* Wrong, variable with char type already exists */
}
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 ;
}
typedef struct {
int a , b ;
} str_t ;
str_t s = {
. a = 1 ,
. b = 2 , /* Comma here */
}
/* Examples of "complex" structure, with or with missing several trailing commas, after clang-format runs the formatting */
static const my_struct_t my_var_1 = {
. type = TYPE1 ,
. type_data =
{
. type1 =
{
. par1 = 0 ,
. par2 = 1 , /* Trailing comma here */
}, /* Trailing comma here */
}, /* Trailing comma here */
};
static const my_struct_t my_var_2 = {. type = TYPE2 ,
. type_data = {
. type2 =
{
. par1 = 0 ,
. par2 = 1 ,
},
}}; /* Missing comma here */
static const my_struct_t my_var_3 = {. type = TYPE3 ,
. type_data = {. type3 = {
. par1 = 0 ,
. par2 = 1 ,
}}}; /* Missing 2 commas here */
/* No trailing commas - good only for small and simple structures */
static const my_struct_t my_var_4 = {. type = TYPE4 , . type_data = {. type4 = {. par1 = 0 , . par2 = 1 }}};
for
die Schleife /* 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
oder double
, verwenden Sie immer Typen, die in der stdint.h
-Bibliothek deklariert sind, z. uint8_t
für unsigned 8-bit
usw.stdbool.h
-Bibliothek. Verwenden Sie 1
oder 0
für true
oder false
jeweils /* OK */
uint8_t status ;
status = 0 ;
/* Wrong */
#include <stdbool.h>
bool status = true;
true
, zB. if (check_func() == 1)
, verwenden Sie if (check_func()) { ... }
NULL
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
für Länge oder Größenvariablenconst
für den Zeiger, wenn die Funktion den Speicher nicht ändern sollte, auf den pointer
angezeigt wirdconst
für den Funktionsparameter oder für den Funktionsparameter oder für die Variable, wenn er nicht geändert werden sollte /* 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 *
, verwenden Sie nicht 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
des Operatorsmalloc
und free
Funktionen oder wenn Bibliothek/Projekt eine benutzerdefinierte Speicherzuweisung bietet, die Implementierung verwenden /* 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 */
}
boolean
Typ behandelt wirdboolean-treated
Variablen mit Null oder einem. Verwenden Sie stattdessen nicht ( !
) 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 */
für Kommentare, auch für EinzellinienkommentareC++
mit extern
Schlüsselwort in der Header -Datei einstatic
istforce_redraw
. Verwenden Sie keinen forceRedraw
void *
, z. uint8_t* ptr = (uint8_t *)func_returning_void_ptr();
als void *
wird sicher zu einem anderen Zeigertyp befördertuint8_t* ptr = func_returning_void_ptr();
stattdessen>
<
für die C -Standardbibliothek inklusive Dateien, z. #include <stdlib.h>
""
für benutzerdefinierte Bibliotheken, z. #include "my_library.h"
uint8_t* t = (uint8_t*)var_width_diff_type
//
nicht erlaubt. Verwenden Sie immer /* comment */
auch für Einzellinienkommentare //This is comment (wrong)
/* This is comment (ok) */
space+asterisk
für jede Zeile /*
* 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
Eingeweide ( 12 * 4
Leerzeichen). Wenn die Aussage größer als 12
Eingeweide ist, machen Sie einen Kommentar 4-spaces
(Beispiele unten) auf den nächsten verfügbaren Einsatz 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 */
}
_
-Zeichen getrennt /* 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!rn" ;
}
/* Wrong */
int32_t foo ( void ) {
return 0 ;
}
_
-Zeichen /* OK */
int32_t a ;
int32_t my_var ;
int32_t myvar ;
/* Wrong */
int32_t A ;
int32_t myVar ;
int32_t MYVar ;
type
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 ;
_
zwischen den Wörtern seintypedef
-Schlüsselwort enthalten Wenn die Struktur deklariert wird, kann eine von 3
verschiedenen Optionen verwendet werden:
_t
enthalten. struct struct_name {
char * a ;
char b ;
};
_t
-Suffix enthalten. typedef struct {
char * a ;
char b ;
} struct_name_t ;
_t
und müssen nach seinem Namen für Typedef -Teil _t
Suffix enthalten. typedef struct struct_name { /* No _t */
char * a ;
char b ;
char c ;
} struct_name_t ; /* _t */
Beispiele für schlechte Erklärungen und ihre vorgeschlagenen Korrekturen
/* 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
-Initialisierungsstil /* OK */
a_t a = {
. a = 4 ,
. b = 5 ,
};
/* Wrong */
a_t a = { 1 , 2 };
_fn
-Suffix /* 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
verschachtelte Erklärung enthält1
Einrückungsgröße für jedes Nest hinzu /* 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
oder if-else-if
muss sich else
in derselben Zeile wie das Schließen der ersten Anweisung befinden /* OK */
if ( a ) {
} else if ( b ) {
} else {
}
/* Wrong */
if ( a ) {
}
else {
}
/* Wrong */
if ( a ) {
}
else
{
}
do-while
, while
ein Teil in der gleichen Zeile sein muss wie die Schließung der Klammer von do
-Teil /* 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
oder for
Schleifen Klammern enthalten muss /* OK */
while ( is_register_bit_set ()) {}
/* Wrong */
while ( is_register_bit_set ());
while ( is_register_bit_set ()) { }
while ( is_register_bit_set ()) {
}
while
(oder for
, do-while
usw.) leer ist (es kann bei eingebetteter Programmierung der Fall sein), verwenden Sie leere Einzelklammern /* Wait for bit to be set in embedded hardware unit */
volatile 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 */
for
, do-while
, while
/* 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 ;
}
}
if
Anweisung nur für die Zuordnung oder Funktionsaufrufvorgänge verwendet werden kann /* OK */
int a = condition ? if_yes : if_no ; /* Assignment */
func_call ( condition ? if_yes : if_no ); /* Function call */
switch ( condition ? if_yes : if_no ) {...} /* OK */
/* Wrong, this code is not well maintenable */
condition ? call_to_function_a () : call_to_function_b ();
/* Rework to have better program flow */
if ( condition ) {
call_to_function_a ();
} else {
call_to_function_b ();
}
case
einzelne Einrückung hinzubreak
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
ein /* OK */
switch ( var ) {
case 0 :
do_job ();
break ;
default :
break ;
}
/* Wrong, default is missing */
switch ( var ) {
case 0 :
do_job ();
break ;
}
break
-Anweisung darin ein.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 ;
}
_
-Zeichen sein, außer wenn sie eindeutig als Funktion markiert sind, die in Zukunft durch die reguläre Funktionssyntax ersetzt werden kann /* OK */
#define SQUARE ( x ) ((x) * (x))
/* Wrong */
#define square ( x ) ((x) * (x))
/* OK */
#define MIN ( x , y ) ((x) < (y) ? (x) : (y))
/* Wrong */
#define MIN ( x , y ) x < y ? x : y
/* 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 ( 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) < (y) ? (x) : (y))
#define SUM ( x , y ) ((x) + (y))
do {} while (0)
Anweisung 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 does the `else` keyword belong?
*
* 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 */
}
}
#ifdef
oder #ifndef
. Verwenden Sie defined()
oder !defined()
stattdessen #ifdef XYZ
/* do something */
#endif /* XYZ */
if/elif/else/endif
-Anweisungen /* OK */
#if defined( XYZ )
/* Do if XYZ defined */
#else /* defined(XYZ) */
/* Do if XYZ not defined */
#endif /* !defined(XYZ) */
/* Wrong */
#if defined( XYZ )
/* Do if XYZ defined */
#else
/* Do if XYZ not defined */
#endif
#if
-Anweisungen ein /* 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) */
Der dokumentierte Code ermöglicht es Doxygen, HTML/PDF/Latex -Ausgabe zu analysieren und zu generieren. Daher ist es sehr wichtig, ihn in einem frühen Stadium des Projekts ordnungsgemäß zu tun.
variables
, functions
und structures/enumerations
für Doxygen, verwenden Sie @
nicht5x4
Leerzeichen ( 5
Registerkarten) von Beginn der Zeile für Text /**
* 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 ;
/**
* 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 */
COLOR_GREEN , /*!< Green color */
COLOR_BLUE , /*!< Blue color */
} point_color_t ;
brief
und alle Parameterdokumentation enthaltenin
out
return
enthalten, wenn sie etwas zurückgibt. Dies gilt nicht für void
note
oder warning
:
Zwischen dem Parameternamen und seiner Beschreibung /**
* 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
die Funktion ein Mitglied der Aufzählung zurückgibt, verwenden /**
* 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 ;
}
NULL
) für Konstanten oder Zahlen /**
* 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 enthalten /**
* 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))
file
und brief
Beschreibung gefolgt von leerer Zeile (bei Verwendung von Doxygen) enthalten. /**
* file template.h
* brief Template include file
*/
/* Here is empty line */
/**
* 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 <[email protected]>
*/
#ifndef
enthaltenC++
-Prüfung enthaltenC++
Überprüfung beiextern
für globale Modulvariablen in der Header -Datei, definieren Sie sie später in der Quelldatei /* 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 */
Fügen Sie niemals .c
-Dateien in eine andere .c
-Datei ein
.c
-Datei sollte zunächst die entsprechende .h
-Datei, später andere, enthalten, sofern nicht anders ausdrücklich erforderlich ist
Fügen Sie keine privaten Erklärungen für Modul in der Header -Datei auf
Beispiel für die Headerdatei (keine Lizenz für ein Beispiel)
/* 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 */
Das Repository wird immer auf. .clang-format
-Datei, eine Eingabekonfiguration für clang-format
-Tool. Es kann nahtlos in die meisten neuesten Techno -IDes integriert werden, einschließlich VSCODE. Formatieren erfolgt dann vor Ort auf jeder Datei speichern.
https://code.visualstudio.com/docs/cpp/cpp-ide#_code-formating
Astyle ist eine großartige Software, die bei der Formatierung des Codes basierend auf der Eingabekonfiguration helfen kann.
Dieses Repository enthält astyle-code-format.cfg
Datei, die mit AStyle
Software verwendet werden kann.
astyle --options="astyle-code-format.cfg" "input_path/*.c,*.h" "input_path2/*.c,*.h"
Die künstlerische Stilkonfiguration ist veraltet und nicht mehr aktualisiert
Das Repository enthält eclipse-ext-kr-format.xml
Datei, die mit Eclipse-basierten Toolchains verwendet werden kann, um Formatieroptionen festzulegen.
Es basiert auf K & R -Formatierer mit Änderungen, um die oben genannten Regeln zu respektieren. Sie können es in Eclipse -Einstellungen, Preferences -> LANGUAGE -> Code Style -> Formatter
-Registerkarte importieren.