日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c语言printf %llo,c++ - Printf疯狂了 - 堆栈内存溢出

發布時間:2025/3/15 c/c++ 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言printf %llo,c++ - Printf疯狂了 - 堆栈内存溢出 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

你不能使用%d來打印long long 。 你必須使用%lld 。 (因此請使用"\\n%d %d | %lld %lld | %d %d"作為格式字符串。)

特別是,顯而易見的是,在“52 0 | 52 0”中,第一個52 0是a.rez ,第二個52 0是b.rez (這些中的每一個都是long long ,顯然是(從輸出)將兩個單詞推入堆棧)。 a.tonum不打印a.tonum和b.tonum 。

要理解為什么會發生這種情況,讓我解釋一下喬納森和我想說的話。 當你調用像一個可變參數函數printf (被聲明為類似printf(const char *format, ...)編譯器沒有辦法來驗證正確的參數類型的...在編譯時。因此,有在這種情況下決定在堆棧上推送什么的過程,大致可以概括為:如果它是int或可升級到int ,它將被推送為int ;如果它是double或可升級為double ,則它被推送為double ;否則,按原樣推送。

在實現像printf這樣的可變函數時,您需要一些方法來訪問...項目。 這樣做的方法是使用在聲明的va_list 。 這是一些偽代碼,顯示它是如何使用的:

int printf(const char *format, ...)

{

va_list ap;

va_start(ap, format);

while (/* we find the next format marker */) {

if (/* %d, %i, %c */) {

int val = va_arg(ap, int);

/* print out val as decimal or (for %c) char */

} else if (/* %u, %x, %X, %o */) {

unsigned int val = va_arg(ap, unsigned int);

/* print out val as decimal, hex, or octal */

} else if (/* %ld, %li */) {

long val = va_arg(ap, long);

/* print out val as decimal */

} else if (/* %lu, %lx, %lX, %lo */) {

unsigned long val = va_arg(ap, unsigned long);

/* print out val as decimal, hex, or octal */

} else if (/* %lld, %lli */) {

long long val = va_arg(ap, long long);

/* print out val as decimal */

} else if (/* %llu, %llx, %llX, %llo */) {

unsigned long long val = va_arg(ap, unsigned long long);

/* print out val as decimal, hex, or octal */

} else if (/* %s */) {

const char *val = va_arg(ap, const char *);

/* print out val as null-terminated string */

} /* other types */

}

va_end(ap);

return /* ... */;

}

請注意,每次要選擇...參數時,都要使用va_arg ,并且必須指定要選擇的類型。 您可以選擇正確的類型。 如果類型不正確,則會出現類型錯誤,在大多數情況下會出現未定義的行為(意味著程序可以執行任何喜歡的操作,包括崩潰或更糟)。

在您的特定計算機中,似乎當您通過long long ,它將64位數量推送到堆棧,但因為您使用了%d格式說明符,它使用了va_arg(ap, int)版本,它只抓取一個32位的數量。 這意味著64位字的另一半仍然未讀,后續%d然后繼續讀取。 這就是為什么在格式字符串完成時,它永遠不會處理你傳遞的a.tonum和b.tonum的值。

如果您正確使用%lld ,它將使用va_arg(ap, long long) ,并且可以正確讀取整個64位數量。

總結

以上是生活随笔為你收集整理的c语言printf %llo,c++ - Printf疯狂了 - 堆栈内存溢出的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。