当前位置:首页 » 编程语言 » c语言是用什么封装的
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言是用什么封装的

发布时间: 2023-07-26 10:27:17

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||''==log->path[0])return;

memset(&stat_buf,0,sizeof(structstat));

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);//deletethefile*.bakfirst

rename(new_path,bak_path);//changethenameofthefile*.newto*.bak

}

//createanewfile

log->fd=open(new_path,O_RDWR|O_APPEND|O_CREAT|O_SYNC,S_IRUSR|S_IWUSR|S_IROTH);

}

}


G. C语言中如何将自己常用的函数封装到编译器的库函数中具体应该怎么做呢

用编译器提供的库管理工具。
C语言的编译器都会提供一个命令行工具,可以把自己编译后的.obj模块加入指定的库文件,以后使用时只需要连接该库文件即可。这个命令行工具通常是lib.exe,用这个工具可以查看库中的模块,可以把模块加入到库中,可以从库中删除模块。这个工具不仅仅是自己建立的库文件的管理工具,可以管理所有的库文件,包括C语言提供的标准库。