C語言程式設計 演算法優化

2021-10-11 11:43:18 字數 2692 閱讀 6125

相信大多數計算機學者或從事與之相關工作的朋友都聽過這麼一句話——演算法是程式的靈魂。從這句話中我們就可以看到演算法在程式設計中的重要性。

簡單來說,演算法(algorithm)是指完成乙個任務所需要的具體步驟和方法。也就是說給定初始狀態或輸入資料,能夠得出所要求或期望的終止狀態或輸出資料。

在乙個c語言程式中,乙個好的演算法可以提高程式執行的效率,盡可能的使用少的硬體資源而完成相同的目的。今天就給大家分享一下怎樣寫出好的演算法,怎麼優化演算法,提高程式執行的效率。

演算法的優化分為全域性優化和區域性優化兩個層次。全域性優化也稱為結構優化,主要是從基本控制結構優化、演算法、資料結構的選擇上考慮;區域性優化即為**優化,包括使用盡量小的資料型別、優化表示式、優化賦值語句、優化函式引數、全域性變數及巨集的使用等內容。

例如,在排序中用快速排序或者堆排序代替插入排序或氣泡排序;用較快的折半查詢代替順序查詢法等,都可以極大地提高程式的執行效率。

例如在一堆隨機存放的數中使用了大量的插入和刪除指令,那麼使用鍊錶要快得多。陣列和指標具有十分密切的關係,一般來說,指標比較靈活簡潔,而陣列比較直觀,容易理解。在許多情況下,可以用指標運算代替陣列,這樣做常常能產生又快又短的**,並且執行速度快,占用空間少。

①巢狀if語句的使用。當if結構中要判斷的並列條件較多的時候,最好將它們拆分成多個if語句結構,然後巢狀在一起,就可以減少不必要的判斷。

②巢狀switch語句的使用。switch語句中的case很多時,為了減少比較次數,可以把大switch語句轉化為巢狀switch語句。把頻率較高的case標號放在乙個switch語句中,而發生頻率較低的case標號則放到另乙個switch語句當中。

③給switch語句中的case排序。根據發生的可能性對case的值排序,最有可能的放在第一位就可以使選擇過程更合理,從而提高了效率。

提高程式效率的核心是對影響**執行速度的關鍵程式段進行優化。在任何程式中,最影響**速度的往往是迴圈結構,特別是多層巢狀的迴圈結構。掌握迴圈優化的的各種實用技術是提高程式效率的關鍵。

常用的迴圈優化技術如下:

①降價策略。通過演算法分析我們知道演算法的事件複雜度主要是由迴圈巢狀的層數決定的,所以,演算法中如果能夠減少迴圈巢狀的層數,如將雙重迴圈改寫成單迴圈,則從事件複雜度上可達到降價的目的。

②加速原理。是指將迴圈體內的選擇結構去掉,則加速迴圈結構的執行效率。

③**外提。是指將迴圈體中與迴圈變數無關的運算提出,並將其放到迴圈之外,以避免每次迴圈過程中的重複操作。

④變換迴圈控制條件。當某迴圈變數在迴圈體中除自身引用外,已不再控制迴圈過程時,可以將其從迴圈中刪去。

⑤合併迴圈。把兩個或兩個以上的迴圈合併放到乙個迴圈裡,這樣會加快速度。使用迴圈雖然簡單,但是使用不當,往往可能帶來很大的效能影響。原則是將問題充分分解為小的迴圈,不在迴圈內的多餘的工作(如賦值、常量計算等),避免死迴圈。還可以考慮將迴圈改為非迴圈來提高效率。

1.使用盡量小的資料型別

能夠使用字元型(char)定義的變數,就不要使用整型(int)變數來定義;能夠使用整型變數定義的變數就不要使用長整型(long int),能不使用浮點型(float)就不要使用浮點型變數。當然,在定義變數後不要超過變數的作用範圍,如果超過變數的範圍賦值,c編譯器並不報錯,但程式執行結果卻錯了,而且這樣的錯誤很難發現。

2.優化表示式

對於乙個表示式中各種運算執行的優先順序不太明確或容易混淆的地方,應當採用圓括號明確指定他們的優先順序。乙個表示式通常不能寫的太複雜,如果表示式太複雜,時間久了,自己也不容易看得懂,不利於以後的維護。

3.使用自增、自減和復合賦值運算子

通常使用自增、自減運算子和復合賦值表示式(如a-=1及a+=1等)都能夠生成高質量的程式**,編譯器通常都能夠生成inc和dec之類的指令,而使用a=a+1或a=a-1之類的指令,有很多c編譯器都會生成二到三個位元組的指令。

4.使用運算量較小(但功能相同)的表示式代替複雜的表示式可以減少運算的強度。例如平方運算:a=pow(b,2.0)優化為:a=b*b。

5.避免浮點運算。c語言中的浮點型float和雙精度型double運算比短整型、整型、長整型運算要慢得多,因此避免浮點運算就非常有必要。

6.優化賦值語句。在**中,若乙個變數經賦值後在後面語句的執行過程中不再引用,則這一賦值語句就稱為無用賦值,可以不用。當賦值語句**現多個已知量的運算時,可以將其合併成乙個值,減少程式執行過程中重複計算的工作量。

7.優化函式引數。在c語言中,呼叫函式的第一步是傳遞引數給暫存器或堆疊。當函式的引數很多時,就要呼叫大量的堆疊空間,開銷會很大。當結構作為函式引數傳遞的內容時,編譯器的第一步操作是把整個結構複製到堆疊,這種情況下堆疊空間的使用會非常大。此外,如果結構作為函式返回值,呼叫程式會把堆疊空間保留,把結構位址傳遞給函式同時呼叫函式,接著把函式返回。最後,呼叫程式需要把堆疊空間清除,並把返回的結構拷貝到第二個結構當中。這樣**和堆疊的開銷就會非常驚人。因此應禁止傳遞結構,一般用結構指標作為函式的引數,來避免這種開銷。

8.巨集的使用

在程式設計過程中,對於經常使用的一些常數,如果將它直接寫到程式中去,一旦常數的數值發生變化,就必須逐個找出程式中所有的常數,並逐一進行修改,這樣必然會降低程式的可維護性。因此,應該採用預處理命令中的巨集定義,而且還可以避免輸入錯誤。

1.程式的優化以不破壞程式的可讀性、可理解性為原則。

2.如果將程式的執行效率納入軟體的整個生命週期來考慮,為提高單個程式的效率而花費大量的開發時間往往得不償失,在下列情況下,程式的優化才有意義。

①首先保證程式的正確性和健壯性,然後才考慮優化。

②嚴重影響效率的程式才值得優化。例如系統反覆呼叫的核心模組,無關大局的模組沒有優化的價值。

c語言程式設計 效能優化

使用巨集定義 在c語言中,巨集是產生內嵌 的唯一方法。對於嵌入式系統而言,為了能達到效能要求,巨集是一種很好的代替函式的方法。寫乙個 標準 巨集min 這個巨集輸入兩個引數並返回較小的乙個 錯誤做法 define min a,b a b a b 正確做法 define min a,b a b a b...

c語言程式設計演算法

1 fibonacci 數列的遞迴演算法的實現。要求 輸入 n 輸出數列第 n 個數列的值。2 fibonacci 數列的非遞迴演算法的實現。要求 輸入 n 輸出數列第 n 個數列的值。3 集合全排列問題的遞迴演算法的實現。要求 輸入陣列 list 輸出陣列 list 相應元素 1 4 的全排列。4...

C語言程式設計概述 C語言簡介 演算法概述

為了讓計算機能夠貫徹執行人的意圖,需要人能與計算機 溝通 而這種 溝通 所需要的語言就是程式語言,使用程式語言所設計的指令的集合就是程式。分析問題 設計演算法 編碼 程式除錯。二進位制 計算機能看懂的語言。計算機只能看懂 010101011010010001 這樣的二進位制 用助記符來表示機器指令的...