Summary of personal C language programming style, C language programming style
To sum up my personal programming style and the reasons for doing so, I wrote it only to write a unified C language programming specification for the lab. First, I declare that the programming specification I mentioned below is set for myself, not in the C language.
One thing may be separated by 108,000.
Similarly, the quality of Code reflects the level of programmers. In order to enable everyone to develop good programming habits from the very beginning, to create high-quality code, the lab edits this document as a reference for everyone's programming, it is also a hard rule for future programming styles.
For a team, the advantage of developing uniform programming specifications is obvious. A project is usually completed by multiple members. In a project, the code of members in the group is often called to each other. If two people have significantly different programming habits and styles, it will waste a lot of time reading and understanding the code. On the contrary, consistent and good programming specifications make cooperative development easy and efficient.
As we all know, C language is a process-oriented language. That is to say, the programmer must have a precise grasp of each step of the program and know the execution content and results of each program statement. Therefore, code readability is particularly important. Here, it is not only readable to yourself, but also to other people. A piece of code that can only be understood by yourself can be said to be of low value, and such code often does not understand it over time. The highly readable code not only facilitates transplantation and communication, but also brings immeasurable convenience to debugging.
After reading a good piece of code, you will feel a kind of fluency in reading English articles. Although the C language provides a limited number of 32 keywords, the naming of variables, functions, and so on provides greater freedom, which is also the basis for coding. Imagine that if a piece of code has a subject-object structure, even people who do not understand programming can understand the functions of the Code. This is exactly what our code editors are pursuing.
Therefore, write a piece of code, starting from making your code reader a programmer!
I. File Management
Every technical engineer, regardless of hardware and software, should have a pure English drive letter in the computer. Note that I speak English, not pinyin. In this English-only drive letter, of course, it is used to store software, programs, and documents related to various technologies. The content should also be named in English, including subfolders. Other such instant messaging software and game files should be placed in other drive letters. On the one hand, this is to exercise your English skills; on the other hand, it can also avoid many bugs when using foreign software.
Every software should be placed in a separate folder. This facilitates searching and avoids confusion. Because we all know that after each software is complete, it is not just as simple as an exe file. There are usually files with various suffixes that we cannot delete. If tens of thousands of files generated during installation of different software are caught in the eye when you open the D Drive, we believe that everyone will be forced to write a letter in upper case. Therefore, it is necessary to put different software in a separate folder.
Programs Written in different ides should also be stored in an independent folder. In the folder, different projects should also create folders and name them properly and accurately. This will bring great convenience for future search.
When writing program files, many ides need to create a Project and a Workspace, that is, a Workspace. A workspace usually specifies a space (that is, a folder). When the IDE starts, it automatically opens various projects in the space. Therefore, a Workspace can store multiple projects. In this way, we can use the Workspace to manage various projects written in the IDE. The premise is that you have created a Workspace, and the Project is stored in this Workspace.
Each independent Project should be an independent Project. For example, you need to create a Project when you are writing a program for a streaming lamp and a digital tube, instead of a Project, unless your Project uses both a streaming lamp and a digital tube. The advantage of this is that you can accurately obtain the content information of a Project name, without any issue where the program cannot be searched after it has been written for a while.
Ii. Naming rules
First, let's talk about the general naming rules: the names must be in English. It is not because pinyin cannot be used, but because we must be in line with international standards and develop good English writing habits. Second, besides "\/: *?", <> | "Cannot contain letters, underscores, or numbers. If you want to name it flash LED. c, the spaces in the middle should be replaced by underscores (_) and written as flash_LED.c. In addition, necessary numbers can appear in the name.
1. File/folder naming
The file name must be accurate, and the file name must accurately reflect the file content. Write is
All file names must contain lowercase letters, such as keyboard. c.
If there are abbreviations, the words must be capitalized, such as flash_LED.c and UART. c. LEDs are short for Light-Emitting Diode and UART is short for Universal Asynchronous transceiver/Transmitter (Universal Asynchronous transceiver, that is, serial port. For words with common abbreviations, use abbreviations.
The file name should use nouns instead of verbs. If the file content is data collection, it should be named data_collection.c rather than data_collect.c.
2. identifier name
In C language, various identifiers can be defined as variable names, array names, function names, labels, and names of user-defined objects. Ansi c specifies that the identifier must start with a letter or underline and then contain letters, underscores, and numbers.
1) variable naming
All variables are named in lower case. The abbreviations are in upper case, and all nouns are used. You can use adjectives to modify them and use the "_" table for subordination. Because the variable name is the name of a variable, it should be a noun.
Use I, j, and k to control the local cyclic body. For example, for (I = 0; I <100; I ++ ).
The pointer variable starts with "p _" and then points to the content. For example, the pointer to the height variable is named "* p_height ". Please differentiate between pointers and pointer variables on your own.
Use a word to express the meaning of a local variable.
When naming a global variable, first write the name of the module to which it belongs. For example, if a global variable in the sensor file sensor. c Represents the temperature, it is named sensor_temperature. For example, in LCD. c, the global variable that represents the LCD status is named "LCD _status. Because global variables are often called across files, such as not defining the location of variables, it is very troublesome to search when the program is large and IDE does not support one-click location. Even if the IDE supports one-click positioning and a clear name, you can instantly understand the meaning of the variable.
2) array naming
The array names the first letter of each word in upper case, and the other variables are the same.
Readers may wonder why the array name is preceded by a [] symbol, which is significantly different from a variable. In fact, when the array name is used as the real parameter to pass the first address of the array, the [] symbol is often omitted. The array name should be the first address of the array. For example:
Unsigned char string [] = "abcdefg ";
Printf ("% s", string );
In the above Code, string is an 8-Bit Array (why is it 8-bit ?), When using the printf () function output, only the array name is written. Obviously, this method is allowed. At this time, no [] is written. In this case, you cannot instantly know whether the string is a variable or an array, but you need to refer to the previous format controller "% s ". In other functions, there may be no format controllers such as "% s" to help us determine whether the string is an array or a variable. We can only find the declaration or definition of the function to know the answer, reading is seriously affected. Therefore, it is necessary to distinguish between arrays and variables.
3) function naming
The name of a function is an upper-case description of the first letter of each word. The subject is in the form of a primary predicate. The predicate is a verb, the abbreviation is in the upper-case, and the "_" table is used for subordination. The subject is usually the module name, And the predicate is the action that describes the module. Because the function itself is used to execute a series of actions, combined with function parameters, you can express fluent statements. A simple example is a latency function. Defines a ms-level latency function:
Void Delay (unsigned int MS); (this is actually the declaration, the function body does not want to write)
Write during call:
Delay (500 );
Obviously, the latency is 500 ms. If you use another macro definition:
# Define MS500 500
Delay (MS500 );
Is it clearer?
In addition, for example, the serial sending function named UART_TX () is written as follows:
UART_TX (time); (generally, Transmit Data is abbreviated as TXD)
It clearly indicates the serial port sending time data.
For example, if the function for setting the reference value is named REF_Set (), it is written as follows:
REF_Set (current_voltage); (generally, the Reference value is abbreviated as REF)
It clearly indicates that the current voltage is set as the reference value.
Naming of the subject-and-verb formats greatly increases the possibility of code.
Of course, the function name can contain an object if necessary. In this case, the function does not have parameters. For example, if a function is used to display LCD time and time is a global variable, this function does not need a parameter. In this case, it is directly defined as void LCD _Display_Time (void) (in fact, it is a declaration, because no function body is written ).
Won't I be confused with arrays when naming an uppercase letter? Obviously, no, because the function must be followed by "()" In terms of definition, declaration, and call "()".
4) label naming
In hardware programming, labels can be replaced by loops, so they are rarely used. The naming format of the label is basically the same as that of the variable. All lowercase nouns are used, but only one word is used. It is easy to distinguish it from variables because a goto or ":" is added at the time of the label. Besides, it is only a positioning sign, so a word is enough.
5) custom type naming
Custom type naming mainly refers to the new type name defined by typedef, And the type name of the struct type and shared body type (rather than the variable name of this type ).
The new custom type name. Only one word is used and the first letter is capitalized. However, when you define a new type of variable, the naming rules are exactly the same as those of the variable.
See the differences between the new type name and the new type variable.
6) macro definition name
All macro naming Rules use uppercase letters, with no limit to the number of words. You can add numbers and underscores, but cannot start with a number.
Due to the special nature of macro definition, the use of nouns or verbs is not specified. A macro defines a function as a verb, while a macro defines a constant as a noun.
Iii. Expression writing
When writing an expression, the most important thing is clear meaning. Since different operators in the C language have different combinations of order and priority, it is easy to cause ambiguity, that is, the actual operation order is different from the hypothetical operation order. In addition to fully understanding and memorizing the combination of order and priority, the simplest method is to use parentheses to clarify the order of operation-in an expression, parentheses have the highest priority.
In addition, there must be spaces between operators and their operands. For example:
A = a + B;
Should be written:
A = a + B;
This will make the expressions appear less crowded and increase readability, but this is not the focus. The focus of this is to help us avoid many unrecognized errors. For example:
A = a/* B;
Our intention is to divide a by the content pointed to by the pointer variable B, and then assign the quotient to. However, the cruel reality is that the compiler finds the connected "/*", which is a annotator. Therefore, the subsequent content will be commented out until the latest "*/" is found.
Therefore, we should write:
A = a/* B; // the pointer operator * should keep up with the pointer variable B
Or:
A = a/(* B); // even if this is the case, spaces should be added for ease of reading.
Some people will say that the current IDE will use different colors to prompt the comment content, so such errors should not appear. But what I want to say is that, as a qualified engineer, will you allow yourself to have less rigorous habits? Moreover, our document aims to develop a programming specification based on the C language syntax and lexical structure.
In addition, some earlier versions of C compilers allow the use of = + to replace the meaning of + =, that is, the two signed sequences of compound assignment numbers can be reversed. In this case, if you write:
A =-1;
The intention is to assign-1 to a, but the compiler will understand it:
A = a-1;
Obviously, the meaning has completely changed.
Some people will say that you are not saying that the C compiler of the old version is okay if I don't need it. However, we should never allow this idea to consider code portability.
Therefore, when writing expressions, do not ignore your spaces and parentheses.
It is worth noting that the two operators of the compound assignment operator cannot be separated. For example, "+ =" cannot be written as "+ = ".
Iv. File writing
1. File Division
A simple program contains only a few lines to dozens of lines, which is clearly displayed in a file. However, a large project may contain thousands of lines of code, and millions of lines of large program code. The code of this scale is stored in a file, so you can imagine it as scary.
When a function has more than dozens of lines of code, consider whether it is possible to extract some of the Code into another function and then call it. Similarly, when the Code volume of a file exceeds several hundred lines, you should consider whether it is possible to split some functions into other files. This is done for the readability and convenience of the program. After all, it is much easier to test a short function than to test a long function.
However, a better division of files should be based on modules. Of course, the function should be divided by function. That is to say, a file stores the content of a module, and a function completes a single function.
2. File Content
There are two types of files for C programming. One is the source file (with the suffix. c) and the other is the header file (with the suffix. h ).
C language compilation is based on c files. Therefore, it is impossible to compile only H files. Depending on the project size, a project can be composed of a single c file or multiple c files and H files.
The C language compiler usually goes through the following steps during compilation:
Preprocessing → syntax, lexical analysis → compilation → Assembly → link.
In the preprocessing phase, the content of the c file is modified according to the preprocessing command. The pre-processing Commands include macro definition (# define), Conditional compilation commands (# ifdef, # ifndef, # endif, etc.), and header file inclusion commands (# include), special symbols (LINE, FILE, etc ). For header file containing commands, its function is to replace the content in the contained H file with the containing command. Of course, if there are other preprocessing commands in the content, it will also be processed accordingly.
Therefore, the H file is inserted into the c file during compilation. It can be seen that the H file can contain any content that conforms to the c language syntax, but in actual programming, we obviously won't do this, because this will lose the meaning of distinguishing the c file and the H file.
H files are used as external interfaces and play a significant role in publishing library files. That is to say, the content of the H file is used to provide the function prototype and variable for other files or function calls. The following describes the content that should appear in file c and file h:
Source file (. c) |
Header file (. h) |
Header file containing commands (# include) |
Header file containing commands (# include) |
|
Macro definition (# define) |
All function definitions (must have a function body, that is {}) Internal function declaration (static, no function body) |
External function declaration (extern, no function body) |
External variable definition (initial values must be assigned) Static external variable definition (static, initial values must be assigned) |
External variable Declaration (extern, cannot be assigned a value) |
|
Custom type (typedef) |
External array Definition Static internal array definition (static) |
External array declaration (const) |
Conditional compilation |
Conditional compilation |
As can be seen from the table above, the H file memory is placed with declarations of externally visible variables and function arrays, and the macro definition is available for both internal and external use. When defining external variables, arrays, and functions, you do not need to write extern, because the default extern is missing. When declaring external variables, arrays, and functions, extern must be used for explicit declaration to make the code more intuitive.
The function description must be written. The function Entry, Exit parameters, functions, and other descriptions can be written to facilitate code maintenance and rewriting.
Generally, if all the H files are external interfaces, and the corresponding functions in the c file do not call other content in this file (variables, functions, etc ), you do not need to include your own H files.
In addition, the indentation should be standardized during programming, and the hierarchy should be able to express. It is Indented by four characters at a time and cannot be indented at will.
There are two common formats for using the {} format for function bodies or combined statements:
Int main (){
}
Or:
Int main ()
{
}
I prefer the first one, because it can save the number of rows and compact the program. However, some people think that the first one is not as hierarchical as the second one. Therefore, let the two methods coexist. Because other problems do not involve aesthetic habits, we only need to make good regulations for everyone to execute. After all, this involves the aesthetic differences of everyone.
In the H file, you must write Conditional compilation at the beginning and end:
# Ifndef _ full capital file name _ H _ (or written as: full capital file name _ H __)
# Ifndef _ full capital file name _ H __
... (File Content)
# Enif
This is done to prevent multiple inclusion and ensure that the header file has been replaced before compilation, and will not be replaced later. Otherwise, some content may be defined repeatedly.
The following code is used as an example:
<Protocol. h>:(EveryHFile must contain√Content)
# Include <javasx14x. h> // header file inclusion
# Ifndef_ PROTOCOL_H _ // Conditional compilation √
# Define_ PROTOCOL_H _ // Conditional compilation √
// # Define MONITOR_TERMINAL // Conditional compilation
# DefineMONITOR_NODE1 // Conditional compilation
// # Define MONITOR_NODE2 // Conditional compilation
# DefineMATCHING_CODE 0x55 // macro definition
# DefineHOST_ADDRESS 0x40 // macro definition
# DefineNODE_1 0x41 // macro definition
# DefineNODE_2 0x42 // macro definition
Typedef Struct{// Custom type
FloatStart_bit;
FloatTXD_data;
FloatStop_bit;
} TX_Data;
Extern Unsigned CharTx_Data_Packet []; // external array declaration
Extern Unsigned CharRx_Data_Packet []; // external array declaration
Extern Unsigned CharProtocol_set_flag; // external variable Declaration
Extern Unsigned Char Extract_Data(Void); // External function declaration
# Endif// Conditional compilation √
<Protocol. c>:
# Include<Math. h>// The header file is included, and the system library function is used <>
# Include"Protocol. h"// The header file is included, and the system library function uses ""
Static unsigned Char Easy_delay(Void); // Internal function declaration
Unsigned CharProtocol_set_flag = 0; // external variable definition
Unsigned CharTx_Data_Packet [6] = {'0', '1', '2', '3', '4', '5'}; // external array Definition
UnsignedCharRx_Data_Packet [6] = {'0', '1', '2', '3', '4', '5'}; // external array Definition
Static charTemp_Packet [6] = {'0', '1', '2', '3', '4', '5'}; // static external array definition, only available in this file
/*************************************** *****************
*NameName:Extract_Data ()
*MeritYes: extract the received data frame.
*Entry parameter: None
*Exit parameters:1-Successful,0-Failed
*DescriptionMing:
**************************************** ****************/
Unsigned Char Extract_Data(Void){
Unsigned CharTemp = 0;
Temp =Rx_1_o_readchar();
If(Temp = MATCHING_CODE ){
UART_TX_OPEN();
Rx_Data_Packet [0] = temp;
Rx_Data_Packet [1] =Rx_1_o_readchar(); // Source
Rx_Data_Packet [2] =Rx_1_o_readchar(); // Destination
Rx_Data_Packet [3] =Rx_1_o_readchar(); // Illumination + high temperature
Rx_Data_Packet [4] =Rx_1_o_readchar(); // Low Temperature
Rx_Data_Packet [5] = '\ 0 ';
Return(1 );
}
Else Return(0 );
} // External function definition, which must be described earlier
/*************************************** *****************
*NameName:Easy_delay ()
*MeritYes:Simple latency
*Entry parameter: None
*Exit parameter: None
*DescriptionMing:
**************************************** ****************/
Static unsigned Char Easy_delay(Void){
Unsigned IntI = 0;
For (I = 0; I <1000; I ++ );
} // Internal function definition. You must write the function description before and declare it at the front of this document for reading.
These two files are all captured from the code that the editor once wrote. Some files are added to the demo content and do not exist in the source code. Please do not care about the details, the key points are to understand the content that should appear in the two files, which will be described in a comment later.
Notice:
Many characters that appear in this article can be used in both Chinese and English input methods for aesthetic and intuition, or multiple spaces are added. When programming, you should remember to use the English half-width input method. No matter how many spaces or tabs You add, the compiler will process them one by one.