atof(char*), atol(char*), atoi(char*) 都是很好用的函數! 學號: 姓名: _______________ __________ C 語言的語法真的沒有多少句 ! 不到十句! 請仔細研究這個與程式庫(Library)中的 atof(char*) 做的事完全相同的函數( funtcion), ** 然後 在規定要寫理由(每個有 ________)之處, 以及你覺得有人可能看不懂之處補上註解! 請注意, atof 傳回的是 double, 不是 float 喔! 這個程式用了一招非常巧妙的招式, 處理可能有也可能沒有的小數點! 也處理代表次方的 E 或 e ** 根據手冊, atof(char*) 是過時的, 建議改用完全相同功能的 double strtod(char*); //atof.c -- by tsaiwn@csie.nctu.edu.tw //this double atof(char*); is a complete version; same as the one in Library //這個 double atof(char*) 是完整版, 做的事與 Library 內的 atof(char*) 完全一樣 // atof("123") 等於 123.0; atof(" -12.345ABC") 等於 -12.345; // atof(" 123E-2") 等於 1.23; atof(" -12345e-3") 等於 -12.345; // atof(" 123.456E-2") 等於 1.23456; atof(" -12345.678e-3") 等於 -12.345678; // atof(" 123.456E2") 等於 12345.6; atof(" -123.45678e+3") 等於 -123456.78; #include double atof(char p[ ]) { // same as char*p when it appears in parameter double ans =0.0, power = 1.0; // important ! for what? // ==> 請寫出為何 ans 初值 0.0, 但 power 初值要放 1.0 ?________ // int i, ee, sign = 1; // assume positive; 請寫出為何 sign 初值要放 1 ? ___________ // 但是 i 和 ee 為何沒寫初值 ? _____________ // while(isspace(*p) ) ++p; // skip all leading blanks // 請寫出 leading blanks 的中文 :________ if(*p == '-') sign = -1; // it is a negative number; // 請寫出為何這裡 sign 要放 -1 ?________ if(p[0]=='-' || p[0]=='+') ++p; // skip the sign, // 上句已檢查 '-' 為何又檢查一次? ______ while(isdigit(*p)) { // 請問這 atof(" + 38") 會得到多少? ________ ans = ans*10.0 + p[0]-'0'; // 請寫出這句到底在做啥? ________ ++p; } // while 處理連續的數字 (digit)直到遇見非 digit 為止, 停下時 p 指到一個不是 digit 的字 if(*p == '.') ++p; // skip the decimal DOT (.) 若這時看到的是 '.' 小數點, 阿就跳過去 // 上列的 if 獨立寫就可 ! 不必用 { } 把以下全包起來! Why? .. // .. Why? 請寫理由 : _________ // _____________________________________________________________ power = 1.0; // 提醒一下 :-) 這是寫爽的, 因其實前面定義此變數時已經給了 初值 1.0 while(isdigit(*p)) { // 開始處理小數部份! 請寫出為何這樣就可處理小數部份? ________ ans = ans*10.0 + p[0] - '0'; // p[0] 就是 *p power = power * 10.0; // .. // 請寫出為何 power 一直 * 10 ? __________ ++p; // move to next char } // while ans = sign * ans / power; // 請寫出為何 ans 這樣算? ___ ___ _______________ // /// /// 再來要能處理 atof("12E2"), atof("12e-2"), atof("12.345e2"); 等有 E或 e 的 // 以上為止與 K&R 課本 4.2 節做的一樣, 接下來可以是 E 或 e 表示10的次方 // 要能處理 atof("123.45678E+3") 或 atof("1234567E-2") 就是說 E 的右邊也可能有+ 或 -號 // 但是注意 ("123.456-38") 要看作 123.456 喔! 所以以下 if Block 要用 { } 夾住 if(*p == 'e' || *p == 'E') { // 請寫出.. // 若以下9列只把 ++p; 包在這if 的 { } 內會如何? // 就是說把這 if 的左右大括號去掉會怎樣?____________________ ++p; // skip the "e" or "E" ee = 0; sign = 1; // 要開始算次方的部份, sign 重複用來看 E 後面的 if(*p == '-') sign = -1; // negative 次方; 注意 E或 e 後面也可有 +或 - 號 if(p[0]=='-' || p[0]=='+') ++p; // skip the sign while(isdigit(*p)) { ee = ee*10 + p[0]-'0'; ++p; } // 上面這 while Loop與前面算整數部份以及atoi( ) 相同 for(i = 1; i <= ee; ++i) { // 若 ee 是 0 則 for 做 0 次; // 請把這for改用 while 寫出:_____________________ if(sign == -1) ans = ans / 10.0; // 請寫出這if .. else ans = ans*10.0; // ..這if ..else在做啥??? _____________________ } // for i } // if( *p 是 e 或 E return ans; // 請問double x; /// ..若 x = atof("123.246-5"); 會使 x 得到多少? ____________________ } // atof -- by tsaiwn@csie.nctu.edu.tw // 請在以下空白處寫出研究心得(至少99字 )! ( 注意任何時候 *p 就是 p[0] ) // 並請在此頁背面: // (1)寫一個完整的 int atoi(char*) 函數, // (2)寫一個簡單的 main( ) 可以測試到我們在此頁講到 atof( ) 會遇到的各種情況.. // 別忘了右上角寫上學號姓名, 週一上課時拿來繳交!