Mengapa itu scanf()
perlu l
" %lf
" di saat membaca double
, kapan printf()
bisa menggunakan " %f
" terlepas dari apakah argumennya adalah a double
atau a float
?
Kode contoh:
double d;
scanf("%lf", &d);
printf("%f", d);
c
scanf
length-modifiers
raldi
sumber
sumber
&
operator unary , hasil operasi itu adalah penunjuk ke lokasi penyimpanan variabel dalam memori. Ini adalah pointer yang diteruskan kescanf
.Jawaban:
Karena C akan mempromosikan floats ke doubles untuk fungsi yang mengambil argumen variabel. Pointer tidak dipromosikan ke apa pun, jadi Anda harus menggunakan
%lf
,%lg
atau%le
(atau%la
dalam C99) untuk membaca ganda.sumber
Sejak С99 pencocokan antara penentu format dan tipe argumen floating-point dalam C konsisten antara
printf
danscanf
. ini%f
untukfloat
%lf
untukdouble
%Lf
untuklong double
Kebetulan ketika argumen tipe
float
dilewatkan sebagai parameter variadic, argumen tersebut secara implisit dikonversi menjadi tipedouble
. Ini adalah alasan mengapa dalamprintf
penspesifikasi format%f
dan%lf
setara dan dipertukarkan. Di dalamprintf
Anda dapat "cross-use"%lf
denganfloat
atau%f
dengandouble
.Tetapi tidak ada alasan untuk benar-benar melakukannya dalam praktik. Jangan gunakan
%f
untukprintf
argumen tipedouble
. Ini adalah kebiasaan yang tersebar luas yang lahir kembali di tahun C89 / 90, tetapi itu adalah kebiasaan buruk. Gunakan%lf
diprintf
untukdouble
dan terus%f
dicadangkan untukfloat
argumen.sumber
%f
di printf adalah kebiasaan yang baik karena kode Anda selalu berfungsi, sedangkan menggunakan%lf
mungkin gagal jika kompiler tidak memiliki perpustakaan yang sesuai dengan C99. Sayangnya situasi itu memang terjadi dalam kenyataan.printf
danscanf
. Perhatikan bahwa ini tidak menyiratkan bahwa menggunakan specifier format yang sama berarti bahwa data yang ditulis oleh a[f]printf()
dapat dibaca oleh[f]scanf()
. Secara umum, menggunakan specifier format yang sama untukscanf()
yang digunakan oleh tidakprintf()
akan berhasil membaca data. Misalnya, ruang bantalan yang dapat dimasukkan oleh penentu format format akan dilewati oleh penentu format format yang sama dalam panggilan.prinf()
"%d"
"%d"
scanf()
scanf
perlu mengetahui ukuran data yang ditunjuk oleh&d
untuk mengisinya dengan benar, sedangkan fungsi variadic mempromosikan floats menjadi ganda (tidak sepenuhnya yakin mengapa), jadiprintf
selalu mendapatkan adouble
.sumber
Karena jika tidak, scanf akan berpikir Anda melewatkan pointer ke float yang ukurannya lebih kecil daripada double, dan itu akan mengembalikan nilai yang salah.
sumber
Menggunakan float atau nilai ganda dalam ekspresi C akan menghasilkan nilai yang merupakan nilai ganda, sehingga printf tidak dapat membedakannya. Sedangkan pointer ke double harus secara eksplisit ditandai untuk memindai sebagai berbeda dari pointer ke float, karena apa yang menunjuk pointer adalah yang penting.
sumber
float
nilai-nilai bahasa C secara otomatis dipromosikan kedouble
dalam ekspresi. Aturan itu ditinggalkan dalam standar C. Secara umum,float
tidak dipromosikan kedouble
dalam ekspresi. Itu hanya akan dipromosikandouble
ketika disahkan sebagai argumen variadic, yang adalah apa yang terjadi dalam kasus ini.