Structure and Bit Operation
description
Transcript of Structure and Bit Operation
Structure and Bit Operation
C Structures
• Structures 是多個相關的變數的集合,用一個共同的名稱來統稱。
• 譬如要描述平面上的點座標,可以用int x, y;
• 若使用 structures 則可以自定一個叫做t_point 的資料型態,寫成
C Structures(Cont.)
宣告過 structure 之後可以用它來定義變數所以 pt 會包含 x 和 y 兩個 members ,要設定或更改 members 的內容,最直接的方式是使用 member operator “.” 來存取。
○1
○1 ○2
○2
C Structures(Cont.)
• 已經宣告過的 structure 可以再拿來宣告另一個structure 。
• 然後用它來產生變數以及存取 members 。
, ,. . . .
使用 C Structures 來做運算• Structures 的運算可以自己寫 functions
來達到我們想要的功能。• 下面為自定 function 之範例。
• makePoint 與 midPoint 為兩自定 function 。• makePoint 設定點的 x,y 座標, midPoint 為取兩點之中點。• 在主程式裡呼叫 makePoint() 來設定 struct t_point 變數。• mpt 即為 pt1 和 pt2 的中點。
範例 6-1
Structures 參數的傳遞方式• 傳遞 structure 變數到 function ,會用 call-
by-value 方式,所以在 function 裡改變structure 的 members 的值,並不會影響外部的 structure 變數的內容。
• Structures 同樣可以用指標方式來達到 call-by-reference 的效果,通常用傳遞指標的方式會比傳遞整個 structure 來得有效率 (call-by-value 需要複製整個 structure 變數的內容 ) 。
Structures 參數的傳遞方式(Cont.)
• C 提供 typedef 來讓我們宣告新的型別名稱,這樣接下來宣告變數會比較方便。
• 原本產生變數必須使用
• 現在只要用 Point pt;
Structures 參數的傳遞方式(Cont.)
• 所以現在宣告一個指到 struct t_point 的指標可以用
• 把 pp 指到 pt 就和一般變數一樣,要使用 & 來取得structure 的位址
• 透過指標來存取 structure 的 members 有兩種寫法,一種是用標準的 * 先找到指標指的內容,再用“ .” 來取出 member
• 另一種則是用 -> 符號,相當於上面的縮寫
Structures 陣列• 陣列的使用更能說明 structures 的必要性。• 以 struct t_point 為例,要產生 100
個平面上的點來記錄 100 組座標 :• 不使用 structure 要寫成
• 使用 structure 變成
複製 structure members 的值
• 此範例為複製所有structure members 的值,將 a 的座標位置assign 給 b 。
範例 6-6
Structure與指標的應用
Structure參數含有指標• 下面的例子中的 t_point structure 內含有一
個指標 x ,此範例將 link.x 指向陣列 A ,代表 link.x 現在指在陣列 A 的開始位址。
輸出 : arrayA : 0x22FDA0link.x : 0x22FDA0
(每次配置的位址不見得會一樣,此輸出僅供參考。 )
範例 6-2
利用指標指向 structure參數位址• 此範例例用一個指標指向
structure 的參數 a 的位址。• 再利用 ptr=ptr+1 使指標指向
下一個參數 b 的位址。
輸出 : pointer 指向 :apointer 指向 :b
範例 6-3
Structure的衍生- union與enum
Union
• 除了 structures 之外, C 還提供另一種衍伸型別 unions ,讓我們用同一塊區域來儲存不同類型的資料
• 例如 :
Union(Cont.)
• 用這樣方式產生的變數 u 會有剛好足夠的空間來儲存 int、 float、 char* 三種型別中最大的型別資料。
• 變數 u 每次只能儲存三種型別資料中的一種。• 執行下面的程式,就會對 union 的作用更了解。
範例 6-4
Enum
• Enum 型別用來將一串列舉資料用常數表示。• 預設型別中的資料代號從 0 開始依序遞增。• 另外,也可以自己設定資料的代號。• 以此為例 :• A=0,B=1,C=2,D=3,E=4• 自行設定 :• A=1,B=2,C=2,D=3,E=4
Enum(Cont.)
• 此範例將星球按照離太陽距離排序以 enum型別存好,並將 Mars 與 Earth 拿來比較距離太陽之遠近。
輸出 : Mars is farther from the Sun than Earth is.
參考: http://crasseux.com/books/ctutorial/enum.html
範例 6-5
Bitwise Operations and
Operator Precedence
AND, OR, XOR
AND: & OR: | XOR: ^
執行結果a & b = 0x5a | b = 0xFFa ^ b = 0xFA
AND a = 01010101 b = 10101111 00000101
OR a = 01010101 b = 10101111 11111111
XOR a = 01010101 b = 10101111 11111010
NOT
NOT: ~
a = 0000 0000 0000 0000 0000 0000 0101 0101 !a = 1111 1111 1111 1111 1111 1111 1010 1010執行結果~a = 0xFFFFFFAA
Bit shifts
左移運算子 (<<): 向左移 n 個位元 右移運算子 (>>): 向右移 n 個位元
執行結果a << 1 = 0xAAa >> 4 = 0x5
a = 01010101>> 4 00000101
a = 01010101<< 1 10101010
邏輯運算子 做執行流程控制時,條件判斷使用 僅有 True, False 兩種結果,分別以 1 與 0 表
示 在 C 語言中 0 為 False, 非 0 為 True
運算子 功能 用法&& AND a > b && a <
c
|| OR a > b || a < c
! NOT !(a>b)
邏輯運算子範例 a = 1 b = 2 c = 3
執行結果a>b && b<c: 0a>b || b<c: 1!(a>b): 1
條件運算子 條件運算子 (?:) 可藉由判斷式的真假值,來回傳指定的值 C 語言中唯一的三元運算子 語法 : 判斷式 ? 結果為真的值 : 結果為假的
值
= 執行結果n = -1
運算子優先序
運算式• 運算式裡分別有運算子及運算元。• 在做運算時,首先要區別出運算子及運算
元,再依據運算子之優先順序做運算。• 計算時可用括號隔開每個需要計算之計算
子,以分辨計算之優先順序。• 下面將以簡表列出常見之運算之優先順序。• 最後一頁會附上所有 C 語言遇到之運算子
的優先順序。
優先序簡表
• 同優先順序之細分請參見最後一頁的附錄。
優先順序 運算子 敘述 結合性
1 "( ) [ ] { }" " . ->", " " " "括號類 , 物件存取、指標存取 ( )左結合 由左至右
"++ --" " "遞增、遞減 ( ) ( )左結合 由左至右 、右結合 由右至左
"+ -" "~" "!" "* &", , , " " " " "not" "正負號 , 一補數 , , 指標之參照、參考(derefereance address-of)"、
( )右結合 由右至左
3 "* / %" " "乘法、除法、餘數4 "+ -" " "加法、減法5 ">> <<" " "位元右移、左移6 "> <" ">= <=", " " " "大於、小於 , 大於等於、小於等於7 "== !=" " "比較相等、不相等8 "& | ̂ " " and or xor"位元運算之 、 、9 "&& ||" " and or"邏輯判斷之 、10 "?:" " "三元條件運算式11 "=" " "賦值 ( )右結合 由右至左
2
( )左結合 由左至右
運算子分類• 算術運算子: + 、 - 、 * 、 / 、 % 、 +
+ 、 --• 關係運算子: > 、 < 、 == 、 >= 、
<= 、 !=• 邏輯運算子: && 、 || 、 !• 位元運算子:
& 、 | 、 ~ 、 ^ 、 << 、 >>• 除左移與右移以外,一般的優先順序為:
算術 > 關係 > 位元 > 邏輯
範例 1
• 輸出結果: S=75
• 運算元優先順序:* + |
• 運算式分解 :S=((a+(b*c))|d)
範例 2
• 輸出結果:S=1
• 運算式分解 :S=a && (b-c) || d
範例 3
• 輸出結果 :S=24
• 運算式分解 :S=-a*b+c&d%e|*f-g<<2
S=(((((-a)*b)+c)&(d%e))|(((*f)-g)<<2))
範例 3(Cont.)
• 此為上例之運算優先順序二元樹。
複合指定運算子• += 、 -= 、 *= 、 /= 、 %= 、 <<= 、
>>= 、 &= 、 ^= 、 |=• 複合指定運算子為右結合• 複合指定運算子之運算式例子:• a+=b a=a+b;• 下面為複合指定運算子及一般運算子之混
合範例
範例 1
• 輸出結果:S=-5
• 運算式分解:S=(S+(a-(b*c)))
範例 2
• 輸出結果:S=15
• 由於複合指定運算子為右結合,所以運算式計算順序為:
1. c=c%52. b=b*c3. a=a|b4. S=S+a
範例練習• a=5,b=12,c=6,d=8,e=7,f=9,S=11. S=a+b/c&d<<2|e%f , S=?
Ans:72. S*=a-b<<c|d*e+f , S=?
Ans:-8943. S^=a+b|c%d*e , S=?
Ans:57
Appendix
附錄優先順序 運算子 敘述 範例 結合性
-- 字尾遞減 i--{} 組合 {i++;a*=i;}() 函式呼叫或變數初始化 c_tor(int x, int y) : _x(x), _y(y * 10) {}[] 陣列存取 array[4] = 2;. 以物件方式存取成員 obj.age = 34;
++ 字首遞增 ++i-- 字首遞減 --i+ 一元正號 int i = +1;- 一元負號 int i = -1;! 邏輯非not !的備用拼寫~ 按位取反compl ~的備用拼寫(type) 強制型別轉換 int i = (int)floatNum;* 參照 int data = *intPtr;& 取某某的位址(參考) int *intPtr = &data;
size_t s = sizeof(int);
1
++ 字尾遞增 i++
-> 以指標方式存取成員 ptr->age = 34;
由左至右
2 由右至左
if (!done) …
flag1 = ~flag2;
sizeof 某某的大小
附錄優先順序 運算子 敘述 範例 結合性
/ 除法 float f = 10.0 / 3.0;% 模數(取余) int rem = 4 % 3;+ 加法 int i = 2 + 3;- 減法 int i = 5 - 1;<< 位元左移 int flags = 33 << 1;>> 位元右移 int flags = 33 >> 1;< 小於關聯 if (i < 42) …<= 小於等於關聯 if (i <= 42) ...> 大於關聯 if (i > 42) …>= 大於等於關聯 if (i >= 42) ...== 等於關聯eq ==的備用拼寫!= 不等於關聯not_eq !=的備用拼寫& 位元 ANDbitand &的備用拼寫^ 位元 XOR(獨佔or)xor ^的備用拼寫
| 位元 OR(包含or)
bitor |的備用拼寫
&& 邏輯 AND
and &&的備用拼寫|| 邏輯 ORor ||的備用拼寫
3
* 乘法 int i = 2 * 4;
12 if (conditionA || conditionB) ...
10 flag1 = flag2 | 42;
11 if (conditionA && conditionB) …
8 flag1 = flag2 & 42;
9 flag1 = flag2 ̂42;
由左至右
4
5
6
7
if (i == 42) ...
if (i != 42) …
附錄優先順序 運算子 敘述 範例 結合性
13 c?t:f 三元條件運算 int i = a > b ? a : b;= 直接賦值 int a = b;+= 以和賦值 a += 3;-= 以差賦值 b -= 4;*= 以乘賦值 a *= 5;/= 以除賦值 a /= 2;%= 以取餘數賦值 a %= 3;<<= 以位元左移賦值 flags <<= 2;>>= 以位元右移賦值 flags >>= 2;&= 以位元AND賦值and_eq &=的備用拼寫^= 以位元XOR賦值xor_eq ^=的備用拼寫|= 以位元OR賦值or_eq |=的備用拼寫
15 , 迴圈評估運算 for (i = 0, j = 0; i < 10; i++, j++) … 由左至右
由右至左14
flags &= new_flags;
flags =̂ new_flags;
flags |= new_flags;
END