買不起iPhone4,只能弄了一台iTouch4,想嘗試一下iOS上的開發,雖然有monoTouch可用,但是這東西要399美金授權,換成RMB好幾千塊了,算了,為了省錢,還是老老實實複習C 吧,然後升級到Objective-C。
1.1 在你自己的系統中運行“hello, world”程式。再有意去掉程式中的部分內容,看看會得到什麼出錯資訊。
#include <stdio.h> //雖然預設已經包括了stdio.h,但還是建議加上,以保證代碼結構清晰 //main函數總是返回int,雖然這個int不是必須,但是建議加上,以養成良好的習慣 int main(void){ printf("hello, world\n"); system("pause");//暫停,否則程式一閃而過(相當於c#中的Console.Read()) return 0; //明確給出傳回值,雖然可省略,但是建議寫上,main函數也需要向運行環境傳回值 }
1.2 做個實驗,當printf 函數的參數字串中包含\c(其中c 是上面的逸出字元序列中未曾列出的某一個字元)時,觀察一下會出現什麼情況。
#include <stdio.h> int main(void){ //註:建議使用標準的逸出字元(\n,\t,\b,\",\\之類),如果使用非標準的逸出字元,結果將變得不可預期(比如下面的\a,\f,\r,\v 之類) printf("\\Audible or visual alert. \a\n"); printf("Form feed. \f\n"); printf("This escape, \r, moves the active position to the initial position of the current line.\n"); printf("Vertical tab \v is tricky, as its behaviour is unspecified under certain conditions.\n"); system("pause"); return 0;}
1.3 修改溫度轉換程式,使之能在轉換表的頂部列印一個標題。
#include <stdio.h>int main(void){ printf("%2.1f",1.234); float fahr,celsius; int lower,upper,step; lower = 0; upper = 300; step = 20; printf("華氏溫度\t攝氏溫度\n"); fahr = lower; while(fahr <= upper){ celsius = (5.0/9) * (fahr - 32.0);//註:5/9最終的結果為int型,即0;而5.0/9結果為float型(int型9會自動轉化為float) printf("%8.0f\t%8.1f\n",fahr,celsius);//註:%8.1f表示 不算小數點,總共佔8位,其中小數位為1位 fahr += step; } system("pause"); return 0;}
1.4 編寫一個程式列印攝氏溫度轉換為相應華氏溫度的轉換表。
#include <stdio.h>int main(void){ float fahr, celsius; int lower=0, upper=300, step=20; printf("攝氏溫度\t華氏溫度\n"); celsius = lower; while(celsius <= upper){ fahr = (9.0/5.0) * celsius + 32.0; printf("%8.0f\t%7.1f\n", celsius, fahr); celsius = celsius + step; } system("pause"); return 0;}
1.5 修改溫度轉換程式,要求以逆序(即按照從300 度到0 度的順序)列印溫度轉換表
#include <stdio.h>int main(void){ float fahr, celsius; int lower=0, upper=300, step=20; printf("攝氏溫度\t華氏溫度\n"); for(celsius=upper;celsius>=lower;celsius-=step) { fahr = (9.0/5.0) * celsius + 32.0; printf("%8.0f\t%7.1f\n", celsius, fahr); } system("pause"); return 0;}
1.6 驗證運算式getchar() != EOF的值是0還是1。
#include <stdio.h> int main(void){ printf("隨便按個鍵,Ctrl+D或Ctrl+Z代表EOF\n"); printf("運算式 getchar() != EOF 的值為 %d\n", getchar()!= EOF); system("pause"); return 0;}
1.7 編寫一個列印EOF值的程式。
#include <stdio.h> int main(void){ printf("EOF的值用數字表示為:%d\n", EOF); system("pause"); return 0;}
1.8 編寫一個統計空格、定位字元與分行符號個數的程式。
#include <stdio.h>int main(void){ printf("請輸入一些字元,ctrl+Z 或 ctrl+D 結束:\n"); int c,blanks,tabs,newlines,done,lastchar; c = blanks = tabs = newlines = done = 0; while(done==0){ c = getchar(); if (c==' ') ++blanks; if(c=='\t') ++tabs; if(c=='\n') ++newlines; if (c==EOF) { //根據The C Answer Book一書上的解釋,下面的處理是為了應付“某文字檔可能並不以分行符號結尾”的情況, //但我在windows console應用程式裡試不出來,因為不按斷行符號,字元根本就沒送到while迴圈裡,所以就算最後打一個Ctrl+Z,不敲斷行符號也白費 if (lastchar!='\n') { ++newlines; } done = 1; } lastchar = c; } printf("剛才輸入的字元中,空格有%d個,定位字元有%d個,分行符號有%d個\n",blanks,tabs,newlines); system("pause"); return 0;}
1.9 編寫一個將輸入複製到輸出的程式,並將其中連續的多個空格用一個空格代替。
解法1
#include <stdio.h> int main(void){ int c; int inspace=0;//用來判斷是不是遇到了連續空格(0否,1是) while((c = getchar()) != EOF) { if(c == ' ') { //如果未遇到連續空格(即前一個字元是否為空白格) if(inspace == 0) { inspace = 1;//先假設下一個字元也是空格(即連續空格) putchar(c);//顯示第一個字格 } } /* 因為書中到目前為止,還未講到yet關鍵字,所以這裡暫用二個不太優雅的連續if語句處理 */ //如果下一個字元不是空格 if(c != ' ') { inspace = 0;//糾正上一個if中的"連續空格假設",並inspace重新設定為0,即非連續空格 putchar(c);//顯示下一個非空白字元 } } system("pause"); return 0;}
解法2
#include <stdio.h>int main(void){ int c,pc;//c用來儲存當前字元,而pc即previous charactor前一個字元 pc = EOF;//將前一個字元設定為EOF,這樣不匹配任何字元 while((c=getchar())!=EOF) { if (c==' ') //如果當前字元為空白格 if (pc!=' ') //繼續判斷上一個字元是否為空白格 putchar(c); //如果不是連續空格,則輸出該字元 if (c!=' ') //因為原書到目前為止仍未講到else關鍵字,這裡暫時用二個連續if語句處理 putchar(c); pc = c; //"更新"前一個字元的值 } system("pause"); return 0;}
解法3
#include <stdio.h>int main(void){ int c; while((c=getchar())!=EOF) { if (c==' ') { putchar(c); while((c=getchar())==' ' && c !=EOF) //繼續接受下一個字元,如果下一個字元是空格,且沒有輸入結束符 ;//什麼也不幹,即無視該連續的空格 } if (c==EOF)//遇到結束符,則退出 break; putchar(c);//註:這裡實際上是輸出第二個while迴圈中的“合法”字元 } return 0;}
1.10 編寫一個將輸入複製到輸出的程式,並將其中的定位字元替換為\t,把回退符替換為\b,把反斜線替按為\\。這樣可以將定位字元和回退符以可見的方式顯示出來。
解法1
#include <stdio.h>int main(void){ int c,d;//d用來判斷是否指定的逸出字元(1是,0否) while((c=getchar())!=EOF) { d=0; if (c=='\\') { //連續輸出二個'\' putchar('\\'); putchar('\\'); d = 1; } if (c=='\t') { //輸出'\t' putchar('\\'); putchar('t'); d = 1; } if (c=='\b') { putchar('\\'); putchar('b'); d = 1; } if (d==0) //如果不是指定逸出字元,則輸出(註:如果去掉此判斷,則仍然會以不可見方式輸出逸出字元) putchar(c); } system("pause"); return 0;}
解法2
#include <stdio.h>#define ESC_CHAR '\\' //相當於定義了一個"字元常量" int main(void){ int c; while((c = getchar()) != EOF) { switch(c) { case '\b': putchar(ESC_CHAR); putchar('b'); break; case '\t': putchar(ESC_CHAR); putchar('t'); break; case ESC_CHAR: putchar(ESC_CHAR); putchar(ESC_CHAR); break; default: putchar(c); break; } } system("pause"); return 0;}