Printf () sadece “% f” ile uygunsa scanf () 'nin çiftler için neden “% lf” gerekir?


179

Neden olduğunu scanf()ihtiyacı l"içinde %lf" bir okurken doublezaman printf()kullanabilirsiniz " %fonun argümanı bir olup olmadığı bakılmaksızın" doubleveya float?

Örnek kod:

double d;
scanf("%lf", &d);
printf("%f", d);

1
Burada POINTER ile ne demek istediğini anlamıyorum.

7
@ deetchanya C'de, bir değişkeni tekli işleçle "aldığınızda" &, bu işlemin sonucu değişkenin bellekte depolandığı yeri gösterir. Bu işaretçi aktarılır scanf.
zwol

Yanıtlar:


207

Çünkü C değişken değişkenleri alan fonksiyonlar için değişkenleri iki katına çıkarır. Kullandığınız olmalıdır böylece İşaretçiler, bir şey terfi değildir %lf, %lgya da %le(ya da %laçiftlerde okumak için C99).


26

С99 yana C biçimi belirteçleri ve kayan nokta değişken türleri arasında uygun arasında tutarlı printfve scanf. Bu

  • %f için float
  • %lf için double
  • %Lf için long double

Öyle ki float, tür argümanları varyasyon parametreleri olarak iletildiğinde, bu tür argümanlar örtük olarak türe dönüştürülür double. Bu yüzden de nedenidir printfbiçim belirteçleri %fve %lfdengi ve birbirleriyle değiştirilebilir. In printfsize "kullanımını çapraz" olabilir %lfile floatveya %fbirlikte double.

Ancak bunu pratikte yapmak için hiçbir neden yoktur. Kullanmayın %fiçin printfÇeşidi argümanlar double. C89 / 90 kez doğan yaygın bir alışkanlıktır, ancak kötü bir alışkanlıktır. Kullanım %lfiçinde printfiçin doubleve devam %fiçin ayrılmış floatargümanlar.


1
Derleyici C99 uyumlu bir kütüphane yoksa %fkullanarak %lfbaşarısız olabilir , çünkü printf içinde kullanmak iyi bir alışkanlık olduğunu söyleyebilirim . Ne yazık ki bu durum gerçekte gerçekleşir.
MM

С99 yana C biçimi belirteçleri ve kayan nokta değişken türleri arasında uygun arasında tutarlı printfve scanf. Bunun, aynı biçim belirtecini kullanmanın, a tarafından yazılan verilerin [f]printf()okunabileceği anlamına gelmediğini unutmayın [f]scanf(). Genel olarak, aynı biçim belirteci kullanarak scanf()bu tarafından kullanılan printf()olacak değil başarıyla veri okumak. Örneğin, bir prinf()'s "%d"biçimlendiricisi tarafından eklenebilen boşluk doldurma işlemi, bir çağrıdaki aynı "%d"biçim belirticisi tarafından atlanacaktır scanf().
Andrew Henle

16

scanf&ddeğişkenlerin düzgün bir şekilde doldurulması için işaret edilen verinin boyutunu bilmesi gerekirken, değişken işlevler şamandıraları iki katına çıkarır (tamamen neden olduğundan emin değilim), bu yüzden printfher zaman bir alır double.


1
Variadic bir fonksiyon çok kırılgandır, çünkü kendisine iletilen tüm parametrelerin tam tipini ve boyutunu bilmesi gerekir ve bunu derleme zamanında uygulayamaz. Bir değişken yanlış türdeyse, yanlış değer okunur; yanlış boyutta ise, sonraki tüm değişkenler de yanlış okunacaktır. İki farklı boyutta şamandıra geçirilebilseydi, her türlü kötü ve kaçırılması kolay sorunlara neden olur.
mwfearnley

7

Çünkü aksi takdirde scanf, bir çiftten daha küçük boyutlu bir şamandıraya bir işaretçi geçirdiğinizi düşünür ve yanlış bir değer döndürür.


2

C ifadesinde kayan nokta veya çift değer kullanmak, yine de çift olan bir değerle sonuçlanır, bu nedenle printf farkı söyleyemez. Oysa bir ikilinin işaretçisi, açıkça bir işaretçiden kayan işaretçiden farklı olarak scanf'e bildirilmelidir, çünkü işaretçinin işaret ettiği şey önemlidir.


5
şamandıra çift dönüştürülür , bu durumda argümanlar bir sayısı değişken listesinin bir parçası olduğundan, yüzer hep C. çiftlerde dönüştürülmeyen
Robert Gamble

1
C standart öncesi versiyonlarda dil floatdeğerleri doubleifadelerde otomatik olarak yükseltilmiştir . Bu kural C standardında terk edildi. Genellikle ifadelerde floatterfi edilmez double. Sadece doublevaryasyonlu bir argüman olarak geçtiğinde terfi eder , bu da bu durumda olan şeydir.
AnT
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.