天天看點

你知道如何優化你的C語言代碼嗎?(中篇)

作者:曉亮Albert

本篇給您列舉5個C語言的優化案例,并展示未優化前和優化後的代碼。

1.避免重複計算

在某些情況下,某個表達式的值是不變的,但是卻被重複計算了多次,這樣會影響程式的效率。可以将該表達式的值計算一次并存儲在一個變量中,然後在需要使用該表達式的值時直接使用該變量即可。

#include <stdio.h>

int main() {
    int i, sum = 0;

    for (i = 1; i <= 100; i++) {
        sum += i * i;
    }

    printf("%d\n", sum);

    return 0;
}
           

可以将 i * i 計算一次并存儲在一個變量中:

#include <stdio.h>

int main() {
    int i, sum = 0;

    for (i = 1; i <= 100; i++) {
        int square = i * i;
        sum += square;
    }

    printf("%d\n", sum);

    return 0;
}
           

2.減少函數調用次數

函數調用會有一定的開銷,是以如果某個函數會被頻繁調用,可以考慮将其中的某些代碼直接嵌入到調用該函數的地方,減少函數調用次數。

#include <stdio.h>

int max(int a, int b) {
    return a > b ? a : b;
}

int main() {
    int a = 10, b = 20, c = 30;

    int max1 = max(a, b);
    int max2 = max(max1, c);

    printf("%d\n", max2);

    return 0;
}
           

可以将 max 函數的代碼直接嵌入到調用該函數的地方:

#include <stdio.h>

int main() {
    int a = 10, b = 20, c = 30;

    int max1 = a > b ? a : b;
    int max2 = max1 > c ? max1 : c;

    printf("%d\n", max2);

    return 0;
}
           

3.使用更高效的算法

某些問題存在多種算法,不同算法的效率也不同,可以使用效率更高的算法來解決問題。

例如,求斐波那契數列的第 n 項可以使用遞歸算法:

#include <stdio.h>

int fibonacci(int n) {
    if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
}

int main() {
    int n = 40;

    printf("%d\n", fibonacci(n));

    return 0;
}
           

但是,遞歸算法的效率比較低,可以使用循環算法來代替:

#include <stdio.h>

int fibonacci(int n) {
    int a = 0, b = 1, c, i;

    if (n == 0) {
        return a;
    }

  for (i = 2; i <= n; i++)
  {
    c = a + b;
    a = b;
    b = c; 
  }
  return b;
  }

int main() { 
  int n = 40;
   printf("%d\n", fibonacci(n));
	return 0;
 }           

4. 優化循環

在循環中可以進行一些優化,例如:

- 循環的次數是固定的,可以使用 for 循環代替 while 循環;

- 盡量避免在循環中進行重複的計算;

- 在循環中避免使用浮點數運算;

- 使用位運算代替乘除法等運算。

#include <stdio.h>

int main() {
    int i, sum = 0;

    for (i = 1; i <= 100; i++) {
        sum += i;
    }

    printf("%d\n", sum);

    return 0;
}
           

可以使用等差數列求和公式避免重複計算:

#include <stdio.h>

int main() {
    int n = 100;

    int sum = (1 + n) * n / 2;

    printf("%d\n", sum);

    return 0;
}
           

5.使用指針通路數組

使用指針通路數組比使用下标通路數組更高效,因為指針可以直接通路數組中的元素,而不需要進行下标計算。

#include <stdio.h>

int main() {
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i, sum = 0;

    for (i = 0; i < 10; i++) {
        sum += a[i];
    }

    printf("%d\n", sum);

    return 0;
}
           

可以使用指針通路數組:

#include <stdio.h>

int main() {
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *p, *end, sum = 0;

    end = a + 10;
    for (p = a; p < end; p++) {
        sum += *p;
    }

    printf("%d\n", sum);

    return 0;
}           

繼續閱讀