C 語言介紹

Download Report

Transcript C 語言介紹

程 式寫 作 的 建 議
*開闊的心胸、貼心的設計、需求創造進步。
*沒有人能在課堂上學會寫好程式;
就好像不下水永遠學不會游泳。
*停(想如何解決問題)、
看(觀摩別人的程式)、
聽(別人的想法)。
*程式先求正確的執行,再談最佳化。
/* First C program , remark of C and C++, many lines allowed */
#include <stdio.h> // for using printf()
#include <stdlib.h>
int main(int argc, char *argv ) // C++ 形式的單行註解。
{
printf(“Hello World !\n”) ; // ‘\n’ : new line
return (0);
}
註解、縮排、include、define、main()、分號、控制碼、
Free-style 、{複合敘述}、void、< >與“ ”的區別
變數的介紹
變數(variable):表示記憶體某一位址內所存放的值。
&(變數):該變數在記憶體中所在的位址。
變數的命名:
可用的字元:0…9、A...Z、a…z、under line(‘_’)。
命名的規則:
1) 變數的第一個字元,必須是底線或字母(A...Z、a…z),餘為可用之字元。
2) 大小寫是不一樣的!(case sensitive)
3) C的保留字 (reserved word or key word) 不可以當成變數名稱。
(*儘可能取有意義的變數名稱)
變數宣告的方式: 資料型態 變數名稱 [,變數名稱] ()
例如: char my_account[20]; // 以底線分開
int
TotalMoney;
// 首字大寫來區分
float javaStyleIdentifier; // Java 命名慣例
double v1, v2, v3; // 同時宣告多個相同型態的變數,變數間以逗點分隔
各種資料型態的儲值範圍(各系統可能不同)
type modifier data type bytes
char
1
unsigned
range
-128 ~ 127
short
long
char
int
int
int
1
4
2
4
0 ~ 255
-2147483648 ~ 2147483647
-32768 ~ 32767
-2147483648 ~ 2147483647
unsigned
unsigned short
unsigned long
int
int
int
4
2
4
0 ~ 4294967295
0 ~ 65535
0 ~ 4294967295
float
double
4
8
3.4E-38 ~ 3.4E+38
1.7E-308 ~ 1.7E+308
*可使用 sizeof ( ) 來求出資料型態在記憶體中的儲存長度(bytes)。
C /C++語言的資料表示法
10進位數值:與一般數值相同,此為內定的表示法。
8 進位數值:以 數字0 開頭的數值。
16 進位數值:以 0x 或0X開頭的數值。(x or X 前為數字0)
為避免產生變數判別上的混淆:
例如:就像是個變數名稱的十六進位數,0xAB,
所以在C/C++中,變數的首字字元不可以是數字。
10進位數值:
12 = (12)10
8 進位數值: 012 = (10)10
16進位數值: 0x12 = (18)10
char 可當成是數值或是ASCII碼為該數值的字元。
C/C++語言中負數的表示法
設數值 x (>0) 為 r 進位,且共有 n 位數:
則(-x)的 r 補數表示法為:
( -x ) => ( rn – x ) = x 的 (r-1)補數 + 1;
x 的 r-1 補數表示法為:
x => ( rn –1) – x
x 的 r 補數的 r 補數 = ( rn – ( rn – x )) = x
例如: (0111 1111)2 = ( 127 )
符號位元
0:正, 1:負
(1000 0000)2 = ( -128 )
(1000 0001)2 = ( -127 )
(1111 1111)2 = ( -1 )
加
1
變數的介紹
變數的宣告:
資料型態 變數名稱1, 變數名稱2, ….., 變數名稱n;
例如:
char ch; // 型態為char,且命名為ch 的變數。
int m;
int n; 等效於 int m, n; // 多個相同型態的變數可以逗點隔開。
float f = 10.0;
// 宣告變數的同時也可以指定初值。
double d =f * 10.0;
// 可以引用之前宣告的變數。
float *ptr, a; 等效於下列兩個指令 // 考慮優先順序
=> float *ptr; // 指標的表示法是緊跟著對應的變數的!
float a;
printf (“格式化” [, 參數列] )
• %:表示列印表列資料,至於
型態則是在%後面指定.
• \:格式控制
1)
2)
3)
4)
1) \n: new line 換一行
2) \” : 印出”符號
3) \\: 印出\符號
%d:十進位整數
%f:浮點數
%e:10的指數
%x:16進位(小寫)
%X:16進位(大寫)
5) %%:印出%符號
%Wd : 指定列印成W位數的整數
%W.Df: 指定總位數為W(含一位
小數點),小數部分為D位
ex.12.345 (%5.2f) ==> 12.35
#include "stdio.h"
#include "conio.h"
void main()
{ char ch=128; //注意其值
float f=123.456;
int k=123;
printf()的使用
printf(“printf testing ....\n");
printf("sizeof( 2 )=%d => int default\n", sizeof(2));
printf("sizeof(1.0)=%d => double default\n", sizeof(1.0));
printf("\\\x5c\"\042%%\045\x25\n");
printf("12345678901234567890\n");
printf("%d %c\n", ch, ch);
printf("%u %u\n", ch, (unsigned char) ch);
printf("12345678901234567890\n");
printf("%d\n", k);
printf("%2d\n", k);
// 當成n(=2)位數
printf("|%-5d|\n", k); // 靠左排列
printf(“%05d\n”, k); // 前方空位補零
printf(“%+5d\n”, k); // 正數前給 + 號
printf("%4X\n", k); // 以16進位表示
printf("12345678901234567890\n");
printf("%f\n", f);
printf("%5.3f\n", f);
printf("|%-8.2f|\n", f);
printf("%08.3f\n", f);
printf("%+8.3f\n", f);
printf("%4.0f\n", f);
}
宣告的變數會有一個地方(位址)存放其所表示型態的值
//宣告一整數變數並設定初值
int x = 10;
位址:
存放的資料
5438 :
10
//宣告一存放整數資料位址的變數
int *ptr;
ptr=&x; // 將x的位址存入ptr
&x
x
3721: 5438
5438:
&ptr
ptr
*ptr = x
ptr所在
的位址
所放的
資料
變數x在
記憶體中
的位址.
10
scanf (“讀取資料的格式” [, &變數名稱] )
int k;
scanf(“%d”, &k);
float ft;
scanf(“%f”, &ft);
double d;
scanf(“%lf”, &d);
char msg[80];
(msg : pointer)
scanf(“%s”, &msg);
scanf(“%s”, msg); //
int hex, oct;
scanf(“%d:%d”, &hex, &oct);
可不加&
(separated by ‘:’, it can be other character)
int hex, oct;
scanf(“%x”, &hex);
(hexadecimal)
scanf(“%o”, &oct);
(octal)
C / C++ 的 運 算 子
算術運算子:+、-、*、/、%(mod)
關係運算子:>、>=、<、<=、==、!=
位元運算子:&(and)、|(or)、^(xor)、~(not)、
>>(shift
邏輯運算子:&&(logic
to right)、<<(shl)
and)、||(logic or)、!(logic not)
條件運算子:?:
遞增、遞減運算子:++、-- (先後有別)
x=++y-x; => 1)y=y+1; 2)x=y-x; (前置)
x=y++-x; => 1)x=y-x; 2)y=y+1; (後置)
C/C++ 運算式的簡寫表示法
a = a + (value);
=> a += (value);
a = a + (expression); => a += (expression);
其中的運算子可以是下述的任一個:
+、-、*、/、%、&、|、^、>>、<<
a &= (expression);
a -= (expression);
a >>= (expression);
a ^= (expression);
…, etc.
條 件 運 算 子 => ?:
(條件判斷式) ? (成立執行此部分) :(不成立執行此部分) ;
例如:
(x>0)?(x=x):(x=-x); //取x的絕對值
(x%2)? printf(“odd”) : printf(“even”);
a = (x>=0)?(100):(50); //a=100 as x>=0;
*C語言中,任何型態的資料,都可以視為數值,即使是指標
存的位址,也能當成是數值來看待。
*在C語言中,條件成立與否或其結果是真或假,是以數值
來表示: 成 立、真、true => 非零值
不成立、假、false =>
零
遞增、遞減運算子:++、-a++; ++a; 均等效於 a = a + 1; or a += 1;
a--;
--a; 均等效於 a = a - 1; or a -= 1;
前置運算與後置運算的差別:
++a:先將變數(a)的值加1後,再參與運算。 a= a+1;
b=
a--:先參與運算後,再將變數(a)的值減1。 a+5+b;
b= b-1;
例如:int a=10, b=20;
解讀規則:
1)先做前置運算
2)計算敘述結果
3)進行後置運算
1) b=++a+5+b--;
a=11; b=35;
2) a = a++ + 9;
a=20; b=20;
3) b=(b++) + (++a);
a=11; b=32;
4) a=(a--)*(++b);
a=209; b=21;
It’s another story in Java.
1) 各變數的前置運算先作
2) 計算此時右邊的結果(暫存)
3) 接著處理需後置運算的變數
4) 最後把 2) 得到的結果,代入左邊的變數
例如:int a=10, b=20;
1) b=++a+5+b--;
a=11; b=36;
2) a = a++ + 9;
a=19; b=20;
3) b=(b++) + (++a);
a=11; b=31;
4) a=(a--)*(++b);
a=210; b=21;
a=a+1;
k=a+5+b;
b=b-1;
b=k;
if ( 條件式 ) 敘述Yes;
if ( 條件式 ) 敘述Yes;
敘述next;
else 敘述No;
敘述next;
條件式
no
敘述next
yes
no
敘述Yes
成立才做
條件式
敘述No
yes
敘述Yes
敘述next
Ex. if statement
if ( a>0 )
Ex. if-else statement
if ( a>0 )
printf(“a>0\n”);
printf(“a>0\n”);
printf(“next statement”);
else printf(“a<=0\n”);
printf(“next statement”);
if (1)
if (0.5)
if (-2)
if (0)
非零值的條件表示成立或 true!
a = 0;
if ( a = 0 ) printf(“a=0”);
if ( a == 0 ) printf(“a=0”);
(邏輯相等是兩個等號!)
複合敘述:
以{}括住將其當成一個敘述。
if ( 條件式 )
{ 敘述Yes1;
敘述Yes2;
}
else
{ 敘述No1;
敘述No2;
};
敘述next;
no
條件式
yes
敘述No1
敘述Yes1
敘述No2
敘述Yes2
敘述next
複合敘述:誤讀敘述。
if ( 條件式 )
no
條件式
yes
{ 敘述Yes1;
敘述Yes2;
敘述No1
敘述Yes1
}
敘述Yes2
else
敘述No1; // end if
敘述No2;
敘述No2
敘述next;
敘述next
no
條件式1
yes
if ( 條件式1 )
條件式2
敘述No
將左邊流程圖以下列
程式表示,這樣對嗎?
yes
{ if ( 條件式2 )
{ 敘述Yes21;
敘述Yes22;
敘述Yes21
} }
敘述Yes22
else 敘述No;
敘述next;
敘述next
else 會與
最近的if配對
程式碼與對應的流程圖
no
是描述左圖的程式碼?
a != 0
int a = -1;
yes
a>0
if ( a != 0 )
if ( a > 0 ) printf(“a>0\n”);
else printf(“a=0\n”);
no
printf(“a=0\n”)
What is the output ?
a=0
敘述next
yes
printf(“a>0\n”)
if- else-if………else => 多個條件選一!
條件1
yes
敘述1
no
條件2
no
yes
條件n-1
no
yes
敘述2
敘述n-1
敘述next
敘述n
if ( score>=90 )
printf(“Grade A”);
else if ( score>=80 )
printf(“Grade B”);
else if ( score>=70 )
printf(“Grade C”);
else if ( score>=60 )
printf(“Grade D”)
else
printf(“Grade E”);
對應展開上一
頁的if-else的
配對關係
Transfer score to grade: if ( score>=90 )
Score Grade
>=90
A
>=80
B
>=70
C
>=60
D
< 60
E
printf(“Grade A”);
else if ( score>=80 )
printf(“Grade B”);
else if ( score>=70 )
printf(“Grade C”);
else if ( score>=60 )
printf(“Grade D”)
else
printf(“Grade E”);
程式碼對齊:
將else 前移。
for 迴圈 (for loop):
1
2
5
4
7
for (初值設定; 條件判斷; 條件變換)
{
3
祇會做一次
……….. 6
迴圈內容;
初值設定
};
條件變換
敘述next;
Ex. 求1+2+…+n的值
條件判斷
int n, total=0;
scanf(“%d”, &n);
no
for (k=1; k<=n; ++k )
{ total = total + k; // or total += k;
}
printf(“1+…+%d=%d\n”, n, total);
敘述next
yes
迴圈內容
C/C++ 陣列的宣告與使用範例 (1)
陣列(array)的宣告:
DataType
Ex. int
arrayName[number_of_element];
aryValue[10];
float myArray[30];
現在我們有了:
aryValue[0],aryValue[1],aryValue[2],aryValue[3],aryValue[4],
aryValue[5],aryValue[6],aryValue[7],aryValue[8],aryValue[9];
1) Zero-based: index starting from zero.
2) To obtain the size of the array,
sizeof(aryName)/sizeof(aryName[0]) => 10
C/C++ 陣列的宣告與使用範例 (2)
宣告陣列並設定初值:
Ex. int aryValue[4] = {5,4,3,8};
=> aryValue[0]=5,
aryValue[1]=4,
aryValue[2]=3,
aryValue[3]=8;
或者甚至不必指定陣列的大小,compiler會根據程式中所設定的
初值個數,自動的算出該陣列的大小來。
Ex. int sameArray[] = {5,4,3,8};
=> sameArray[0]=5, sameArray[1]=4,
sameArray[2]=3, sameArray[3]=8;
另外陣列大小多於設定的初值個數,未指定的部分將被設成零;
Ex. int partAry[5]={1,2,3};
partAry[0]=1, partAry[1]=2, partAry[2]=3,
partAry[3]=0, partAry[4]=0;
C/C++ 陣列的宣告與使用範例 (3)
隨機產生十個浮點數,並找出最大的數。
Ex.
#include <stdlib.h>
#define random(n)
// for rand
(rand() % (n))
// 0 <= random(n) < n, n is an interger.
. . . . .
int value[10], k, max;
value[0] = random(101);
max = value[0];
for (k=1; k<10; ++k)
{ value[k] = random(101);
if ( max < value[k] ) max = value;
}
for (k=0; k<10; ++k)
printf(“value[%d]=%d\n”, k+1, value[k]);
printf(“最大值是:%d\n”, max);
C/C++ 陣列的宣告與使用範例 (4)
如何將兩個變數的內含值交換。
1) a=10; b=20;
a = b; ===> a=20; b=20;
b = a; ===> a=20; b=20;
因為取代的關係,a 的值 10 不見了!
2) a=10; b=20;
//
在程式世界裡,我們需要第三者! ==> temp;
temp = a;
// a=10; b=20; temp=10;
a = b;
// a=20; b=20; temp=10;
b = temp;
// a=10; b=10; temp=10;
3) 隨機產生10個整數存入陣列中,再將其由小到大排列。
C/C++ 陣列的宣告與使用範例 (5)
字元:表示一單獨的字元符號,該字元以單撇號括住。
例如:char ch = ‘A’;
字串:字元的陣列。字串的內容以雙撇號括住,並用‘\0’作為結束。
例如:char str[] = “This is string”;
‘T’
‘h’
‘i’
‘s’
‘’
‘i’
‘s’
‘’
‘s’
‘t’
‘r’
‘i’
‘n’
‘g’
‘\0’
字串的大小不能改變。
可存入較小的字串,但不能超過原先陣列的大小。
例如:char str[] = “This is string”; // or
char str[15] = “This is string”;
ex.
for (int k=14; k>=0; --k)
{ str[k] = 0; // ‘\0’
printf(“%s\n”, str);
}
C/C++ 陣列的宣告與使用範例 (6)
Ex.字元可視為數值或 ASCII 符號。
int k;
char string[10], ch;
ch=‘A’;
string[9]=‘\0’;
// or string[9]=0;
for (k=0; k<9; ++k)
{ string[k]=ch++;
printf(“%c => %d\n”, ch, ch);
}
printf(“%s\n”, string);
printf(“%s\n”, string+3);
while-loop:
while ( 條件式 )
{ ………….
條件式
yes
迴圈內容
迴圈內容;
};
敘述next;
no
敘述next
條件成立時
才會做迴圈內容
total=0; k=1;
while ( k<=n )
{ total += k; ++k; }
敘述next;
計算1+2+…+n的值
至少做一次
do-while-loop:
迴圈內容
do { ………….
迴圈內容;
};
while ( 條件式 ) ;
敘述next;
相當於下列流程:
條件式
迴圈內容;
while ( 條件式 )
{ ………….
迴圈內容;
};
no
敘述next
do { printf(“Input your password:”);
scanf(“%s”, password);
}
while ( check(password) );
敘述next;
檢查輸入的密碼
yes
switch case => 多個條件選一!
switch ( value )
switch ( value )
value可以是
運算式
{
{
case v1 : 敘述1;
case v1 : 敘述1;
case v2 : 敘述2;
case v2 : 敘述2;
…..
…..
case vk : 敘述k;
case vk : 敘述k;
…..
…..
default : 敘述n;
default : 敘述n;
};
敘述next;
當所有情況
都不符合時,
可有可無
};
敘述next;
break;
有break
switch case 與 if- else-if … else 的比較:
都能做多個條件選一,兩者有何差異?
1) switch 中 case 的值必須是類整數型態的;
2) if- else-if … else 則可以使用更彈性的條件判斷式!
Ex. switch-case without break
value=‘A’;
switch (value)
{
case ‘A’ : printf(“A”);
value=‘A’
ABCnot ABC
case ‘B’ : printf(“B”);
value=‘B’
BCnot ABC
case ‘C’ : printf(“C”);
value=‘C’
Cnot ABC
default : printf(“not ABC”);
value=‘P’
not ABC
};
敘述next;
Ex. switch-case with break
value=‘A’;
switch (value)
{
case ‘A’ : printf(“A”);
value=‘A’
A
case ‘B’ : printf(“B”);
value=‘B’
BC
case ‘C’ : printf(“C”);
value=‘C’
C
value=‘P’
not ABC
break;
break;
default : printf(“not ABC”);
};
敘述next;
break : 跳出迴圈,至敘述next(迴圈後的下一敘述)
continue: 跳至 條件變換 或 條件判斷 處
break可用於for-loop, while, do-while, switch
continue 則用於for-loop, while, do-while
for (k=1; k<10; ++ k)
{ ……….
….. break;
……….
….. continue;
……...
};
while ( a>=1 )
{ ……….
….. break;
……….
….. continue;
……...
};
next-statement;
next-statement;
// break case:
sum=0;
for (n=1; n<=10; ++n)
{ if ( n==5 ) break;
sum+=n;
sum=1+2+3+4=10
}
// continue case:
sum=0;
for (n=1; n<=10; ++n)
{ if ( n==5) continue;
sum+=n;
}
sum=1+2+3+4+6+7+8+9+10=50
位元的介紹
bit (binary digit):位元 => 0 or 1
byte = 8 bits: (byte: 位元組)
word = 2 bytes = 16 bits; (word: 字組)
位 元 的 稱 呼 (與冪次有關)
1
0
1
1
0
1
0
1
27
26
25
24
23
22
21
20
bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
位元的運算: & | ^ ~ << >>
&
0
1
0
0
0
1
0
1
|
0
1
0
0
1
1
1
1
^
0
1
0
0
1
1
1
0
0&A=0
具reset的作用
1&A=A
能把bit設成0
0|A=A
具set的作用
1|A=1
能把bit設成1
0^A=A
具inverse的作用
1 ^ A = ~A
能把bit設成反相(0<=>1)
位元的運算: & | ^ ~ << >>
A
0
1
~A 1
0
將A逐位元的反相
XOR (互斥或):
XOR (互斥或):
相等時為 0;不相等時是1
可做簡易的
加密編碼
位元的運算例子 (1/2)
若 A = 0xD3 = (1101 0011)2
a) 將 bit4 設成 0:
1
1
1
0
0
1
1
利用& (and)運算
A = A & 0xEF;
b) 將 bit3 設成1:
0
1
1
1
0
1
1
1
1
1
1
0
1
0
0
1
1
0
0
利用| (or)運算
A = A | 0x08;
0
0
0
0
1
0
位元的運算例子 (2/2)
若 A = 0xD3 = (1101 0011)2
c) 將 high nibble反相:
1
(nibble: 4 bits)
1
1
0
0
1
1
利用^ (xor)運算
A = A ^ 0xF0;
d) 保留 low nibble:
0
1
1
1
1
0
0
0
0
1
1
0
1
0
0
1
1
1
1
利用& (and)運算
A = A & 0x0F;
0
0
0
0
1
1
位元的右、左移
N = 0xA7
1
0
1
0
0
1
1
1
N = N>>1
0
1
0
1
0
0
1
1
補零
N = 0xA7
注意!符號位元可能會被改變!
1
0
1
0
0
1
1
1
0
1
0
0
1
1
1
0
N = N<<1
*建議位元運算時,資料修飾為 unsigned。
補零
A>>1:A除以2,並且去餘數。
A<<1:A乘以2,但有可能超過數值的範圍或導致變號。
可利用上述的特性,來加快數值的計算!
例如:a = 5*a; => a = (a<<2)+a; // a=a*4+a;