色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

幾個實用的C語言知識點

硬件攻城獅 ? 來源:硬件攻城獅 ? 2023-02-15 10:25 ? 次閱讀

一、變量與值得比較

1、布爾變量與零值的比較

不可將布爾變量直接與 TRUE、 FALSE或者 1、 0進行比較 。據布爾類型的語義,零值為“ 假”(記為 FALSE),任何非零值都是“ 真”(記為TRUE)。

TRUE的值究竟是什么并沒有統一的標準。例如 Visual C++ 將 TRUE定義為 1, 而 Visual Basic則將 TRUE定義為-1 。

假設布爾變量名字為 flag,它與零值比較的標準 if語句如下:

if (flag) // 表示flag為真
if (!flag) // 表示flag為假

其它的用法都屬于不良風格,例如:

if (flag == TRUE)
if (flag == 1 )
if (flag == FALSE)
if (flag == 0)

2、整形變量與零值的比較

應當將整型變量用“ ==” 或“ !=” 直接與 0比較 。假設整型變量的名字為 value,它與零值比較的標準 if語句如下:

if (value == 0)
if (value != 0)

不可模仿布爾變量的風格而寫成:

if (value) // 會讓人誤解 value是布爾變量
if (!value)

3、浮點變量與零值的比較

不可將浮點變量用“ ==” 或“ !=” 與任何數字比較 。千萬要留意, 無論是 float還是 double類型的變量, 都有精度限制。

所以一定要避免將浮點變量用“ ==” 或“ !=” 與數字比較,應該設法轉化成“ >=” 或“ <=” 形式。假設浮點變量的名字為 x,應當 將:

if (x == 0.0) // 隱含錯誤的比

轉化為:

if ((x>=-EPSINON) && (x<=EPSINON))

其中 EPSINON是允許的誤差(即精度) 。

4、指針變量與零值的比較

應當將指針變量用“ ==” 或“ !=” 與 NULL比較 。指針變量的零值是“ 空”(記為 NULL)。

盡管 NULL 的值與 0相同,但是兩者意義不同。假設指針變量的名字為 p,它與零值比較的標準 if語句如下:

if (p == NULL) // p與 NULL顯式比較,強調 p是指針變量
if (p != NULL)

不要寫成:

if (p == 0) // 容易讓人誤解 p是整型變量
if (p != 0)

或者:

if (p) // 容易讓人誤解p是布爾變量
if (!p)

二、變量及基本運算

1、整型數

如果我們確定整數非負,就應該使用unsigned int而不是int。

有些處理器處理無符號unsigned 整形數的效率遠遠高于有符號signed整形數(這是一種很好的做法,也有利于代碼具體類型的自解釋)。

因此,在一個緊密循環中,聲明一個int整形變量的最好方法是:

registerunsignedint variable_name;

記住,整形in的運算速度高浮點型float,并且可以被處理器直接完成運算,而不需要借助于FPU(浮點運算單元)或者浮點型運算庫。

盡管這不保證編譯器一定會使用到寄存器存儲變量,也不能保證處理器處理能更高效處理unsigned整型,但這對于所有的編譯器是通用的。

例如在一個計算包中,如果需要結果精確到小數點后兩位,我們可以將其乘以100,然后盡可能晚的把它轉換為浮點型數字。

2、除法和取余數

在標準處理器中,對于分子和分母,一個32位的除法需要使用20至140次循環操作。

除法函數消耗的時間包括一個常量時間加上每一位除法消耗的時間。

Time (numerator / denominator) = C0 + C1* log2 (numerator / denominator)
     = C0 + C1 * (log2 (numerator) - log2 (denominator)).

對于ARM處理器,這個版本需要20+4.3N次循環。這是一個消耗很大的操作,應該盡可能的避免執行。

有時,可以通過乘法表達式來替代除法。例如,假如我們知道b是正數并且b*c是個整數,那么(a/b)>c可以改寫為a>(c*b)

如果確定操作數是無符號unsigned的,使用無符號unsigned除法更好一些,因為它比有符號signed除法效率高。

3、取模的一種替代方法

我們使用取余數操作符來提供算數取模。但有時可以結合使用if語句進行取模操作。考慮如下兩個例子:

uint modulo_func1 (uint count)
{
   return (++count % 60);
}

uint modulo_func2 (uint count)
{
   if (++count >= 60)
      count = 0;
   return (count);
}

優先使用if語句,而不是取余數運算符,因為if語句的執行速度更快。這里注意新版本函數只有在我們知道輸入的count結余0至59時在能正確的工作。

4、使用數組下標

如果你想給一個變量設置一個代表某種意思的字符值,你可能會這樣做:

switch ( queue )
{
case0 :   letter = 'W';
   break;
case1 :   letter = 'S';
   break;
case2 :   letter = 'U';
   break;
}

或者這樣做:

if ( queue == 0 )
  letter = 'W';
elseif ( queue == 1 )
  letter = 'S';
else
  letter = 'U';

一種更簡潔、更快的方法是使用數組下標獲取字符數組的值。如下:

staticchar *classes="WSU";
letter = classes[queue];

5、使用別名

考慮如下的例子:

void func1( int *data )
{
    int i;
 
    for(i=0; i<10; i++)
    {
          anyfunc( *data, i);
    }
}

盡管*data的值可能從未被改變,但編譯器并不知道anyfunc函數不會修改它,所以程序必須在每次使用它的時候從內存中讀取它。如果我們知道變量的值不會被改變,那么就應該使用如下的編碼:

void func1( int *data )
{
    int i;
    int localdata;
 
    localdata = *data;
    for(i=0; i<10; i++)
    {
          anyfunc ( localdata, i);
    }
}

這為編譯器優化代碼提供了條件。

6、局部變量的類型

我們應該盡可能的不使用char和short類型的局部變量。對于char和short類型,編譯器需要在每次賦值的時候將局部變量減少到8或者16位。

這對于有符號變量稱之為有符號擴展,對于無符號變量稱之為零擴展。這些擴展可以通過寄存器左移24或者16位,然后根據有無符號標志右移相同的位數實現,這會消耗兩次計算機指令操作(無符號char類型的零擴展僅需要消耗一次計算機指令)。

可以通過使用int和unsigned int類型的局部變量來避免這樣的移位操作。這對于先加載數據到局部變量,然后處理局部變量數據值這樣的操作非常重要。無論輸入輸出數據是8位或者16位,將它們考慮為32位是值得的。

考慮下面的三個函數:

int wordinc (int a)
{
   return a + 1;
}
short shortinc (short a)
{
    return a + 1;
}
char charinc (char a)
{
    return a + 1;
}

盡管結果均相同,但是第一個程序片段運行速度高于后兩者。

三、循環語句

1、多重循環

在多重循環中, 如果有可能, 應當將最長的循環放在最內層, 最短的循環放在最外層,以減少 CPU 跨切循環層的次數。例如示例 4-4(b)的效率比示例4-4(a)的高 :

3e64f6c4-ac8d-11ed-bfe3-dac502259ad0.png

2、循環體內的判斷

如果循環體內存在邏輯判斷, 并且循環次數很大, 宜將邏輯判斷移到循環體的外面。

示例 4-4(c)的程序比示例 4-4(d)多執行了 N-1次邏輯判斷。并且由于前者老要進行邏輯判斷,打斷了循環“ 流水線” 作業,使得編譯器不能對循環進行優化處理, 降低了效率。

如果N非常大, 最好采用示例 4-4(d)的寫法, 可以提高效率。如果 N非常小,兩者效率差別并不明顯,采用示例 4-4(c)的寫法比較好, 因為程序更加簡潔。

3e7a89a8-ac8d-11ed-bfe3-dac502259ad0.png

3、for 語句的循環控制變量

不可在 for 循環體內修改循環變量,防止 for 循環失去控制 。建議 for語句的循環控制變量的取值采用“ 半開半閉區間” 寫法。

示例 4-5(a)中的 x值屬于半開半閉區間“ 0 =< x < N”,起點到終點的間隔為 N,循環次數為 N。

示例 4-5(b)中的 x值屬于閉區間“ 0 =< x <= N-1”,起點到終點的間隔為 N-1,循環次數為 N。

相比之下,示例 4-5(a)的寫法更加直觀,盡管兩者的功能是相同的 。

3e979cb4-ac8d-11ed-bfe3-dac502259ad0.png

4、更快的for()循環

這是一個簡單而高效的概念。通常,我們編寫for循環代碼如下:

for( i=0;  i<10;  i++){ ... }

i從0循環到9。如果我們不介意循環計數的順序,我們可以這樣寫:

for( i=10; i--; ) { ... }

這樣快的原因是因為它能更快的處理i的值–測試條件是:i是非零的嗎?如果這樣,遞減i的值。對于上面的代碼,處理器需要計算“計算i減去10,其值非負嗎?

如果非負,i遞增并繼續”。簡單的循環卻有很大的不同。這樣,i從9遞減到0,這樣的循環執行速度更快。

這里的語法有點奇怪,但確實合法的。循環中的第三條語句是可選的(無限循環可以寫為for(;;))。如下代碼擁有同樣的效果:

for(i=10; i; i--){}

或者更進一步的:

for(i=10; i!=0; i--){}

這里我們需要記住的是循環必須終止于0(因此,如果在50到80之間循環,這不會起作用),并且循環計數器是遞減的。使用遞增循環計數器的代碼不享有這種優化。

四、指針

我們應該盡可能的使用引用值的方式傳遞結構數據,也就是說使用指針,否則傳遞的數據會被拷貝到棧中,從而降低程序的性能。

函數通過參數接受結構數據的指針,如果我們確定不改變數據的值,我們需要將指針指向的內容定義為常量。例如:

void print_data_of_a_structure ( const Thestruct  *data_pointer)
{
    ...printf contents of the structure...
}

這個示例告訴編譯器函數不會改變外部參數的值(使用const修飾),并且不用在每次訪問時都進行讀取。

同時,確保編譯器限制任何對只讀結構的修改操作從而給予結構數據額外的保護。

五、懶檢測開發

if(a>10 && b=4)這樣的語句中,確保AND表達式的第一部分最可能較快的給出結果(或者最早、最快計算),這樣第二部分便有可能不需要執行。

六、用switch()函數替代if…else…

對于涉及if…else…else…這樣的多條件判斷,例如:

if( val == 1)
    dostuff1();
elseif (val == 2)
    dostuff2();
elseif (val == 3)
    dostuff3();

使用switch可能更快:

switch( val )
{
    case1: dostuff1(); break;

    case2: dostuff2(); break;

    case3: dostuff3(); break;
}

在if()語句中,如果最后一條語句命中,之前的條件都需要被測試執行一次。switch允許我們不做額外的測試。如果必須使用if…else…語句,將最可能執行的放在最前面。

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7608

    瀏覽量

    137112
  • 編譯器
    +關注

    關注

    1

    文章

    1636

    瀏覽量

    49172
  • 變量
    +關注

    關注

    0

    文章

    613

    瀏覽量

    28408

原文標題:幾個實用的 C 語言知識點

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    一些小眾的C語言知識點

    一些小眾的C語言知識點,可能會比較有趣或者怪異,分享給大家看一下。
    發表于 09-26 10:16 ?666次閱讀

    嵌入式C語言知識點總結

    怎么才能做好嵌入式開發?學好C語言吧!今天就來推薦一篇大佬寫的嵌入式C語言知識點總結。
    發表于 09-27 09:53 ?1187次閱讀

    C語言鏈表知識點(2)

    C語言鏈表知識點(2)
    發表于 08-22 10:38 ?335次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>鏈表<b class='flag-5'>知識點</b>(2)

    C51單片機及C語言知識點必備秘籍

      電子發燒友網訊:應廣大電子發燒友網讀者要求,本電子書《C51單片機及C語言知識點必備秘籍》為《單片機關鍵知識點全攻略》單片機系列教程及《
    發表于 07-30 13:59 ?9854次閱讀

    【信盈達】C語言知識點的總結

    、算法說明:學習單片機C一般只需要前9個知識點即可進行產品開發,但要學習嵌入式C還需要要掌握:指針、結構體、鏈表、宏定義等知識點。二、單片機C
    發表于 10-08 14:41

    C語言程序小知識點總結

    C語言總結(stm32嵌入式開發)文章目錄C語言總結(stm32嵌入式開發)c程序小知識點總結1
    發表于 11-05 07:45

    淺談幾個C語言基礎知識點

    文章目錄前言一、位操作二、使用步驟前言這里主要是簡單的復習一下幾個 C 語言基礎知識點,引導那些 C
    發表于 12-09 07:14

    C51語言的基礎知識點實例講解

    本文檔的主要內容詳細介紹的是C51語言的18個基礎知識點實例講解包括了:C51控制語句和C51數組和指針
    發表于 06-04 17:52 ?12次下載
    <b class='flag-5'>C</b>51<b class='flag-5'>語言</b>的基礎<b class='flag-5'>知識點</b>實例講解

    C語言學習入門知識點/干貨

    C語言知識點總結
    的頭像 發表于 07-18 17:54 ?5955次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>學習入門<b class='flag-5'>知識點</b>/干貨

    STM32中重要的C語言知識點總結

    的一些例程中,遇到不懂的C語言知識,再去查相關的知識點,這樣印象才會深刻些。 下面就列出了一些STM32中重要的C
    的頭像 發表于 04-25 16:42 ?2816次閱讀
    STM32中重要的<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>知識點</b>總結

    嵌入式C語言知識點總結

    導讀:怎么做好嵌入式?相信這個問題無論問誰你都會得到一句學好C語言!今天推薦一篇大佬寫的嵌入式C語言知識點總結,非常值得一讀。
    的頭像 發表于 04-13 11:12 ?2728次閱讀

    C語言C++面試知識點總結

    相對而言,C語言C++相關的面試題比較少見,沒有Java方向寫的人那么多,這是一篇 C 語言C
    的頭像 發表于 05-12 14:59 ?1472次閱讀

    C語言C++面試知識點總結

    相對而言,C語言C++相關的面試題比較少見,沒有Java方向寫的人那么多,這是一篇 C 語言C
    的頭像 發表于 05-13 11:59 ?1874次閱讀

    C語言最重要的知識點

    C語言知識點總結.doc
    發表于 02-16 16:37 ?9次下載

    C語言基礎知識點

    C語言是單片機開發中的必備基礎知識,這里就列舉部分STM32學習中會遇見的C 語言基礎知識點
    的頭像 發表于 05-31 09:07 ?962次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>基礎<b class='flag-5'>知識點</b>
    主站蜘蛛池模板: 三级色视频| 九热这里只有精品| 午夜aaaa| 榴莲推广APP网站入口官网| 草莓在线观看| 影音先锋2017av天堂| 四虎影5151毛片在线看| 美女用手扒开粉嫩的屁股| 国产精品自在拍在线播放| 99在线免费观看| 伊人久久精品AV无码一区| 午夜福利合集1000在线| 青青伊人久久| 妹妹我要色| 久久热免费观看视频| 国产色精品久久人妻无码| 超碰97人人做人人爱网站| 4虎影院午夜在线观看| 亚洲呦女专区| 亚洲精品久久YY5099| 偷拍亚洲色自拍| 日本久久道一区二区三区| 女人会操出水图| 麻美ゆま夫の目の前で犯| 久久精品国产午夜伦班片| 好大快用力深一点h视频| 国产精品色无码AV在线观看| 俄罗斯freeⅹ性欧美| yellow日本高清在线| 99午夜高清在线视频在观看| 最近中文字幕2019免费版| 亚洲精品视频免费在线观看| 香蕉59tv视频| 午夜A级理论片左线播放| 翁熄性放纵交换300章| 天天躁日日躁狠狠躁中文字幕老牛 | 男女啪啪久久精品亚洲A| 吉吉影音先锋av资源| 国产亚洲福利在线视频| 嘟嘟嘟WWW在线观看视频高清 | 欧美派对xxxhdparty|