Untuk apa specifier format yang benar double
dalam printf? Apakah itu %f
atau tidak %lf
? Saya percaya itu %f
, tapi saya tidak yakin.
Contoh kode
#include <stdio.h>
int main()
{
double d = 1.4;
printf("%lf", d); // Is this wrong?
}
c
floating-point
printf
double
format-specifiers
Macan tutul
sumber
sumber
"%lf"
tidak terdefinisi; di perpustakaan C99 dan C11 itu didefinisikan sama dengan"%f"
.%lf
adalah penentu format yang benar untukdouble
. Tapi itu jadi di C99. Sebelum itu orang harus menggunakan%f
.Jawaban:
"%f"
adalah (atau setidaknya satu) format yang benar untuk double. Ada yang ada format untukfloat
, karena jika Anda mencoba untuk lulusfloat
untukprintf
, itu akan dipromosikan kedouble
sebelumprintf
menerimanya 1 ."%lf"
juga dapat diterima di bawah standar saat ini - yangl
ditentukan tidak berpengaruh jika diikuti olehf
specifier konversi (antara lain).Perhatikan bahwa ini adalah satu tempat
printf
string format berbeda secara substansial dari string formatscanf
(danfscanf
, dll.). Untuk output, Anda melewati sebuah nilai , yang akan dipromosikan darifloat
kedouble
ketika lulus sebagai parameter variadic. Untuk input Anda melewati pointer , yang tidak dipromosikan, jadi Anda harus memberi tahuscanf
apakah Anda ingin membaca afloat
ataudouble
, jadi untukscanf
,%f
berarti Anda ingin membacafloat
dan%lf
berarti Anda ingin membacadouble
(dan, untuk apa itu layak, untuk along double
, Anda gunakan%Lf
untuk salah satuprintf
atauscanf
).1. C99, §6.5.2.2 / 6: "Jika ekspresi yang menunjukkan fungsi yang dipanggil memiliki tipe yang tidak termasuk prototipe, promosi integer dilakukan pada setiap argumen, dan argumen yang memiliki tipe float dipromosikan menjadi dua kali lipat. Ini disebut promosi argumen default. " Dalam C ++ kata-katanya agak berbeda (misalnya, itu tidak menggunakan kata "prototipe") tetapi efeknya sama: semua parameter variadic mengalami promosi default sebelum diterima oleh fungsi.
sumber
g++
tolak%lf
ketika kompilasi dengan-Wall -Werror -pedantic
:error: ISO C++ does not support the ‘%lf’ gnu_printf format
l
adalah ekstensi. Standar C99 / 11 dan C ++ 11 membutuhkan implementasi untuk memungkinkannya.scanf
memang ingindouble
diwakili oleh%lf
: ia mengeluh bahwa ia diharapkanfloat *
dan ditemukandouble *
dengan adil%f
.scanf
membutuhkan pointer ke mana untuk menyimpan apa yang dibaca, sehingga kebutuhan untuk mengetahui seberapa besar ruang yang menunjuk-di adalah, sedangkanprintf
mengambil nilai-nilai mereka sendiri, dan "argumen promosi default" berarti baik akhir sebagaidouble
s, sehinggal
adalah pada dasarnya opsional.Mengingat standar C99 (yaitu, draft N1256 ), aturan bergantung pada jenis fungsi: fprintf (printf, sprintf, ...) atau scanf.
Berikut adalah bagian yang relevan yang diekstraksi:
Aturan yang sama ditentukan untuk
fprintf
melamarprintf
,sprintf
dan fungsi serupa.Singkat cerita, untuk
fprintf
penentu berikut dan jenis yang sesuai ditentukan:%f
-> dobel%Lf
-> panjang ganda.dan untuk
fscanf
itu adalah:%f
-> mengapung%lf
-> dobel%Lf
-> panjang ganda.sumber
Bisa jadi
%f
,%g
atau%e
tergantung pada bagaimana Anda ingin nomor diformat. Lihat di sini untuk detail lebih lanjut. Thel
pengubah diperlukanscanf
dengandouble
, tapi tidak diprintf
.sumber
l
pengubah (huruf kecil) untuk tipe integer ( cplusplus.com/reference/clibrary/cstdio/printf ), danL
untuk tipe floating point. Selain itu,L
pengubah mengharapkan along double
, bukan polosdouble
.l
tidak diperlukanprintf
untukdouble
.Format
%lf
adalahprintf
format yang benar-benar benardouble
, persis seperti yang Anda gunakan. Tidak ada yang salah dengan kode Anda.Format
%lf
dalamprintf
tidak didukung dalam versi bahasa C lama (pra-C99), yang menciptakan "inkonsistensi" dangkal antara penentu format untukdouble
diprintf
danscanf
. Ketidakkonsistenan dangkal itu telah diperbaiki di C99.Anda tidak diharuskan untuk menggunakan
%lf
dengandouble
diprintf
. Anda dapat menggunakan%f
juga, jika Anda lebih suka (%lf
dan%f
setara denganprintf
). Tetapi dalam C modern sangat masuk akal untuk lebih suka menggunakan%f
denganfloat
,%lf
dengandouble
dan%Lf
denganlong double
, secara konsisten dalam keduanyaprintf
danscanf
.sumber
scanf()
,"%f"
,"%lf"
cocok denganfloat *, double *
, tidakfloat, double
seperti yang tersirat oleh baris terakhir.%Lf
(perhatikan ibukotaL
) adalah penentu format untuk ganda yang panjang .Untuk polos
doubles
, baik%e
,%E
,%f
,%g
atau%G
akan melakukan.sumber
%g
dan%G
?