10 ways to make your C program more efficient

Source: Internet
Author: User

This article introduces 10 methods to standardize your C code.
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 the functions of these two functions are similar. 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
This time we will use two examples to compare and explain:
Int multiply (int * num1, int * num2)
{
* Num1 = * num2;
* Num1 + = * num2;
Return * num1;
}
Int multiply1 (int * num1, int * num2)
{
* Num1 = 2 ** num2;
Return * num1;
}
Similarly, 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
}
It is a common input error to replace the equal operator =. 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, and B is only an 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 repeated recursive computation
Considering 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. Avoid hanging pointers and wild pointers
If a pointer pointing to an object has been 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 ).


Author sdtarena

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.