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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c/c++ / printf 实现

發(fā)布時間:2024/10/14 c/c++ 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c/c++ / printf 实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、源碼實現(xiàn)

#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <assert.h>void my_printf(const char *fmt, ...) {va_list ap;va_start(ap, fmt); /* 用最后一個具有參數(shù)的類型的參數(shù)去初始化ap */for (; *fmt; ++fmt){/* 如果不是控制字符 */if (*fmt != '%'){putchar(*fmt); /* 直接輸出 */continue;}/* 如果是控制字符,查看下一字符 */++fmt;if ('\0' == *fmt) /* 如果是結(jié)束符 */{assert(0); /* 這是一個錯誤 */break;}switch (*fmt){case '%': /* 連續(xù)2個'%'輸出1個'%' */putchar('%');break;case 'd': /* 按照int輸出 */{/* 下一個參數(shù)是int,取出 */int i = va_arg(ap, int);putchar(i);}break;case 'c': /* 按照字符輸出 */{/** 但是,下一個參數(shù)是char嗎*//* 可以這樣取出嗎? */char c = va_arg(ap, char);putchar(c);}break;case 's':{char *pc = va_arg(ap, char *);while(*pc)putchar(*pc++);}break;}}va_end(ap);return; }int main() {my_printf("%s %s %c%c%c%c%c!\n", "welcome", "to", 'C', 'h', 'i', 'n', 'a');return 0; }

二、缺陷分析

代碼編譯時會提示警告:

test_printf.c:41:33: warning: ‘char’ is promoted to ‘int’ when passed through ‘...’char c = va_arg(ap, char);

不處理,直接執(zhí)行程序,發(fā)現(xiàn)程序崩潰了。

問題就在于這行代碼:

char c = va_arg(ap, char);

這里面會涉及“默認參數(shù)提升”的情況。

C語言中什么時候會牽扯到默認參數(shù)提升呢?

在C語言中,調(diào)用一個不帶原型聲明的函數(shù)時:調(diào)用者會對每個參數(shù)執(zhí)行“默認實際參數(shù)提升(default argument promotions)。同時,對可變長參數(shù)列表超出最后一個有類型聲明的形式參數(shù)之后的每一個實際參數(shù),也將執(zhí)行上述提升工作。

提升工作如下:

  • float 類型的實際參數(shù)將提升到 double 。

  • char、short 和相應(yīng)的 signed、unsigned 類型的實際參數(shù)提升到 int 。

  • 如果 int 不能存儲原值,則提升到 unsigned int 。

所以,調(diào)用 my_printf 函數(shù)時,傳入的參數(shù)絕對不會是如下類型:

  • char、signed?char、unsigned?char

  • short、unsigned short

  • signed shortshort int、signed?short int、unsigned?short int

  • float

所以正確的方案是將代碼

char c = va_arg(ap, char);

?改為

int c = va_arg(ap, int);

即可。

?

參考:

https://blog.csdn.net/astrotycoon/article/details/8284501

https://blog.csdn.net/iynu17/article/details/51588199

?

(SAW:Game Over!)

總結(jié)

以上是生活随笔為你收集整理的c/c++ / printf 实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。