在開發mtk的時候,總習慣一直跟蹤**,一層一層的跳進去看個究竟。看到dbg_print(char *fmt,...) 這個函式,看了函式體,發現它實現了我從前一直疑惑的乙個問題,printf的格式化輸出是怎麼實現的,查了一些關於可變引數函式的資料,並把mtk中printf格式化字串的實現方式附上,希望對大家有用:
1.要在函式中使用引數,首先要包含標頭檔案。
這個標頭檔案宣告了乙個va_list型別,定義了四個巨集,用來遍歷可變引數列表。
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);
下面詳細介紹這些巨集定義:
2.void va_start(va_list ap, last)
va_start必須第乙個呼叫,它初始化va_list型別的變數ap,使ap指向第乙個可選引數。引數 last 是可變引數列表(即函式原型中的省略號…)的前乙個引數的名字,也就是最後型別已確定的函式引數名。因為這個引數的位址將會被巨集va_start用到,所以最好不要是暫存器變數,函式,或者陣列。
對於有可變長引數,但是在可變長引數前沒有任何的固定引數的函式,如int func (...)是不允許的。 這是ansi c所要求的,變參函式在...之前至少得有乙個固定引數。這個參
數將被傳遞給va_start(),然後用va_arg()和va_end()來確定所有實際呼叫時可變長引數的型別和值。
type va_arg(va_list ap, type)
巨集va_arg展開後是關於下乙個引數的型別和值的表示式,引數type是明確的型別名。
va_arg返回引數列表中的當前引數並使ap指向引數列表中的下乙個引數。
void va_end(va_list ap)
每次呼叫va_start就必須相應的呼叫va_end銷毀變數ap,即將指標ap置為null。
void va_copy(va_list dest, va_list src)
複製va_list型別的變數。
每次呼叫va_copy,也必須有相應的va_end呼叫。
呼叫者在實際呼叫引數個數可變的函式時,要通過一定的方法指明實際引數的個數,例如把最後乙個引數置為空字串(系統呼叫execl()就是這樣的)、-1或其他的方式(函式
printf()就是通過第乙個引數,即輸出格式的定義來確定實際引數的個數的)。
3. 舉例:
#include
#include
int main()
int a,b,c,d,e;
int max(int,int...);
cin>>a>>b>>c>>d>>e;
cout<<"the bigger between a and b is "int max(int num,int integer...)
va_list ap;
int m=integer;
va_start(ap,integer);
for(int i=1;iwhile(0);
#else
#define dbg_printf(_x_)
#endif
#endif
__file__ 是內建巨集 代表原始檔的檔名
__line__ 是內建巨集,代表該行**的所在行號
/ 是行連線符,會將下一行和前一行連線成為一行,即將物理上的兩行連線成邏輯上的一行
#define dbg_printf(_x_) /
dowhile(0);
這樣更方便閱讀
//獲取網絡卡吞吐率
void run_throughput()
while(!feof(fp))
if( getline(&szline, &len, fp) < 0 )
//忽略每行開頭的空格
p = szline;
while( *p && (*p==' ') )
p++;
if( strncmp(p, "eth0", strlen("eth0")) == 0 )
else if( strncmp(p, "eth1", strlen("eth1")) == 0 )
else
continue;
}
//更新全域性變數
pre_eth0_in = eth0_in;
pre_eth0_out = eth0_out;
pre_eth1_in = eth1_in;
pre_eth1_out = eth1_out;
eth0_in = neth0in;
eth0_out = neth0out;
eth1_in = neth1in;
eth1_out = neth1out;
//計算時間間隔
now = time((time_t*)0);
nseconds = now-pre_time;
pre_time = now;
//計算網絡卡流速
eth0_in_bps = (int) ( (eth0_in-pre_eth0_in) / nseconds );
eth0_out_bps = (int) ( (eth0_out-pre_eth0_out) / nseconds );
eth1_in_bps = (int) ( (eth1_in-pre_eth1_in) / nseconds );
eth1_out_bps = (int) ( (eth1_out-pre_eth1_out) / nseconds );
if(szline)
free(szline);
if(fp)
fclose(fp);
}
//獲取tcp連線數
void run_tcpconn()
conn = tcp_conns;
while(!feof(fp))
if( getline(&szline, &len, fp) < 0 )
p = szline;
while( *p && (*p==' ') )
p++;
//除sl開頭的行,其餘每行都是乙個tcp連線
if( strncmp(p, "sl", strlen("sl")) )
else
continue;
}
conn->st = 0;
conn = tcp_conns;
ntcpconns = 0;
while(conn->st)
conn++;
}
if(szline)
free(szline);
if(fp)
fclose(fp);
}
int job_run()
static void sysstat_sync()
//參考cron實現
static void sysstat_sleep()
}
int main()
while(targettime < time((time_t*)0));
}
now = time((time_t*)0);
dbg_print(log_debug, "stop at %s", ctime(&now));
closelog();
if (fpresult)
fclose (fpresult);
return 0;
}
MTK中dbg print函式的實現
在開發mtk的時候,總習慣一直跟蹤 一層一層的跳進去看個究竟。看到dbg print char fmt,這個函式,看了函式體,發現它實現了我從前一直疑惑的乙個問題,printf的格式化輸出是怎麼實現的,查了一些關於可變引數函式的資料,並把mtk中printf格式化字串的實現方式附上,希望對大家有用 ...
MTK按鍵函式
按鍵常用函式 以左按鍵為列 void setkeyhandler funcptr funcptr,u16 keycode,u16 keytype void setleftsoftkeyfunction void f void mmi key event type k void changelefts...
MTK中GPIO的使用
一 gpio有關的函式 1 gpio modesetup 函式原型 void gpio modesetup kal uint16 pin,kal uint16 conf dada 功能 設定gpio的工作模式是作為gpio,還是作為專有功能介面。引數 pin gpio 的pin腳號,對應於原理圖上m...