随笔分类 -  C

摘要:刚才记录了下用eclipse在linux下开发,突然想起来也另一种方法:MinGW。MinGW是Windows的gcc开发工具,直接使用Windows的运行库,所以可以在windows下面方便的用gcc进行编译。但是这个方法很有局限,那就是没办法使用Linux下面的系统函数,除非自己的代码不依赖于任... 阅读全文
posted @ 2014-06-29 22:18 linxr 阅读(1365) 评论(0) 推荐(0) 编辑
摘要:一直在Linux下开发,苦于没有IDE,一般都是自己编写Makefile,然后在windows下用文本编辑器ftp打开文件编辑,然后在linux下完成编译。调试代码也只能是命令行用gdb进行调试,相当痛苦。现在推荐一个可行的方法:jre +eclipse + Xming + SecureCRT 或 ... 阅读全文
posted @ 2014-06-29 22:04 linxr 阅读(11302) 评论(1) 推荐(1) 编辑
摘要:当然下面列出来的几点都是C的基础用法,只不过是这些用法可能平时不会被注意。所以很多东西第一次看到的时候,可能会觉得很怪异,但是细细想想就能很好的理解,也就能更好的清楚C语言的一些特性。但是在具体的编码过程当中,我还是希望都能老老实实规规矩矩的。因为程序员不需要太多棱角,把代码写得规范整洁比耍小聪明要重要得多。下面我列举了5个例子说明一些问题,如果你是老手看到这些就一笑而过吧,如果是新手,我相信还是会得到一些启发的。 1. #和##在宏中的作用,以及带参宏,参数的传递问题。 2. 结构体中域的偏移位置的计算问题。 3. 结构体的定义以及初始化的用法。 4. 数组和指针在运算... 阅读全文
posted @ 2014-01-16 00:23 linxr 阅读(3941) 评论(15) 推荐(5) 编辑
摘要:上一次曾经发布过一篇如何实现一个代码编辑器。今年工作中得空,所以对这个编辑器进一步做了些更新,把名字改成了从CuteC改成了CEditor。主要是重写了软件的界面(最终还原朴素),重写了编辑控件语法高亮的着色方式,还有增加了一个简单的SSH客户端和SFTP文件编辑的功能。感觉基本的功能已经实现了,所以再次写点东西记录一下。并且发布一下编辑控件的源代码,有兴趣的可下载下来看看,虽然代码写得比较乱。 上个版本:http://www.cnblogs.com/linxr/archive/2011/10/30/2229256.html 编辑控件源码链接:http://files.cnblogs.com. 阅读全文
posted @ 2013-08-13 12:37 linxr 阅读(10409) 评论(1) 推荐(10) 编辑
摘要:源码下载: kvfs.rar正文: 所谓的Key-Value就是每次存储一个数据时,是根据Key进行索引存储的。为了实现Key的快速查找功能,我使用了B-tree存储结构。B-tree被大量用于数据库的索引中,所以选用B-tree想必不会有太大的问题。Value是对应该Key的值,他的长度是未知的,所以要实现这样一个存储系统,必须要解决从Key值到文件位置的映射关系。问题一:实现文件的"自由"读写问题二:实现BTree问题一:实现文件的"自由"读写。 基本思想:所有内容被存储到一个文件中,文件被划分成同一大小的粒度,可以自由的申请不同的大小空间,可以释放 阅读全文
posted @ 2013-08-12 12:15 linxr 阅读(19037) 评论(12) 推荐(5) 编辑
摘要:目录:1.脚本的执行要素2.栈的模拟.3.变量在栈中的地址计算4.函数的调用过程5.命令的解析6.C的库函数调用在前面的文章中,我主要讲解了语言的解析部分,最终我们生产了脚本的中间代码。接下来,将是一个最困难的时刻,怎么解析执行中间代码! 执行代码其实是经过一定处理后的中间代码的另外一种表示。正如前面提到的,我们的中间代码是三元组的形式,比如:c = a + b * c; 可以表示成 @1 = b * c; @2 = a + @1; @3 = c = @2;但是,这种中间代码还得经过一定的转换才能更方便我们解析执行。接下来,我将一步步的说明,中间代码被执行的每个过程。1.脚本的执行要素 一个脚 阅读全文
posted @ 2012-03-15 20:26 linxr 阅读(17386) 评论(12) 推荐(3) 编辑
摘要:1.代码块 代码块是由多个表达式组成的一组代码。它可以看成是以下的形式: { exp1 exp2 ... } 它由"{"开始,由"}"结束,中间包含多条表达式,或者是控制语句。如果不是以"{"开始,那么,一个代码块就是一条表达式。在上面的章节,我们已经介绍过了,每个表达式会产生一个中间代码。它是一个链表 struct _code * ,而一个代码块,是由多个表达式组成的,所以我们将每个表达式的中间代码链表连到一起就成了代码块的中间代码了。 如果代码块中包含控制语句,那么,我们必须做一些处理,即在代码链表中插入跳转语句,和跳转位置(La 阅读全文
posted @ 2012-01-04 10:01 linxr 阅读(7190) 评论(2) 推荐(2) 编辑
摘要:1. BNF定义2.表达式解析3. 后缀表达式4.后缀表达式到中间代码5.中间代码的表示1. BNF定义 虽然不想多提理论知识,但是有些东西还是避免不了。在解析表达式的时候,我们必须知道它的BNF定义,这样解析起来就非常方便了。所谓的BNF定义,相信大家看一眼就知道了: exp_additive -> exp_multiplicative ( "+"|"-" ) exp_multiplicative exp_multiplicative -> exp_cast ( "*"|"/"|"%&quo 阅读全文
posted @ 2011-12-28 14:17 linxr 阅读(11037) 评论(10) 推荐(6) 编辑
摘要:说起来很有意思,自认为对C语言理解得还是比较深刻的。但居然到今天才知道有个strtok函数,试用了一下突然感慨以前做了多少重复劳动。每次需要解析配置文件,每次需要分割字符串,居然都是自己去分割字符串,既累人又容易出错。感概继续学得不够全面啊!这里引用一段strtok用法:The strtok() function returns a pointer to the next "token" instr1, wherestr2contains the delimiters that determine the token. strtok() returnsNULLif no t 阅读全文
posted @ 2011-12-28 10:16 linxr 阅读(79832) 评论(4) 推荐(3) 编辑
摘要:上一篇:C语言解释器的实现--词法分析(二)1.类型的表示 C语言的类型是相当灵活的,除了标准的类型(int char float double long 等等)外,自己根据需求,能定义出无穷的类型。一个具体的例子: int * a[10]; 它表示的意思是: a is ARRAY 0..9 of POINTER to INT 仔细观察它的意思,就会发现,这个类型是其他基本类型按照一定顺序的组合:ARRAY|POINTER|INT。要表示这种形式,链表是最合适不过的了。如下图: (图2.1类型的表示) 还有一些情况,比如结构体类型,那么上述的表示就不大合适了。例如下面的结构体: struct. 阅读全文
posted @ 2011-12-27 20:44 linxr 阅读(4824) 评论(3) 推荐(3) 编辑
摘要:上一篇:C语言解释器的实现--存储结构(一) 词法分析是编译原理中最容易理解的,就算没有了解过编译原理,也能写出一个词法分析器。我们不用理解正则表达式,不用理解状态机原理,就可以轻松的完成词法的分析。 这里首先介绍下自顶向下的解析过程,所谓的自顶向下,按我的理解,就是从一个大的集合解析到小的集合。例如:解析一个文件,那么进入文件,解析一个函数,进入一个函数,解析局部变量,解析表达式,进入表达式,解析变量、常量等等,最终完成一个C文件的解析过程。整个过程,其实就是一个猜测的过程。但是这个过程中,我们必须依赖于文件中的每个词(token),token可以看成是解析过程中的一个单位。 例如: 1.. 阅读全文
posted @ 2011-12-27 13:20 linxr 阅读(6228) 评论(0) 推荐(0) 编辑
摘要:上一篇:C语言解释器的实现--序(零)目录: 1. 内存池 2. 栈 3. Hash表1.内存池 在一些小的程序里,没什么必要添加内存管理模块在里面。但是对于比较复杂的代码,如果需要很多的内存操作,那么加入自己的内存管理是有必要的。至少有一些好处:能够加快内存的申请和释放;能够轻松的查找内存泄露问题;能够对整个软件的内存消耗做一个比较精确的统计;对以后的优化有很大的好处等等。所以,在我的解释器里,我加入了一个简单的内存管理模块,仿造了内存池的做法。 主要思想是这样的: a.记录所有的申请的内存 b.当释放内存时,记录下来以供下次申请使用 c.申请内存时,可以直接使用前面释放过的内存 为了达到以 阅读全文
posted @ 2011-12-16 17:37 linxr 阅读(9136) 评论(7) 推荐(6) 编辑
摘要:在写CuteC文本编辑器的同时,为了使之有脚本执行能力。特意实现了一个简易的C语言解释器,所谓的解释器,就是它是解析执行脚本文件的,并不产生可执行的目标代码。它具备了C语言的几乎全部的语法。随着时间的推移,我打算把它作为一个独立的项目来开发了。在这个过程中,自己也学到了不少的知识,所以也打算跟大家分享。写这些东西,虽然是重复发明轮子的事,但也不至于是在浪费生命。程序员嘛,我总觉得应该是要理解我们每天所编译出来的程序是怎么被执行,应该明白我们敲打的每行代码的实际意义。 我打算写一个系列的文章来说明这个解释器的实现过程,其中对于编译原理的理论知识不做太多的讲解,一是不容易提高大家的积极性,二是自. 阅读全文
posted @ 2011-12-16 17:18 linxr 阅读(13346) 评论(8) 推荐(4) 编辑
摘要:1. 新建一个ca目录。 mkdir ca 2. 新建一个openssl.cnf文件。内容如下:dir = .[ req ] default_bits = 1024 # Size of keys default_keyfile = key.pem # name of generated keys default_md = md5 # message digest algorithm string_mask = nombstr # permitted characters distinguished_name = req_distinguished_name req_extensions = v 阅读全文
posted @ 2011-10-17 13:15 linxr 阅读(1102) 评论(0) 推荐(0) 编辑
摘要:>>用C实现WebService,gsoap是最好的选择了。近一个月都在折腾这个,做个总结吧,估计会写得比较长。因为其中碰到了不少问题,但最终都解决调了。>>快速开始 1. gsoap官网。遇到问题时,官网往往是最能提供帮助的地方。 http://gsoap2.sourceforge.net/ 2. 几个值得参考的链接。 GSoap使用心得: http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html GSoap接口定义: http://blog.sina.com.cn/s/blog_5ee9235c 阅读全文
posted @ 2011-10-17 12:50 linxr 阅读(41752) 评论(0) 推荐(5) 编辑
摘要:Python是简单的,Python又是强大的。刚接触Python的人都会有这么一个疑问:Python到底有什么用。不过要知道它能做什么,还得先学会使用它。Python的语法相当简单,这里有一个教程:http://woodpecker.org.cn/abyteofpython_cn/chinese/,相信你一两天就能对Python轻车熟路。我的大部分时间都是用C开发的,所以,在C中调用Python是我比较关心的话题。看了一些网上前辈们的代码大致上也有一个整体的认识。1. 设置编译环境,其实就是设置Python的头文件和库文件目录2. 初始化Python解释器: Py_Initialize();3 阅读全文
posted @ 2011-07-22 14:24 linxr 阅读(19986) 评论(2) 推荐(4) 编辑
摘要:[废话] 其实写C语言的解释器也是出于偶然的原因,本来只是想给自己的编辑器添加脚本解析的功能,或者简单的宏调用的功能。结果就想实现简单的C语言的脚本解析,后来干脆就想支持C的全部语法。至今还未完成...前几天实现了C的预编译的部分功能,主要是#define预编译宏。 可以下载使用,呵呵:)[预编译]1. C的预编译主要是由代码中的预编译行实现,以#开始的行是预处理命令行,#前后可出现空白符,一行中可以只有#, 称为空白行。命令行后面可以有注释,可以\换行2. C的预编译命令有很多,包括: #define #ifdef #ifndef #if #elif define #endif # ## 等 阅读全文
posted @ 2011-03-23 16:09 linxr 阅读(5935) 评论(2) 推荐(1) 编辑
摘要:一、实现目标用汇编实现C库函数的调用,即:当给定函数名和参数时,可以实现该函数的调用。二、问题描述在实现C解释器时,解析函数调用语句,例如:strlen( "linxr" ); 那么,如何去调用strlen函数?首先,可以得到参数列表arg_listk,然后用如下形式的代码去实现调用stlen函数:if( strcmp( token, "strlen" ) == 0 ){strlen( arg_list[0] );}else if( ... ){}...[问题]这样子,C的库函数大致有几百个,那么这个代码就会变得没完没了了。三、解决问题根据上述的问题。我 阅读全文
posted @ 2011-02-22 14:55 linxr 阅读(4215) 评论(0) 推荐(0) 编辑
摘要:pid_t pid = fork();1. fork 函数返回两次, 0 表示父进程,返回值为子进程ID; =0 表示子进程。[代码]2. 父进程必须要回收子进程,这时必须用wait/waitpid。不然当子进程结束后, 它会变成僵死进程。用 "ps -ef" 命令查看,可看到起状态为defunct。 所所以,在fork()之后,我们一般是执行: waitpid( pid, NULL, 0 ); 参数1: pid表示到等待的子进程ID 参数2: NULL表示对子进程的结束状态不在意。 参数3: 控制选项 [代码]3. 问题提出在调用waitpid后,父进程被阻塞,将不能执行其他的任务,这 阅读全文
posted @ 2011-01-20 22:47 linxr 阅读(702) 评论(0) 推荐(0) 编辑
摘要:软件一般都要输出日志,方便排错和跟踪运行情况。所有日志文件的格式还是要美化点好,以免在查找关键信息时费时费力。所以日志函数要支持: 1、时间和地点。即什么时候哪个地方报的信息。 2、为了方便调用,必须支持多重格式的输出,所以使用printf的格式是最好的。下面就是我写的一个日志函数:调用方法:LOG_DEFAULT 把日志输出到默认的日志文件LOG_TOXFILE 把日志输出大指定的日志文件,如果参数是0,则日志打印到标准输出 阅读全文
posted @ 2010-11-12 14:57 linxr 阅读(1616) 评论(1) 推荐(2) 编辑