This article introduces you to 10 methods for standardizing your C code (reference address http://forum.eepw.com.cn/thread/250025/1 ). 1. avoid unnecessary function calls. Consider the following two functions: void str_print (char * str) {int I; for (I = 0; I <strlen (str ); I ++) {printf ("% c", str [I]) ;}}
Void str_print1 (char * str) {int len; len = strlen (str); for (I = 0; I <len; I ++) {printf ("% c ", str [I]) ;}note that these two functions have similar functions. However, the first function calls the strlen () function multiple times, while the second function calls the strlen () function only once. Therefore, the performance of the second function is significantly better than that of the first function.
2. Avoid unnecessary memory references. We will use two examples to compare and explain this time: int multiply (int * num1, int * num2) {* num1 = * num2; * num1 + = * num2; return * num1;} int multiply1 (int * num1, int * num2) {* num1 = 2 ** num2; return * num1, these two functions have similar functions. The difference is that the first function (1 for reading * num1, 2 for reading * num2 and 2 for writing to * num1) has 5 memory references, in the second function, there are only two memory references (one for reading * num2 and one for writing to * num1 ). Which one do you think is better?
3. Memory saving (memory alignment and fill concept) struct {char c; int I; short s;} str_1;
Struct {char c; short s; int I;} str_2; assume that one character requires 1 byte, and short occupies 2 bytes and int requires 4 bytes of memory. At first, we will think that the structure defined above is the same, so it occupies the same amount of memory. However, str_1 occupies 12 bytes. Does the second structure only need 8 bytes? How is this possible?
Note that in the first structure, 3 different 4 bytes are allocated to three data types, while in the first 4 bytes of the second structure, their char and short can be used, int can be adopted at the 4-byte boundary of the second one (a total of 8 bytes ).
4. Use an unsigned integer instead of an integer. If you know the value, it will always be negative.
Some processors can process unsigned integers faster than signed integers. (This is also a good practice to help self-documenting code ).
5. In a logical condition statement, several items are always on the left. Int x = 4; if (x = 1) {x = x + 2; printf ("% d", x); // Output is 3}
Int x = 4; if (1 = x) {x = x + 2; printf ("% d", x ); // Compilation error} uses the "=" value assignment operator instead of the "=" equal operator, which is a common input error. If the constant item is placed on the left side, a compilation error is generated, allowing you to easily capture your error. Note: "=" is a value assignment operator. If B = 1, the variable B is set to 1. Equal operator "=. If the left side is equal to the right side, true is returned; otherwise, false is returned.
6. replace macro with typedef whenever possible. Of course, sometimes you cannot avoid macro, but typedef is better. Typedef int * INT_PTR; INT_PTR a, B; # define INT_PTR int * INT_PTR a, B; In this macro definition, a is a pointer to an integer, B has only one integer declaration. Use typedef a and B as integer pointers.
7. Make sure that the declaration and definition are static unless you want to call the function from different files. Only static functions are visible to other functions in the same file. It limits other access to internal functions if we want to hide the function from the outside. Now we do not need to create a header file for the internal function. The function is invisible to others.
Static declaration of A function has the following advantages: A) two or more static functions with the same name can be used in different files. B) Reduced compilation consumption because there is no external symbol for processing.
Let's have a better understanding. The following example:/* first_file.c */static int foo (int) {/* Whatever you want to in the function */}/* second_file.c */int foo (int) int main () {foo (); // This is not a valid function call as the function foo can only be called by any other function within first_file.c where it is defined. return 0 ;}
8. Use Memoization to avoid recurrence and repeat calculation and consider the issue of Fibonacci (Fibonacci). The problem of Fibonacci can be solved through a simple recursive method: int fib (n) {if (n = 0 | n = 1) {return 1 ;}else {return fib (n-2) + fib (n-1 );}}
Note: Here, we consider the Fibonacci series starting from 1. Therefore, the series looks like ,...
Note: From the recursive tree, we calculate the fib (3) function twice and the fib (2) function three times. This is the repeated calculation of the same function. If n is very large, the fib <n (I) function increases by I <n. The quick way to solve this problem is to compute the function value once, store it in some places, and calculate it as needed instead of repeating it all the time.
This simple technology is called Memoization and can be used in Recursion to increase the computing speed.
The code of the fibonacci function Memoization should look like the following:
Int calc_fib (int n) {int val [n], I; for (I = 0; I <= n; I ++) {val [I] =-1; // Value of the first n + 1 terms of the fibonacci terms set to-1} val [0] = 1; // Value of fib (0) is set to 1 val [1] = 1; // Value of fib (1) is set to 1 return fib (n, val);} int fib (int n, int * value) {if (value [n]! =-1) {return value [n]; // Using memoization} else {value [n] = fib (n-2, value) + fib (n-1, value); // Computing the fibonacci term} return value [n]; // Returning the value}
Here, the calc_fib (n) function is called by main.
9. To prevent the pointer to an object from being deleted, it becomes a floating pointer. The wild pointer is the uninitialized pointer. Note that the wild pointer does not point to any specific memory location.
Void dangling_example () {int * dp = malloc (sizeof (int ));/*........ */free (dp); // dp is now a dangling pointer dp = NULL; // dp is no longer a dangling pointer}
Void wild_example () {int * ptr; // Uninitialized pointer printf ("% u" \ n ", ptr); printf (" % d ", * ptr );} when encountering these pointers, the program is usually "weird.
10. Always remember to release any memory you allocate to the program. In the above example, if the dp pointer is released (we use the malloc () function call)