slides-Structure-Bit

Download Report

Transcript slides-Structure-Bit

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