看板 C_and_CPP 關於我們 聯絡資訊
※ 引述《twayfind (橘水壎)》之銘言: : #include <stdio.h> : int main(void) : { : int a=10; : int b=20; : : float d=0; : : d=(float)a/b; : : printf("%d,%.3f\n",d,d); : printf("%.3f,%d\n",d,d); : return 0; : } : → kiedveian:先轉型成整數 07/17 15:07 : 推 lc85301:我比較好奇為什麼前一個參數的轉換影響到下一個整數? 07/17 17:01 printf (及 scanf) 是使用 C 語言的可變參數下去實作 這種可變參數有幾個限制 首先函式不會知道你傳了什麼東西進去 得要有另外的方法來指名才行 printf/scanf 的做法是傳入一個格式字串以表示後面有哪些參數 再來 不到 int 等級的整數會升級成 int 再傳 float 則會升級成 double 因此這裡推入了兩個 float 實際上傳進 printf 裡時是兩個 double (所以其實 printf 裡指定 %f 跟 %lf 是一樣的) 而 %d 這個格式會去抓一個 int 出來 但是在 32-bit 的架構下 int 跟 double 是不一樣大的 (int 佔 4 byte double 佔 8 byte) 所以在 %d,%.3f 的狀況下 printf 會這樣去抓值: ┌ 第一個 d ┐ ┌ 第二個 d ┐ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** └ %d ┘ └ %.3f ┘ 自然就會跟 %.3f,%d 時抓到的不一樣了: ┌ 第一個 d ┐ ┌ 第二個 d ┐ ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** └ %.3f ┘ └ %d ┘ 無論如何 %d 抓到的一定是錯誤的值 所以一定會有怪結果 在那之後的結果也就不一定正確了 -- 題外話: %f 跟 %lf 在 scanf 裡則有差 因為這時傳進 scanf 的參數全是指標 而 float * 跟 double * 這是兩種指標 所以必須要分開這兩者才行 -- LPH [acronym] = Let Program Heal us -- New Uncyclopedian Dictionary, Minmei Publishing Co. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.118.141.187 ※ 編輯: LPH66 來自: 122.118.141.187 (07/17 19:55)
purincess:你啥時回到人間啊是說 07/17 19:59
purincess:再半年? 07/17 19:59
purincess:噢 忘了先跟lph擊掌 (拍擊lph (?)) 07/17 19:59
cuteclare:/膜拜 07/17 20:29
twayfind:感謝大大的解說 07/17 20:53
hilorrk:從錯誤的使用方法和結果中也可以學習~ 07/17 22:23
azureblaze:我一直以為varg是array of void*,原來是直接疊起來 07/17 22:27
MOONRAKER:我也以為是這樣 07/17 22:35
purincess:所以用stdcall做printf然後參數給的比%數少的話該不會會 07/17 22:38
purincess:爆炸... 07/17 22:38
LPH66:stdcall 是 callee 清堆疊所以不能用可變參數... 07/17 23:13
purincess:可是c standard應該是沒有規定這個吧 @@ 07/17 23:24
a60301:<(_ _)> 07/18 04:00
lc85301:worship 07/18 05:30