1. 程式人生 > >C列印函式printf的一種實現原理簡要分析

C列印函式printf的一種實現原理簡要分析

【0】README

【1】printf函式程式碼分析:

  • P1)line66: va_list arg = (va_list)((char*)(&fmt) + 4); 要知道,對於C函式的呼叫,壓棧順序是從右引數往左邊引數壓棧,最右邊引數最先壓棧,最左邊引數最後壓棧;當然, (&fmt+4)指向的是 printf引數列表中 “…” 的首地址, 而“…” 代表的是引數列表(低地址到高地址,因為壓棧順序就是從高地址到低地址壓棧):MAG_CH_ASSERT, exp, file, base_file, line ;
  • P2)結合以上敘述,我們得到 buf 就是個字串陣列(可以看做緩衝區)、 fmt = “%c assert(%s) failed: file: %s, base_file: %s, ln%d” 、arg = MAG_CH_ASSERT, exp, file, base_file, line 五個引數列表(即長度為5的20位元組陣列,每個地址4個位元組);

【2】vsprintf 函式程式碼分析:

  • V1)line68: 呼叫 vsprintf 函式,同樣的,引數壓棧順序是從右往左壓棧, 我們看看vsprintf 的原始碼, 結合原始碼,我們的分析如下:

    • V1.1)line57~60 :非找到 fmt 中的 % 不可(%是定義輸出格式的識別符號), 且fmt 的字元是一個一個copy 到buf 的;
    • V1.2)line87~113:從引數列表 p_next_arg = args 中 抽取出 格式字串,用q = inner_buf 來儲存這些引數值;(顯然,i2a()函式是 數字輸出的不同進位制的轉換,16進位制、10進位制等),p_next_arg += 4; p_next_arg 為什麼自加4 ,不用我多說了吧;
    • V1.3)line119~122:用inner_buf 儲存的格式輸出值 去填充 %定義的格式輸出;
  • V2)再看看 vsprintf 對於 輸出格式寬度是如何處理的?如%10d,等等;

    • V2.1)line62 :將align_nr 初始化為 0;
    • V2.2)line67~77: 是在 對 %下一個字元出現的可能情況的處理: 如果有兩個 %% 並排,則表明輸出為%、如果為0,待會cs=0、如果是其他情況,cs=空格;
    • V2.3)line78~82: 是在對 % 下一個字元是數字(列印寬度)的處理;
    • V2.4)line115~118:將cs 的值賦給 緩衝區 buf, 這裡應該是把空格賦值過去,以填充列印寬度(說實話,這裡我也沒有好懂, 不過printf 的 實現步驟的大致方向清楚了);

相關推薦

C列印函式printf實現原理簡要分析

【0】README 【1】printf函式程式碼分析: P1)line66: va_list arg = (va_list)((char*)(&fmt) + 4); 要知道,對

C++從零開始區塊鏈:main函式實現

前面已經把各種業務邏輯都寫好了,main函式怎麼呼叫就隨便了,這裡只是其中一種實現方法 int main(int argc, char **argv) { if (argc < 2) { std::cout << "argc error!

C/C++——strcpy函式的 幾 實現 和 詳細 解析

C/C++——strcpy函式的實現 和解析 題目:      已知strcpy函式的原型是:         &nb

C++差分隱私的指數機制的實現方法

list and span 機制 namespace stdio.h int class ++ #include <iostream> #include<stdio.h> #include<stdlib.h> #include<m

c# 數字ID與可見字串碼互轉的實現

c# 數字ID與可見字串碼互轉的一種實現 適用場景:有時使用者id等之類的欄位用的是int型別,但在有些時候不想讓這個id暴露,於是可以考慮把這個id轉換成一個字串,而且要可根據這個字串得到相應的id值 實現如下程式碼: using System; using System.Data; usi

vpn原理實現--隧道的實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

利用IAT匯出OpenGL函式:OpenGL Loader的另實現辦法

利用這種辦法可以用50KB的DLL匯出OpenGL 3.3版本所有Core Profile函式, DLL比GLEW小很多, 根據glcorearb.h自動生成的程式碼與glLoadGen生成的程式碼差不多, 這部分程式碼包含的函式都是空實現,結合__declspec(dllexport,

linux裡的select函式併發伺服器的實現

select函式   函式原型:   int select(int nfds, fd_set *readfds, fd_set *writefds,                        fd_set *exceptfds, struct timeval *t

C++知識分享:C++函式的過載機制

一種C++函式過載機制 這個機制是由張素琴等人提出並實現的,他們寫了一個C++的編譯系統COC++(開發在國產機上,UNIX作業系統環境下具有中國自己版權的C、C++和FORTRAN語言編譯系統,這些編譯系統分別滿足了ISOC90、AT&T的C++85和ISOFORTRAN90標準)。COC++中的

實現人工智慧程式自進化的概念原理

      本文主要論述五點:         1、能自我學習自我控制自我進化的資訊處理控制能力就叫智慧;         2、實現人工智慧程式自進化的模式是程式自己修改自己的自迴圈;         3、智慧演算法通過若干子系統的功能實現自迴圈;         4、人工

C語言中返回字串函式的四實現方法

其實就是要返回一個有效的指標,尾部變數退出後就無效了。 使用分配的記憶體,地址是有效 char   *fun() {         char*   s   =   (char*)calloc(100,   sizeof(char*)   );         if   (s)                

C++返回字串函式的幾實現方法

C++返回字串函式有四種方式: 1。使用堆空間,返回申請的堆地址,注意釋放 2。函式引數傳遞指標,返回該指標 3。返回函式內定義的靜態變數(共享) 4。返回全域性變數 1.使用堆空間,返

05 printf函式可變引數的實現原理之彙編分析

如實現一個像printf函式格式的函式: test.c void myprintf(char *line, ...) // line指標變數是區域性變數,在棧裡分配空間 { printf(line); //呼叫printf時,r0存放字串地

迴圈緩衝區C++的實現

之前去騰訊面試的時候被問到的一道題目:實現一個迴圈緩衝區(不帶互斥鎖)。仔細一想,其實和迴圈佇列的思想一模一樣,還是怪自己資料結構沒學好阿(其實我是學通訊的,所以最近在惡補)。還是先上程式碼 標頭檔案如下,CircleBuffer.h #ifndef _CIRCLE_BUF

malloc函式簡單的原理性實現

malloc()是C語言中動態儲存管理的一組標準庫函式之一。其作用是在記憶體的動態儲存區中分配一個長度為size的連續空間。其引數是一個無符號整形數,返回值是一個指向所分配的連續儲存域的起始地址的指標 malloc()工作機制 malloc函式的實質體現在,它有一個將

詳解單頁面路由的幾實現原理

htm 缺點 服務 ajax請求參數 重復 情況 路由 dem history 路由是每個單頁面網站必須要有的,本篇基本不會天貼代碼,只講原理,代碼在頁面底會有github地址,註意,一定要放在本地服務器裏跑(因為有AJAX) 眾所周知,單頁面網站的路徑跳轉全是通過JS來控

nginx 301重定向實現方法

pan listen lis return uri www com 瀏覽器 request 1 假設要使用的域名是b.com,以前的老域名是a.com,則以下設置讓nginx把a.com的請求訪問轉發到b.com,並返回301給瀏覽器。 2 server 3

Python3中socket的實現方式

div reply auth email str 兩個 env ini 字符串 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017-06-09 22:57 # @Author : wlgo210

樂觀鎖的實現方式——CAS

www. 提升 中一 num 對象 用戶 ace 另一個 nbsp 原文出處: hollischuang (@Hollis_Chuang) 在深入理解樂觀鎖與悲觀鎖一文中我們介紹過鎖。本文在這篇文章的基礎上,深入分析一下樂觀鎖的實現機制,介紹什麽是CAS、CAS的應用以及C

最大子矩陣的實現方法

targe 空間 pos 右下角 ont 算法 algo 最大子矩陣 AC 題目: 農夫約翰想要在他的正方形農場上建造一座正方形大牛棚。他討厭在他的農場中砍樹,想找一個能夠讓他在空曠無樹的地方修建牛棚的地方。我們假定,他的農場劃分成 N x N 的方格。輸入數據中包括