A. c語言中可封裝指啥
應該是指結構struct,可以將若干不同類型的數據封裝起來
B. c++中封裝是藉助什麼達到的
是藉助類達到的。
C++中的類,是在C語言基礎上,針對面向對象編程思想擴展出的一種自定義類型。
其支持成員變數,成員函數,繼承,多態等。
在C++程序設計中,先將實際存在的概念抽象為類,從而實現特性的封裝,然後再通過類對象的定義,將類實例化為對象。
C. c語言如何封裝一個帶有可變參數的方法
需要借用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宏結束可變參數的獲取。
以下是一個自定義列印介面的實現:
intmy_printf(constchar*fmt,...)//...表示參數可變
{
va_listargs;//定義va_list
staticchargc_PrintfOutBuff[1000];
va_start(args,fmt);//初始化
vsnprintf((char*)gc_PrintfOutBuff,1000,(char*)fmt,args);//這里沒有使用VA_ARG取回單個變數,而是借用vsnprinf一次性讀取。
va_end(args);//結束獲取
puts("%s",(constchar*)gc_PrintfOutBuff);//使用。
return0;
}
D. 如何用Python封裝C語言的字元串處理函數
在C語言中,字元串處理是每天都要面對的問題。我們都知道C語言中其實並沒有一種原生的字元串類型,『字元串』在C語言里只是一種特殊的以''結尾的字元數組。因此,如何將C語言與更高層次的Python語言在『字元串』處理這個問題上對接是一個有難度的問題。所幸有swig這種強大的工具。
如何封裝一個函數,它修改參數字元串的內容
假如有這樣一個C語言的函數,
<!-- lang: cpp -->
void FillZero(char* pc,size_t * piLen)
{
size_t i=0;
while(i++<*piLen/2 )
*pc++ = '0';
*pc = 0;
*piLen = i+1;
}
這個函數的功能是把字元串變成n個0。不過我們更關注函數的形式。這樣的函數,表面上看char* pc是函數的參數,可是實際上它才是函數的返回值和執行的結果。piLen這個參數既是pc的最大長度,也是新的字元串的長度。我們直接用python封裝,看看運行結果。
Type "help", "right", "credits" or "license" for more information.
>>> import cchar
>>> s='123456'
>>> cchar.FillZero(s,6)
Traceback (most recent call last):
File "<stdin>", line 1, in <mole>
TypeError: in method 'FillZero', argument 2 of type 'size_t *'
結果差強人意,不是我們想要得到的結果。函數的第二個參數為size_t* 我們很難用python來表示,而且python中也不存在既是輸入,也是輸出的參數。
swig有一個標准庫,其中有一個cstring.i文件就是用來解決C語言字元串類型的問題。
我們在.i文件中加入這樣幾行
<!-- lang: cpp -->
%include "cstring.i"
%cstring_output_withsize(char* pc,size_t* pi)
void FillZero(char* pc, size_t* pi);
然後運行看結果
Type "help", "right", "credits" or "license" for more information.
>>> import cchar
>>> cchar.FillZero(10)
'00000\x00'
>>> s=cchar.FillZero(10)
>>> print s
00000
我們看函數的變化。首先在python里, FillZero變成了只有一個參數的函數。然後函數的返回值變成了一個字元串。其實cstring_output_size其實是一個宏,通過這個宏的定義改變了函數的形式,直接在Python中得到我們想要的結果。
其實類似cstring_output_size的宏還有好幾個,我列舉一下:
cstring_output_allocate(char *s,free($1));
第一個參數是指向字元串地址的指針,第二個參數為釋放空間的方法。
大家考慮這一下這樣的函數:
void foo(char* & s)
{
s = (char*)malloc(10);
memcpy(s,"123456789",9);
}
s這個參數表面上看是輸入,實際上是函數真正的輸出。 函數中真正改變的東西是char&s指向的字元串的值。而且char&這個類型,
python或者其他腳本語言里應該都沒有對應的類型。那麼我們用cstring_output_allocate將這個函數轉換成另外一個形式的python或者其他腳本語言的函數。轉換後的函數其實是這樣的,以python為例str
foo()。
<!-- lang: cpp -->
%mole a
%include "cstring.i"
%{
void foo(char*& s);
%}
%cstring_output_allocate(char *&s, free(*$1));
void foo(char *&s);
在python中的調用:
<!-- lang: python -->
>>> import a
>>> a.foo()
'123456789'
>>>
cstring_output_maxsize(char *path, int maxpath);
第一個參數也是可以改變的字元串首地址,第二個參數為字元串的最大長度。在Python中調用的時候,只有maxpath這個參數,返回字元串。
cstring_output_allocate(char *s, free($1));
第一個參數為指向字元串首地址的指針,第二個參數為釋放指針的方法。這個宏主要是封裝一種直接在函數內部malloc空間的函數。在Python中調用時沒有參數,直接返回字元串。
cstring_output_allocate_size(char *s, int slen, free(*$1));
這個相當於前面兩個函數的組合。在函數內部malloc空間,然後將字元串長度通過slen返回。其實在調用的時候非常簡單,沒有參數,直接返回字元串。
如何處理c++的std::string
std::string是C++標准類庫STL中常見的類。在平時工作中大家肯定是沒少用。在python中如何封裝std::string? swig提供了標准庫
例如函數:
<!-- lang: cpp -->
string Repeat(const string& s)
{
return s+s;
}
只要在swig中加入這樣幾行:
<!-- lang: cpp -->
%include "std_string.i"
using namespace std;
string Repeat(const string& s);
運行結果:
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "right", "credits" or "license" for more information.
>>> import cchar
>>> cchar.Repeat('123')
'123123'
使用起來很方便,但需要注意的是,假如函數的參數的內容是可以被修改,就不能用這種方式封裝。
例如:
<!-- lang: cpp -->
void repeat(string s)
{
s+=s;
}
這樣的函數直接使用 'std_string.i' 就是無效的。遇到這種函數,只能用C語言封裝成 void repeat(chars, int maxsize), 再用swig調用 'cstring_output_withsize' 這個宏再封裝一次了。
E. 如何封裝C語言程序
安裝vc6.0,初學者安裝6.0的,寫一個windows窗口應用程序,編譯後就跟你運行360或者其他軟體一樣,會出現個窗口界面,或者有音效或者彈出窗口,這些需要封裝代碼的。
F. C語言怎麼封裝自己寫的函數
用C語言的時候,您是否還在使用printf函數來輸出日誌呢?您是否考慮過將printf函數列印的內容存到文件中去呢?您是否想擁有一個可選擇的既支持輸出到屏幕又支持存儲到文件中的日誌函數呢?很高興的告訴您,如果您願意的話,歡迎使用本人編寫的一個一套日誌函數,該套函數由五部分組成,分別是宏變數BUF_SIZE、結構體log_st、log_init函數、log_debug函數和log_checksize函數。其中宏變數BUF_SIZE用來限制每次輸出的日誌的最大長度;結構體用來存儲用戶需求,包括文件路徑、文件描述符號、單個文件最大大小、輸出方式標志、文件命名標志等;log_init函數用來完成用戶需求錄入、文件創建等功能,在mian函數的開始調用一次即可;log_debug函數的功能跟printf很類似,是在printf基礎上進行的擴充,實現將日誌輸出到屏幕或者寫入到文件,在需要列印日誌的地方調用該函數;log_checksize函數用來檢測日誌文件大小是否超過最大大小限制,它需要您定時或者定點調用它,如果一直不調用,則日誌文件將不受指定的最大大小限制。
一、定義宏變數BUF_SIZE
view plain to clipboardprint?
#defineBUF_SIZE1024
二、定義log_st結構體
view plain to clipboardprint?
typedefstruct_log_stlog_st;
struct_log_st
{
charpath[128];
intfd;
intsize;
intlevel;
intnum;
};
三、定義log_init函數
參數說明:path——您要存儲的文件路徑;size——單個文件的最大大小,如果超過該大小則新建新的文件用來存儲;level——日誌輸出方式,建議在上層限制其值的范圍為0到3,0表示日誌既不輸出到屏幕也不創建文件和保存到文件,1表示日誌保存到文件但不輸出到屏幕,2表示日誌既輸出到屏幕也保存到文件,3表示日誌只輸出到文件而不創建文件和存入文件;num——日誌文件命名方式,非0表示以(int)time(NULL)作為文件名來保存文件,文件數量隨著日誌量的遞增而遞增;0表示以「.new」和「.bak」為文件名來保存文件,文件數量不超過兩個,隨著日誌量的遞增,舊的日誌文件將被新的覆蓋,更直觀的說就是說.new」和「.bak」文件只保存最近的日誌。
view plain to clipboardprint?
log_st*log_init(char*path,intsize,intlevel,intnum)
{
charnew_path[128]={0};
if(NULL==path||0==level)returnNULL;
log_st*log=(log_st*)malloc(sizeof(log_st));
memset(log,0,sizeof(log_st));
if(level!=3)
{
//thenumusetocontrolfilenaming
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;
returnNULL;
}
}
strncpy(log->path,path,128);
log->size=(size>0?size:0);
log->level=(level>0?level:0);
returnlog;
}
四、定義log_debug函數
view plain to clipboardprint?
voidlog_debug(log_st*log,constchar*msg,...)
{
va_listap;
time_tnow;
char*pos;
char_n=' ';
charmessage[BUF_SIZE]={0};
intnMessageLen=0;
intsz;
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 ",message);
return;
}
if(2==log->level)
printf("%s ",message);
write(log->fd,message,strlen(message));
write(log->fd,&_n,1);
fsync(log->fd);
}
五、定義log_checksize函數
view plain to clipboardprint?
voidlog_checksize(log_st*log)
{
structstatstat_buf;
charnew_path[128]={0};
charbak_path[128]={0};
if(NULL==log||3==log->level||'