c語言中一個完整的函數由函數首部和函數體構成,而且定義函數時兩者都是必不可少的。

渠縣網站建設公司創(chuàng)新互聯(lián)建站,渠縣網站設計制作,有大型網站制作公司豐富經驗。已為渠縣上千提供企業(yè)網站建設服務。企業(yè)網站搭建\成都外貿網站制作要多少錢,請找那個售后服務好的渠縣做網站的公司定做!
函數定義的一般形式如下:
類型標識符
函數名(形參表列)
//
這是函數首部
//
以下{
}內的是函數體
{
說明部分
執(zhí)行部分
}
舉例說明如下:
//
定義一個不帶返回值的函數
//
函數功能:輸出形參的值
void
fun(int
a,
int
b)
{
printf("%d,
%d\n",
a,
b);
}
//
定義一個帶返回值的函數
//
函數功能:返回2個整數數的最大值
int
fun(int
a,
int
b)
{
return
ab
?
a
:
b;
}
用C語言的時候,您是否還在使用printf函數來輸出日志呢?您是否考慮過將printf函數打印的內容存到文件中去呢?您是否想擁有一個可選擇的既支持輸出到屏幕又支持存儲到文件中的日志函數呢?很高興的告訴您,如果您愿意的話,歡迎使用本人編寫的一個一套日志函數,該套函數由五部分組成,分別是宏變量BUF_SIZE、結構體log_st、log_init函數、log_debug函數和log_checksize函數。其中宏變量BUF_SIZE用來限制每次輸出的日志的最大長度;結構體用來存儲用戶需求,包括文件路徑、文件描述符號、單個文件最大大小、輸出方式標志、文件命名標志等;log_init函數用來完成用戶需求錄入、文件創(chuàng)建等功能,在mian函數的開始調用一次即可;log_debug函數的功能跟printf很類似,是在printf基礎上進行的擴充,實現將日志輸出到屏幕或者寫入到文件,在需要打印日志的地方調用該函數;log_checksize函數用來檢測日志文件大小是否超過最大大小限制,它需要您定時或者定點調用它,如果一直不調用,則日志文件將不受指定的最大大小限制。
一、定義宏變量BUF_SIZE
view plaincopy to clipboardprint?
#define?BUF_SIZE?1024
二、定義log_st結構體
view plaincopy to clipboardprint?
typedef?struct?_log_st?log_st;
struct?_log_st
{
char?path[128];
int?fd;
int?size;
int?level;
int?num;
};
三、定義log_init函數
參數說明:path——您要存儲的文件路徑;size——單個文件的最大大小,如果超過該大小則新建新的文件用來存儲;level——日志輸出方式,建議在上層限制其值的范圍為0到3,0表示日志既不輸出到屏幕也不創(chuàng)建文件和保存到文件,1表示日志保存到文件但不輸出到屏幕,2表示日志既輸出到屏幕也保存到文件,3表示日志只輸出到文件而不創(chuàng)建文件和存入文件;num——日志文件命名方式,非0表示以(int)time(NULL)作為文件名來保存文件,文件數量隨著日志量的遞增而遞增;0表示以“.new”和“.bak”為文件名來保存文件,文件數量不超過兩個,隨著日志量的遞增,舊的日志文件將被新的覆蓋,更直觀的說就是說.new”和“.bak”文件只保存最近的日志。
view plaincopy to clipboardprint?
log_st?*log_init(char?*path,?int?size,?int?level,?int?num)
{
char?new_path[128]?=?{0};
if?(NULL?==?path?||?0?==?level)?return?NULL;
log_st?*log?=?(log_st?*)malloc(sizeof(log_st));
memset(log,?0,?sizeof(log_st));
if?(level?!=?3)
{
//the?num?use?to?control?file?naming
log-num?=?num;
if(num)
snprintf(new_path,?128,?"%s%d",?path,?(int)time(NULL));
else
snprintf(new_path,?128,?"%s.new",?path);
if(-1?==?(log-fd?=?open(new_path,?O_RDWR|O_APPEND|O_CREAT|O_SYNC,?S_IRUSR|S_IWUSR|S_IROTH)))
{
free(log);
log?=?NULL;
return?NULL;
}
}
strncpy(log-path,?path,?128);
log-size?=?(size??0???size:0);
log-level?=?(level??0???level:0);
return?log;
}
四、定義log_debug函數
view plaincopy to clipboardprint?
void?log_debug(log_st?*log,?const?char?*msg,?...)
{
va_list?ap;
time_t?now;
char?*pos;
char?_n?=?'\n';
char?message[BUF_SIZE]?=?{0};
int?nMessageLen?=?0;
int?sz;
if(NULL?==?log?||?0?==?log-level)?return;
now?=?time(NULL);
pos?=?ctime(now);
sz?=?strlen(pos);
pos[sz-1]=']';
snprintf(message,?BUF_SIZE,?"[%s?",?pos);
for?(pos?=?message;?*pos;?pos++);
sz?=?pos?-?message;
va_start(ap,?msg);
nMessageLen?=?vsnprintf(pos,?BUF_SIZE?-?sz,?msg,?ap);
va_end(ap);
if?(nMessageLen?=?0)?return;
if?(3?==?log-level)
{
printf("%s\n",?message);
return;
}
if?(2?==?log-level)
printf("%s\n",?message);
write(log-fd,?message,?strlen(message));
write(log-fd,?_n,?1);
fsync(log-fd);
}
五、定義log_checksize函數
view plaincopy to clipboardprint?
void?log_checksize(log_st?*log)
{
struct?stat?stat_buf;
char?new_path[128]?=?{0};
char?bak_path[128]?=?{0};
if(NULL?==?log?||?3?==?log-level?||?'\0'?==?log-path[0])?return;
memset(stat_buf,?0,?sizeof(struct?stat));
fstat(log-fd,?stat_buf);
if(stat_buf.st_size??log-size)
{
close(log-fd);
if(log-num)
snprintf(new_path,?128,?"%s%d",?log-path,?(int)time(NULL));
else
{
snprintf(bak_path,?128,?"%s.bak",?log-path);
snprintf(new_path,?128,?"%s.new",?log-path);
remove(bak_path);?//delete?the?file?*.bak?first
rename(new_path,?bak_path);?//change?the?name?of?the?file?*.new?to?*.bak
}
//create?a?new?file
log-fd?=?open(new_path,?O_RDWR|O_APPEND|O_CREAT|O_SYNC,?S_IRUSR|S_IWUSR|S_IROTH);
}
}
如果是用純C語言來寫,把所有函數聲明放在最前面,然后函數定義好,這樣的函數是公有的,可以隨意調用。然后主函數不能少,這樣子的話,所有函數包括主函數的前后順序可隨意。
void fun1();
void fun2();
//...
int main()
{
return 0;
}
void fun1()
{
//code...
}
void fun2()
{
//code...
}
//...
需要借用C語言的VA_LIST?宏定義,及相關操作來實現可變參數。
VA_LIST?所在頭文件:#include stdarg.h,用法如下:
(1)首先在函數里定義一具VA_LIST型的變量,這個變量是指向參數的指針;
(2)然后用VA_START宏初始化剛定義的VA_LIST變量;
(3)然后用VA_ARG返回可變的參數,VA_ARG的第二個參數是你要返回的參數的類型(如果函數有多個可變參數的,依次調用VA_ARG獲取各個參數);
(4)最后用VA_END宏結束可變參數的獲取。
以下是一個自定義打印接口的實現:
int?my_printf(const?char?*fmt,?...)//...表示參數可變
{
va_list?args;//定義va_list
static?char?gc_PrintfOutBuff[1000];
va_start(args,?fmt);//初始化
vsnprintf((char?*)?gc_PrintfOutBuff,?1000,?(char?*)?fmt,?args);//這里沒有使用VA_ARG取回單個變量,而是借用vsnprinf一次性讀取。
va_end(args);//結束獲取
puts("%s",(const?char?*)gc_PrintfOutBuff);//使用。
return?0;
}
用編譯器提供的庫管理工具。
C語言的編譯器都會提供一個命令行工具,可以把自己編譯后的.obj模塊加入指定的庫文件,以后使用時只需要連接該庫文件即可。這個命令行工具通常是lib.exe,用這個工具可以查看庫中的模塊,可以把模塊加入到庫中,可以從庫中刪除模塊。這個工具不僅僅是自己建立的庫文件的管理工具,可以管理所有的庫文件,包括C語言提供的標準庫。
本文題目:C語言封裝多個函數的方法 c++函數封裝和函數調用
URL分享:http://chinadenli.net/article38/hihssp.html
成都網站建設公司_創(chuàng)新互聯(lián),為您提供App設計、云服務器、網頁設計公司、ChatGPT、企業(yè)網站制作、關鍵詞優(yōu)化
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)