AaronYang風格 C語言挑講[二][基本類型、運算子和運算式]

來源:互聯網
上載者:User

AaronYang風格就是:不講老生長談的東西,挑主題內難懂的地方細講,其他總結一筆帶過,有口訣教口訣,樣本實踐出來,文章內容充實。

本文原理理解性方面的較多,但是都被我用gif圖片(自己photoshop做的)講解

更底層的東西,我自己都不懂的,不可能拿出來講的

本文是針對有學過其他程式設計語言的來學的,有很多地方我跳過略講,所以這不是一篇入門的文章

我在看C的時候,其實發現了一些挺好玩的東西,比如宏替換,帶符號,不帶符號的類型。C的常量定義也不一樣。

重點講位元運算符的運算,還有逗號運算子

最主要是每個類型佔了多少個位元組的理解,以後最佳化程式可以用到。

要避免不必要的類型轉換

 

精彩預覽:

比如課外知識,很多人知道怎麼去寫編程,但原理知道的很少,知道怎麼用,比如作業系統32位和64位的關於編程方面的區別

這裡講的很容易理解,自己做了些圖片方便理解,如果想直接看,就在本文末最後一節,呵呵

 

 資料類型基本一覽

我學C#的,無符號類型和指標沒怎麼接觸過

其他概念:

開啟程式時候,資料會存在記憶體中(個別可能在寄存器中),我們要對每個資料在記憶體中分配若干個位元組,用於存放資料。資料所佔用的記憶體位元組數稱為該資料的“資料長度”。所以我們要定義不同的資料類型,來安排合適的長度去分配資料存放。於是我們需要資料類型這個概念,不知道有沒有聽懂了

 常量
(一) 整型常量
  • 十進位:平常的數字寫法,0,22,+11,-3
  • 八進位:0開頭的書寫形式,例如00,+08,-033,021
  • 十六進位:0x開頭的書寫形式,例如0x1,-0x121,+0x12,0x21

佔用位元組:一般微型機中佔用2個位元組,不分進位,他們的數值範圍都是十進位的-32768~+32767

長整型常量:範圍 -2147483648~+2147483647,佔用4個位元組。    

                      書寫形式:在整數的末尾加上 l  或者 L           例如: 10L    -011L     +0x15L

那麼其他的都是短整型常量了。如果整型常量後面沒有字母“L”或“l”,而且超過了短整型常量能夠表示的數值範圍,則自動認為該常量是長整型常量了,例如-32769、 32768、40000都是長整型常量了

 

總結: 整型常量分短整型和長整型兩種,又分十進位,八進位,十六進位三種書寫形式,使用時,要注意區分。例如,88和88L,數值一樣,但是它們在記憶體中佔用不同數量的位元組;比如 10,010L,0x10雖然是短整型常量,但是表示的整數值不一樣。

 

 

(二) 實型常量一般形式

               [+ 或者 –]    整數部分      小數點      小數部分

指數形式

               [+ 或者 –]    整數部分      小數點      小數部分  e或者E  [+ 或者 –]  指數(就是普通的整數)

 

       例如 12.345e3      就等於  12.345乘以10的3次方 就是 12345

              12345E-3    就等於 12345乘以10的-3次方 就是12.345

 

總結: 實型常量在一般的微機中佔用4個位元組,數值範圍都是-10的38次方 到 10的38次方,有效數字是7位

            例如: 1.23456789和1.234567是相同的,因為有效數字是7位,所以後兩位是無效的

 

(三) 字元常量

就是char類型了,C語言中,字母區分大小寫,‘a’和‘A’ 是不一樣的

在記憶體中,每個字元常量都佔用一個位元組,具體存放的是該字元對應的ASCII代碼值。例如 ‘a’‘A’ ‘1' ‘%’ ‘\r’ ‘\x3d’在記憶體中的位元組中存放的分別是十進位整數 97     65    49    37    13   61

總結:由於整型常量在記憶體中存放的是整數值,如果其值在0~127之間,C語言規定也可以將其看成一個字元型常量,就是數字當符號使用。例如:整型常量111、70、40可以當做字元常量 ‘o’ ‘F’ ‘(’ 來使用

有個好玩的例子: ‘a’+5 這裡a就會被當做97使用,所以等於結果值102,在C#中我也試過了,也是如此

 

(四) 字串常量

就是字串,在C#中是string定義的

但是C中定義字串不是用string的,以後說吧.

例如“aAbBcCdD” 逸出字元 \

字串長度

    普通的不說了,說點特殊的,例如 “ ”是0,       “\\ABCD\\”是6,     “\101\102\x43\x44”是4

雖然每個字元在記憶體中只佔用1個位元組,但C語言規定,每個字串在記憶體中佔用的位元組數等於字串的長度+1,其中最後一個位元組存放的字元為“Null 字元串”,其值為0,書寫的時常用逸出字元“\0”來表示,在C語言中稱為字串結束標記。例如:字串“AB”和 “A”的長度分別是2和1,但他們在記憶體中分別佔用3和2個位元組,所以 “A”和 ‘A’是不同的,一個佔用2個位元組,一個佔用1個位元組

關於這個在C#是否是這樣的,我不清楚…

 

(五) 符號常量        #define  符號常量  常量

C編譯器將在程式編譯前將所有的符號常量自動替換成對應的常量

變數規範 名字全部用大寫字母

例如  #define PI 3.1415926 效果同於C#的      const double PI=3.1415926

        #define A ‘A’      效果等同於C#的      const char A=‘A’

 

宏定義命令的一般格式如下: #define 宏名  一串符號

宏名就等同於變數名,那個一串符號,你可以理解為對應的值

宏替換就是  把名字替換值,然後進行處理。由於宏替換是在編譯前進行的,所以宏定義命令屬於C語言的”先行編譯命令”

 

基本例子,理解替換的過程

#define PI 3.14159

#define R 10

#define D (R+R)

#define L PI*D

若程式中用到了L

①先替換成 PI*D

②再將PI替換成3.14156、D替換成(R+R),結果就是3.14159*(R+R)

③這裡面還有宏名,再替換R,最後結果就是 3.14159*(10+10)

 

下面是1個特殊的例子:

例子:      #define PI 3.14159

                #define R1 2+3

                #define R2 (2+3)

若求 2*PI*R1的值     宏替換結果是”2*3.14159*2+3”

若求 2*PI*R2的值     宏替換結果是”2*3.14159*(2+3)”

 

 變數
定義模式跟C#基本一樣

類型 變數名=值

類型 變數名

算了,直接舉例子

int i;

float i,j;

unsigned short me;

long a1=11L;

unsigned short a1=0111,a2=0x11;

int i=1,j=2,k;

int i,j,k=10;

char c1=‘A’,c2,c3=‘a’;

 

有名常量的定義(就是C#中的const)

在C#中用   const 類型 名稱定義的,變數規範都是一樣的,名字用全部的大寫字母

C中如下:

const 資料類型符 變數名1=初值,變數名2=初值2   等;

跟C# const一樣

例如 const char FALE='男',FEMALE='女';

一旦定義,程式啟動並執行時候就不許修改了,否則報錯

 

 運算子(跟C#基本一樣,多了幾個,這裡假設你已經學了其他程式設計語言)

運算子感覺最基本的

加 減 乘 除 求餘數   + – * /   %

加號或減號 + -

關係運算子    <   >   <=  >=  ==  !=

還有 就是      !       &&    ||

三元運算子(書中寫的三元,二元都是三目,二目,我不太習慣)     ?  :

其他符號像 賦值=        逗號  ,         數組中的[ ]     其他基本的 括弧 ( )     遞增的 ++   --

運算完賦值相關的+=  -= *=    /=  %=

資料長度運算子(sizeof),這個C#中沒有

關於成員運算子,我們在C#中,都是 對象 點(.)出來對象中的屬性或者方法的,C中用-> 和  .  關於->在PHP中也是用這個的

指標運算子,C#中應該沒有吧(& * + – )

比較難理解的有 位元運算符(例如<<  >> ^ ~ &  |   &=等),其實C#中也有,我們很少用,過一會講解一下這個

 

運算相關的還有  就是 結合性,運算的優先順序 這個概念

我以前在 Javascript講過,語言邏輯都是通用的,那裡講的比較詳細  點擊查看

 

一、基本常見的跳過了

二、長度運算子(sizeof)

開啟C-Free5

sizeof 是C裡面的關鍵字 並非函數,意思是c 所佔的記憶體多少 單位是位元組
getch(); 用此命令可以在啟動並執行的時候,按任意鍵退出 ,如果沒有此命令,螢幕閃一下就沒了(程式結束就退出) 所以看不見結果

等同於C#中的Console.ReadLine();

 

 

 

重點講解一下 位元運算符

編程中: 0代表false,假,1代表true,真,有句口訣,非0即真

 

一、位邏輯運算子

                     使用數目和位置                              物件類型                              結果類型                     結合性

位非 ~              單目首碼                                       整型                                      整型                         自右向左

位與 &             雙目中綴                                       整型                                      整型                         自左向右

位或 |               雙目中綴                                       整型                                      整型                         自左向右

按位加 ^         雙目中綴                                        整型                                      整型                         自左向右

 

關於16進位轉2進位的對照表格

【例一】

設變數定義如下: unsigned short a=0111,b=0x53

先把  a 無符號八進位轉換成二進位:     0000 0000 0100  1001

         b 無符號十六進位轉換成二進位:  0000 0000 0101 0011

①~a  把二進位是0的位置變成1,是1的變成0(對應的二進位就是1111 1111 1011 0110),然後轉換成八進位為0177666,運算後a不變

②a&b,兩兩位對應,有0則0,對應的二進位是(0000 0000 0100 0001),然後轉換成八進位為0101,運算後a不變

③a|b,兩兩位對應,有1則1,對應的二進位是(0000 0000 0101 1011),然後轉換成八進位為0133,運算後a不變

④a^b,兩兩位對應,相異則1,對應的二進位是(0000 0000 0001 1010),然後轉換成八進位為032,運算後a不變

 

 

二、位移位元運算符

                   使用數目和位置                運算規則              物件類型                              結果類型                     結合性

左移 <<             雙目中綴           a<<b.a向左移b位          整型                                      整型                        自左向右

右移 >>             雙目中綴           a>>b.a向右移b位          整型                                      整型                        自左向右

移位時,移出的位元全部丟棄,移出的空位補入的數與 左移還是右移有關

如果是左移,則規定補入的數全部是0,;如果是右移,如果不帶符號,則補入的數全部是0;如果帶符號,則補入的數全部等於原數的最左邊位上的數(即原數的符號位)

 

下面假設a已經是轉換成二進位的,原本本來a=47,現在轉換成了二進位101111

無符號左移,帶符號左移,他們兩個一樣的,我做張圖片示範

 

無符號右移

帶符號右移
帶符號右移(最左邊是0,就補0,最左邊是1,就補1)

移動完後,在將二進位轉換成十進位,這就是位移位元運算符

 

 

三、位自反賦值運算子

      功能類似常用的 +=  -=,運算完了,改變原有的值

主要是這5個: &=      |=      ^=      <<=         >>=

這裡不講了,就是經過位移運算後,改變原有的值,第一部分,第二部分講的都是運算後不改變原有的值

 

 

 

 

 

 運算式(跟C#90%一樣)
  1. 算數運算式
  2. 關聯運算式
  3. 邏輯運算式
  4. 賦值運算式
  5. 逗號運算式
  6. 條件運算式

重點講一下,C#中沒有的 逗號的特殊用法,可以組成逗號運算式

逗號除了聲明變數時 int a,b=10,還有函數參數也是用逗號來間隔的

但是那裡的逗號都不是運算子,在C中,逗號可以是一種運算子。下面我們通過幾個例子學習一下

逗號運算子,用它可以將兩個運算式串連起來。如:

3+5,6+8

稱為逗號運算式,又稱為“順序求值運算子”。逗號運算式的一般形式為

運算式1,運算式,運算式3……運算式n

最終的結果都是以最後一個運算式的值為準,也就是運算式n的值

例如上面一個逗號運算式的值就是6+8,也就是14

 

例一

這裡先算3乘以5等於15,然後把值賦給了a,a等於15了,然後15乘以4,最終整個運算式的值就是60了

例二

C語言表達能力強,其中一個重要方面就在於它的運算式類型豐富,運算子功能強,因而c使用靈活,適應性強

 

 類型轉換的小例子,提醒最佳化(變數=運算式)

C#中有強制轉換和隱式轉換,C也有,自動轉換規則和強制轉換規則,99%和C#一樣

  1. 運算式計算中資料類型的自動轉換規則 :參加運算的各個資料都轉換成資料長度最長的資料類型,然後計算-----”就長不就短“。

    例如:

  2. 運算結果存入變數時資料類型的自動轉換規則 :先將運算結果的資料類型自動轉換成左邊變數的資料類型,然後再賦予該變數-----”就左不就右“。

    例如:

  3. 運算結果的強制性資料類型轉換規則 :跟C#一樣,例如 (int)14.5 即 14

    例如:

  4. 避免轉換的小例子

    例如:

 課外知識

一個位元組等於8個二進位位;即 1byte=8bit

電腦採用二進位的,8=2^3,通常最高位為符號位

  位元系統中,每個0或1就是一個位(bit),位是資料存放區的最小單位。其中8bit就稱為一個位元組(Byte)。電腦中的CPU位元指的是CPU一次能處理的最大位元。例如32位電腦的CPU一次最多能處理32位元據。
  Bit,乃BInary digit(位元)位的縮寫,是數學家John Wilder Tukey提議的術語(可能是1946年提出,但有資料稱1943年就提出了)。這個術語第一次被正式使用,是在香農著名的《資訊理論》,即《通訊的數學理論》(A Mathematical Theory of Communication)論文之第1頁中

所以說64位作業系統,每次讀取的位元更多,所以處理資料更快了,但可能存在相容性的問題下面講一個小題目了

回憶本篇第一部分

short類型的位元組長度2

long類型長度是4

下面用圖片解釋一下

變數b3是4位元組的,存放65536後,對應的二進位位元如下:

將b3的值賦予變數a的時候,b3的4位元組中低16位元據(右邊2位元組)組成的新值就賦予變數a了,最後轉換成十進位顯示,就是0

 
 
 學習總結
  1. 對常量,宏替換,變數 原理性的理解和使用
  2. 資料長度,進位轉換的理解
  3. 位元運算符的理解和使用
  4. 逗號運算子的使用
  5. 佔用位元組數的理解和實踐
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.