printf函數運行機制

</pre>printf函數運行機制</p><p><span style="font-size:18px">例如:printf("hello,world\n");</span></p><p><span style="font-size:18px">當前printf函數只有一個參數,可以知道的是printf函數可以有很多不固定數量的參數;但是對於printf函數來說,它執行的是一個輸出打印,一個只讀的操作,不管參數的多少,只要參數大於1個,該函數都會按照一定的規則進行參數的輸出;但是有着一個規定是,printf函數的第一個參數必須是一個字符串地址;所有的打印輸出都是按照這樣的一個字符串進行格式化輸出的;對於當前的hello,world這個程序,調用了這個程序,printf開始將字符串hello,world的首地址進行壓棧;在參數全部壓棧完成之後,將會一個參數一個參數的彈出;</span></p><p><span style="font-size:18px">int i = 10,j = 20;</span></p><p><span style="font-size:18px">printf("The i:%d,j:%d\n",i,j);</span></p><p><span style="font-size:18px">從printf函數的參數進行討論;該函數有三個參數,從j開始進行壓棧,然後是i,最後是字符串首地址;當函數壓棧完成之後,printf函數將會從棧中取出數據,首先彈出的是字符串首地址,"The i:%d,j:%d\n",當遇到了格式佔位符時,將會自動從棧中依次取出數據,進行格式替換;</span></p><p><span style="font-size:18px"></span><pre name="code" class="cpp">int printf(const char * __restrict format, ...)
{
	va_list arg;
	int rv;

	va_start(arg, format);
	rv = vfprintf(stdout, format, arg);
	va_end(arg);

	return rv;
}
Printf函數使用了變參結構(va_list),可以參考其他資料關於講解va_list;va_start中fomart用來表示第一個參數的首地址用來標示參數參數地址起始地址,使用將之後的參數存到va_list結構體中;可以用va_arg(arg, int)接口來獲取參數值,獲取完成之後,arg自動指向下一個參數類型;通過掃描格式化串format,遇到%d,%s將對應的值給打印出來;

示例:

void foo(char *fmt, ...)
{
    va_list ap;
    int d;
    char c, *s;

    va_start(ap, fmt);
    while (*fmt)
    {
      if((*fmt++) !=  '%')
      {
        continue;
      }
      switch (*fmt)
      {
              case 's':              /* string */
                      s = va_arg(ap, char *);
                      printf("string %s\n", s);
                      break;
              case 'd':              /* int */
                      d = va_arg(ap, int);
                      printf("int %d\n", d);
                      break;
              case 'c':              /* char */
                      /* need a cast here since va_arg only  
                         takes fully promoted types */
                      c = (char) va_arg(ap, int);
                      printf("char %c\n", c);
                      break;
      }
  }
    va_end(ap);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章