470 likes | 662 Views
程 式寫 作 的 建 議. *開闊的心胸、貼心的設計、需求創造進步。. *沒有人能在課堂上學會寫程式; 就好像不下水永遠學不會游泳。. *停( 想如何解決問題 )、 看( 觀摩別人的程式 )、 聽( 別人的想法 )。. *程式先求正確的執行,再談最佳化。. /* First C program , remark of C and C++ */ #include < stdio.h > // for using printf() #define PI 3.141592653
E N D
程 式寫 作 的 建 議 *開闊的心胸、貼心的設計、需求創造進步。 *沒有人能在課堂上學會寫程式; 就好像不下水永遠學不會游泳。 *停(想如何解決問題)、 看(觀摩別人的程式)、 聽(別人的想法)。 *程式先求正確的執行,再談最佳化。
/*First C program , remark of Cand C++*/ #include<stdio.h>// for using printf() #define PI 3.141592653 void main( ) //Program starts from here ! Remark of C++ { printf(“Hello World !\n”) ; // ‘\n’ : new line } 註解、縮排、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; // 同時宣告多個相同型態的變數,以逗點分隔
各種資料型態的儲值範圍(各系統可能不同) *可使用 sizeof ( ) 來求出資料型態在記憶體中的儲存長度(bytes)。
C /C++語言的資料表示法 10進位數值:與一般數值相同,此為內定的表示法。 8 進位數值:以 數字0開頭的數值。 16 進位數值:以 0x或0X開頭的數值。 (x or X 前為數字0) 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 ) (1000 0000)2 = ( -128 ) (1000 0001)2 = ( -127 ) (1111 1111)2 = ( -1 ) 加 1 符號位元
變數的介紹 變數的宣告: 資料型態變數名稱1, 變數名稱2, ….., 變數名稱n; 例如: charch; // 型態為char,且命名為ch的變數。 intm; int n; 等效於int m, n; // 多個相同型態的變數可以逗點隔開。 floatf = 10.0; // 宣告變數的同時也可以指定初值。 doubled =f * 10.0; // 可以引用之前宣告的變數。 float *ptr, a; 等效於下列兩個指令// 考慮優先順序 float *ptr; floata;
printf (“格式化” [, 參數列] ) • %:表示列印表列資料,至於 • 型態則是在%後面指定. • 1) %d:十進位整數 • 2) %f:浮點數 • 3) %e:10的指數 • 4) %x:16進位(小寫) • %X:16進位(大寫) • 5) %%:印出%符號 • \:格式控制 • 1) \n: new line 換一行 • 2) \” : 印出”符號 • 3) \\: 印出\符號 %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("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()的使用
printf("12345678901234567890\n"); printf("%d\n", k); printf("%2d\n", k); printf("|%-5d|\n", k); printf("%05d\n", k); printf("%+5d\n", k); printf("%4X\n", k); 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; 位址: 存放的資料 //宣告一存放整數資料位址的變數 int *ptr; ptr=&x; // 將x的位址存入ptr 5438 : 10 3721: 5438: &x x 5438 10 變數x在記憶體中的位址. &ptrptr所在的位址 ptr所放的資料 *ptr = x
C / C++ 的 運 算 子 算術運算子:+、-、*、/、%(mod) 關係運算子:>、>=、<、<=、==、!= 位元運算子:&(and)、|(or)、^(xor)、~(not)、 >>(shift to right)、<<(shl) 邏輯運算子:&&(logic 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; a--; --a; 均等效於 a = a - 1; 前置運算與後置運算的差別: ++a:先將變數(a)的值加1後,再參與運算。 a--:先參與運算後,再將變數(a)的值減1。 a=a+1; b=a+5+b; b=b-1; 例如:int a=10, b=20; 1) b=++a+5+b--; 2) a = a++ + 9; 3) b=(b++) + (++a); 4) a=(a--)*(++b); a=11; b=35; a=20; b=20; a=11; b=32; a=209; b=21;
It’s another story in Java. • 各變數的前置運算先作 • 計算此時右邊的結果(暫存) • 接著處理需後置運算的變數 • 最後把 2)得到的結果,代入左邊的變數 a=a+1; k=a+5+b; b=b-1; b=k; 例如:int a=10, b=20; 1) b=++a+5+b--; 2) a = a++ + 9; 3) b=(b++) + (++a); 4) a=(a--)*(++b); a=11; b=36; a=19; b=20; a=11; b=31; a=210; b=21;
if ( 條件式) 敘述Yes; 敘述next; if ( 條件式) 敘述Yes; else敘述No; 敘述next; 條件式 yes 條件式 no yes 敘述Yes no 敘述No 敘述Yes 成立才做 敘述next 敘述next
Ex. if-else statement if ( a>0 ) printf(“a>0\n”); else printf(“a<=0\n”); printf(“next statement”); Ex. if statement if ( a>0 ) printf(“a>0\n”); printf(“next statement”);
if ( 條件式) { 敘述Yes1; 敘述Yes2; } else {敘述No1; 敘述No2; }; 敘述next; 條件式 no yes 敘述No1 敘述Yes1 敘述No2 敘述Yes2 敘述next
條件式 no yes if ( 條件式) { 敘述Yes1; 敘述Yes2; } else 敘述No1; // end if 敘述No2; 敘述next; 敘述No1 敘述Yes1 敘述Yes2 敘述No2 敘述next
這樣對嗎? if ( 條件式1 ) if ( 條件式2 ) { 敘述Yes21; 敘述Yes22; } else 敘述No; 敘述next; 條件式1 no yes 條件式2 yes 敘述No 敘述Yes21 敘述Yes22 else 會與 最近的if配對 敘述next
a!=0 no yes Ex. int a=-1; if ( a!=0 ) if ( a>0 ) printf(“a>0\n”); else printf(“a=0\n”); What is the output ? a>0 yes no printf(“a=0\n”) printf(“a>0\n”) a=0 敘述next
if- else-if………else 條件1 條件2 條件n-1 no no no yes yes yes 敘述1 敘述2 敘述n-1 敘述n 敘述next
Transfer score to grade if ( score>=90 ) printf(“Grade A”); elseif ( score>=80 ) printf(“Grade B”); elseif ( score>=70 ) printf(“Grade C”); elseif ( score>=60 ) printf(“Grade D”) else printf(“Grade E”);
if ( score>=90 ) printf(“Grade A”); elseif ( score>=80 ) printf(“Grade B”); elseif ( score>=70 ) printf(“Grade C”); elseif ( score>=60 ) printf(“Grade D”) else printf(“Grade E”); 對應展開上一頁的if-else的配對關係
for (初值設定; 條件判斷; 條件變換) { ……….. 迴圈內容; }; 敘述next; 祇會做一次 初值設定 條件變換 條件判斷 yes 迴圈內容 Ex. 求1+2+…+n的值 int n, total=0; scanf(“%d”, &n); for (k=1; k<=n; ++k) { total = total+k; } // total+=k; printf(“1+…+%d=%d\n”, n, total); no 敘述next
C/C++ 陣列的宣告與使用範例 (1) • 陣列的宣告: • DataType arrayName[number_of_element]; • Ex. int 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]; • Zero-based: index starting from zero. • 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> // for rand #define random(n)(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) • 如何將兩個變數的內含值交換。 • a=10; b=20; • a = b; ===>a=20; b=20; • b = a; ===>a=20; b=20; • 因為取代的關係,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”; 字串的大小不能改變。可存入較小的字串,但不能超過原先陣列的大小。 例如: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 ( 條件式) { …………. 迴圈內容; }; 敘述next; 條件式 yes 迴圈內容 no 條件成立時 才會做迴圈內容 敘述next total=0; k=1; while ( k<=n ) { total += k; ++k; } 敘述next; 計算1+2+…+n的值
至少做一次 do-while-loop do { …………. 迴圈內容; }; while ( 條件式) ; 敘述next; 迴圈內容 條件式 yes no 敘述next do {printf(“Input your password:”); scanf(“%s”, psword); } while(check(psword) ); 敘述next; 檢查輸入的密碼
switch ( value ) { case v1 : 敘述1; case v2 : 敘述2; ….. case vk : 敘述k; ….. break; default : 敘述n; }; 敘述next; switch ( value ) { case v1 : 敘述1; case v2 : 敘述2; ….. case vk : 敘述k; ….. default : 敘述n; }; 敘述next; value可以是 運算式 有break 當所有情況 都不符合時 可有可無
Ex. switch-case without break value=‘A’; switch (value) { case ‘A’ : printf(“A”); case ‘B’ : printf(“B”); case ‘C’ : printf(“C”); default : printf(“not ABC”); }; 敘述next; value=‘A’ ABCnot ABC value=‘B’ BCnot ABC value=‘C’ Cnot ABC value=‘P’ not ABC
Ex. switch-case with break value=‘A’; switch (value) { case ‘A’ : printf(“A”); break; case ‘B’ : printf(“B”); case ‘C’ : printf(“C”); break; default : printf(“not ABC”); }; 敘述next; value=‘A’ A value=‘B’ BC value=‘C’ C value=‘P’ not ABC
break : 跳出迴圈,至敘述next(迴圈後的下一敘述) continue: 跳至條件變換或條件判斷處 break可用於for-loop, while, do-while, switch continue則用於for-loop, while, do-while while ( a>=1 ) { ………. ….. break; ………. ….. continue; ……... }; next-statement; for (k=1; k<10; ++ k) { ………. ….. break; ………. ….. continue; ……... }; next-statement;
// break case: sum=0; for (n=1; n<=10; ++n) { if ( n==5 ) break; sum+=n; } // continue case sum=0; for (n=1; n<=10; ++n) { if ( n==5) continue; sum+=n; } sum=1+2+3+4=10 sum=1+2+3+4+6+7+8+9+10=50
位元的介紹 bit (binary digit):位元 => 0 or 1 byte = 8 bits:位元組 word = 2 bytes = 16 bits:字組 位 元 的 稱 呼 (與冪次有關)
位元的運算: & | ^ ~ << >> 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設成反相
位元的運算: & | ^ ~ << >> 將A逐位元的反相
位元的運算例子 (1/2) 若 A = 0xD3 = (1101 0011)2 • 將 bit4 設成 0: • A = A & 0xEF; b) 將 bit3 設成10: A = A | 0x08;
位元的運算例子 (2/2) 若 A = 0xD3 = (1101 0011)2 c) 將 high nibble反相 A = A ^ 0xF0; d) 保留 low nibble : A = A & 0x0F;
位元的右、左移 N = 0xA7 N = N>>1 補零 注意!符號位元可能會被改變! N = 0xA7 N = N<<1 補零 *建議位元運算時,資料修飾為unsigned
A>>1:A除以2,並且去餘數。 A<<1:A乘以2,但有可能超過數值的範圍或導致變號。 可利用上述的特性,來加快數值的計算! 例如:a = 5*a; => a = (a<<2)+a; // a=a*4+a;