簡體   English   中英

function return 更改為直接寫在 printf 語句中

[英]function return changed as directly written in printf statement

#include <stdio.h>
#include <math.h>

int main() {
    printf("%d\n", pow(3546, 0));   
    return 0;
}

上面的代碼打印值0

雖然下面的代碼打印值1

#include <stdio.h>
#include <math.h>

int main() {
    int a  = pow(3546, 0);
    printf("%d\n", a);
    return 0;
}

為什么會這樣? 盡管它們是等價的。

沒有等價的。 后者 function 在打印之前將數字顯式轉換為int ,而前者通過嘗試使用錯誤的格式說明符打印浮點數導致 UB - 你很幸運得到0 ,你可能得到了一個任意數字。

請打開編譯器上的所有警告,它應該抱怨對錯誤類型的數據使用錯誤的格式。

pow返回double類型的結果,並且%d不是用於格式化它的正確轉換說明符。 C 標准未定義由此產生的行為。

要打印double ,您可以使用%g%f以及其他選項:

printf("%g\n", pow(3456, 0));
printf("%f\n", pow(3456, 0));

int a = pow(3546,0); , double值會自動轉換為int以初始化int a ,然后用%d打印該int是正確的。

正如這個答案中提到的, printf使用格式說明符來知道要從堆棧中彈出什么( %dsizeof(int) ,在我的系統中是 4 個字節)。

編輯:正如rici在評論中指出的那樣,它不能保證是堆棧(在x86上,它大部分時間都在 CPU 寄存器中)。標准從不談論實現,這就是這個問題的全部。)

一個有趣的小事實:在我的 Windows 10 框中,它是 0 和 1。在我的 Xubuntu VBox 中,它是 1 和 -2132712864。 因此, printf僅彈出 4 個字節,而您的機器的字節序正在破壞結果。 來自pow(3) 手冊

#include <math.h>

double pow(double x, double y);
float powf(float x, float y);
long double powl(long double x, long double y);

因此,為了在這兩種情況下獲得正確的結果,請使用正確的printf格式說明符

double a = pow(3546, 0);

和:

printf("%lf\n", pow(3546, 0));

如果您想了解有關可變參數函數的更多信息(例如printf ,它采用可變數量的參數),請從閱讀API 手冊頁開始。

#include <stdarg.h>

void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM