我的博客列表

2012年6月10日星期日

【c++】指针图解

http://hi.csdn.net/attachment/201105/13/0_1305265216BaSQ.gif

【c++】内存栈分配和堆分配图解





内存栈分配如上图  内存堆分配如下图  堆无序的可用内存







深入分析C++中char * 和char []的区别 [转]

转自:http://www.yuanma.org/data/2007/0305/article_2375.htm

问题引入:在实习过程中发现了一个以前一直默认的错误,同样char *c = "abc"和char c[]="abc",前者改变其内
容程序是会崩溃的,而后者完全正确。
程序演示:
测试环境Devc++
代码
运行结果
2293628 4199056 abc
2293624 2293624 abc
2293620 4199056 abc

#include <iostream>
using namespace std;

main()
{
   char *c1 = "abc";
   char c2[] = "abc";
   char *c3 = ( char* )malloc(3);
   c3 = "abc";
   printf("%d %d %s/n",&c1,c1,c1);
   printf("%d %d %s/n",&c2,c2,c2);
   printf("%d %d %s/n",&c3,c3,c3);
   getchar();
}  


参考资料:
首先要搞清楚编译程序占用的内存的分区形式:
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于

数据结构中的栈。
2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据

结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态

变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统
释放。
4、文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区
这是一个前辈写的,非常详细
//main.cpp
  int a=0;    //全局初始化区
  char *p1;   //全局未初始化区
  main()
  {
   int b;栈
   char s[]="abc";   //栈
   char *p2;         //栈
   char *p3="123456";   //123456/0在常量区,p3在栈上。
   static int c=0;   //全局(静态)初始化区
   p1 = (char*)malloc(10);
   p2 = (char*)malloc(20);   //分配得来得10和20字节的区域就在堆区。
   strcpy(p1,"123456");   //123456/0放在常量区,编译器可能会将它与p3所向"123456"优化成一个
地方。
}
二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。例如,声明在函数中一个局部变量int b;系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1=(char*)malloc(10);
在C++中用new运算符
如p2=(char*)malloc(10);
但是注意p1、p2本身是在栈中的。
2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将

该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大
小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正
好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地

址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译
时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间
较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地

址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的
虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
2.4申请效率的比较:
栈:由系统自动分配,速度较快。但程序员是无法控制的。
堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用Virtual Alloc分配内存,他不是在堆,也不是在栈,而是直接在进

程的地址空间中保留一块内存,虽然用起来最不方便。但是速度快,也最灵活。
2.5堆和栈中的存储内容
栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的

地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变
量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主

函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。
2.6存取效率的比较
char s1[]="aaaaaaaaaaaaaaa";
char *s2="bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
voidmain()
{
char a=1;
char c[]="1234567890";
char *p="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10:a=c[1];
004010678A4DF1movcl,byteptr[ebp-0Fh]
0040106A884DFCmovbyteptr[ebp-4],cl
11:a=p[1];
0040106D8B55ECmovedx,dwordptr[ebp-14h]
004010708A4201moval,byteptr[edx+1]
004010738845FCmovbyteptr[ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据

edx读取字符,显然慢了。
2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会

切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

自我总结:
char *c1 = "abc";实际上先是在文字常量区分配了一块内存放"abc",然后在栈上分配一地址给c1并指向

这块地址,然后改变常量"abc"自然会崩溃
然而char c2[] = "abc",实际上abc分配内存的地方和上者并不一样,可以从
4199056
2293624 看出,完全是两块地方,推断4199056处于常量区,而2293624处于栈区

2293628
2293624
2293620 这段输出看出三个指针分配的区域为栈区,而且是从高地址到低地址

2293620 4199056 abc 看出编译器将c3优化指向常量区的"abc"

继续思考:
代码:

输出:
2293628 4199056 abc
2293624 2293624 abc
2293620 4012976 gbc
写成注释那样,后面改动就会崩溃
可见strcpy(c3,"abc");abc是另一块地方分配的,而且可以改变,和上面的参考文档说法有些不一定, 

#include <iostream>
using namespace std;

main()
{
   char *c1 = "abc";
   char c2[] = "abc";
   char *c3 = ( char* )malloc(3);
   //  *c3 = "abc" //error
   strcpy(c3,"abc");
   c3[0] = 'g';
   printf("%d %d %s/n",&c1,c1,c1);
   printf("%d %d %s/n",&c2,c2,c2);
   printf("%d %d %s/n",&c3,c3,c3);
   getchar();
}  

2012年6月9日星期六

有关TinyXML使用的简单总结

这次使用了TinyXML后,觉得这个东西真是不错,于是将使用方法坐下总结来和大家分享。
     该解析库在开源网站(http://sourceforge.net )上有下载,在本Blog也提供下载(下载TinyXML
    TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在WindowsLinux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这课XML树。
    注:DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系(理解html语言的读者会很容易理解这种树状模型)。              
     如下是一个XML片段:
    <Persons>
         <Person ID="1">
             <name>周星星</name>
             <age>20</age>
         </Person>
         <Person ID="2">
             <name>白晶晶</name>
             <age>18</age>
         </Person>
     </Persons>
     在TinyXML中,根据XML的各种元素来定义了一些类:
        TiXmlBase:整个TinyXML模型的基类。
               TiXmlAttribute:对应于XML中的元素的属性。
                TiXmlNode:对应于DOM结构中的节点。
                        TiXmlComment:对应于XML中的注释。
                        TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。
                        TiXmlDocument:对应于XML的整个文档。
                        TiXmlElement:对应于XML的元素。
                        TiXmlText:对应于XML的文字部分。
                        TiXmlUnknown:对应于XML的未知部分。
        TiXmlHandler:定义了针对XML的一些操作。
    那我们如何使用这些类以及他们的方法来操纵我们的XML呢?请看下面。
    一、读取XML(假设我们的Xml文档中的内容与上面的Xml内容一样)
    //创建一个XML的文档对象
    TiXmlDocument *myDocument = new TiXmlDocument("填上你的Xml文件名");
    myDocument->LoadFile();
    //获得根元素,即Persons。
    TiXmlElement *RootElement = myDocument.RootElement();
    //输出根元素名称,即输出Persons。
    cout << RootElement->Value() << endl;
    //获得第一个Person节点。
    TiXmlElement *FirstPerson = RootElement->FirstChildElement();
    //获得第一个Person的name节点和age节点和ID属性。
    TiXmlElement *NameElement = FirstPerson->FirstChildElement();
    TiXmlElement *AgeElement = NameElement->NextSiblingElement();
    TiXmlAttribute *IDAttribute = FirstPerson->FirstAttribute();
    //输出第一个Person的name内容,即周星星;age内容,即20;ID属性,即1。
    cout << NameElement->FirstChild()->Value << endl;
    cout << AgeElement->FirstChild()->Value << endl;
    cout << IDAttribute->Value() << endl;

   
    看,读取XML是不是很简单阿,和Java的XML解析库非常的相似,就是名字改了一下而已。
    二、生成XML内容
    //创建一个XML的文档对象。
    TiXmlDocument *myDocument = new TiXmlDocument();
    //创建一个根元素并连接。
    TiXmlElement *RootElement = new TiXmlElement("Persons");
    myDocument->LinkEndChild(RootElement);
    //创建一个Person元素并连接。
    TiXmlElement *PersonElement = new TiXmlElement("Person");
    RootElement->LinkEndChild(PersonElement);
    //设置Person元素的属性。
    PersonElement->SetAttribute("ID", "1");
    //创建name元素、age元素并连接。
    TiXmlElement *NameElement = new TiXmlElement("name");
    TiXmlElement *AgeElement = new TiXmlElement("age");
    PersonElement->LinkEndChild(NameElement);
    PersonElement->LinkEndChild(AgeElement);
    //设置name元素和age元素的内容并连接。
    TiXmlText *NameContent = new TiXmlText("周星星");
    TiXmlText *AgeContent = new TiXmlText("20");
    NameElement->LinkEndChild(NameContent);
    AgeElement->LinkEndChild(AgeContent);
    //保存到文件
     myDocument->SaveFile("要保存的xml文件名");
     这样,便创建了一个如下的xml文件:
    <Persons>
         <Person ID="1">
             <name>周星星</name>
             <age>20</age>
         </Person>
    </Persons>

TinyXML中文文档(转)


2009-08-25 9:25
译注:本文是TinyXML 2.5.2版本Document的中文文档,经原作者Lee Thomason同意由hansen翻译,如有误译或者错漏,欢迎指正。
版权:版权归原作者所有,翻译文档版权归本人hansen所有,转载请注明出处。
原文:http://www.grinninglizard.com/tinyxmldocs/index.html

TinyXml 文档

2.5.2

TinyXML

TinyXML是一个简单小巧,可以很容易集成到其它程序中的C++ XML解析器。

它能做些什么

简单地说,TinyXML解析一个XML文档并由此生成一个可读可修改可保存的文档对象模型(DOM)。

XML的意思是“可扩展标记语言“(eXtensible Markup Language)。它允许你创建你自己的文档标记。在为浏览器标记文档方面HTML做得很好,然而XML允许你定义任何文档标记,比如可以为一个组织者 应用程序定义一个描述“to do”列表的文档。 XML拥有一个结构化并且方便的格式,所有为存储应用程序数据而创建的随机文件格式都可以用XML代替,而这一切只需要一个解析器。

最全面正确的说明可以在http://www.w3.org/TR/2004/REC-xml-20040204/找到,但坦白地说,它很晦涩难懂。事实上我喜欢http://skew.org/xml/tutorial上关于XML的介绍。

有不同的方法可以访问和与XML数据进行交互。TinyXML使用文档对象模型(DOM),这意味着XML数据被解析成一个可被浏览和操作的C++对象, 然后它可以被写到磁盘或者另一个输出流中。你也可以把C++对象构造成一个XML文档然后把它写到磁盘或者另一个输出流中。

TinyXML被设计得容易快速上手。它只有两个头文件和四个cpp文件。只需要把它们简单地加到你的项目中就行了。有一个例子文件——xmltest.cpp来引导你该怎么做。

TinyXML以Zlib许可来发布,所以你可以在开源或者商业软件中使用它。许可证更具体的描述在每个源代码文件的顶部可以找到。

TinyXML在保证正确和恰当的XML输出的基础上尝试成为一个灵活的解析器。TinyXML可以在任何合理的C++适用系统上编译。它不依赖于异常或 者运行时类型信息,有没有STL支持都可以编译。TinyXML完全支持UTF-8编码和前64k个字符实体(<i>译注:如果你不明白这句 译文,可能你需要了解一下Unicode编码</i>)。

它无法做些什么

TinyXML不解析不使用DTDs(文档类型定义)或者XSLs(可扩展样式表语言)。有其它解析器(到www.sourceforge.org搜索一 下XML)具有更加全面的特性,但它们也就更大,需要花更长的时间来建立你的项目,有更陡的学习曲线,而且经常有一个更严格的许可协议。如果你是用于浏览 器或者有更复杂的XML需要,那么TinyXML不适合你。

下面的DTD语法在TinyXML里是不做解析的:


<!DOCTYPE Archiv [
<!ELEMENT Comment (#PCDATA)>
]>

因为TinyXML把它看成是一个带着非法嵌入!ELEMENT结点的!DOCTYPE结点。或许这在将来会得到支持。

指南

有耐性些,这是一份能很好地指导你怎么开始的指南,它(非常短小精悍)值得你花时间完整地读上一遍。
TinyXML指南

代码状况

TinyXML是成熟且经过测试的代码,非常健壮。如果你发现了漏洞,请提交漏洞报告到sourcefore网站上 (www.sourceforge.net/projects/tinyxml)。 我们会尽快修正。

有些地方可以让你得到提高,如果你对TinyXML的工作感兴趣的话可以上sourceforge查找一下。

相关项目

你也许会觉得TinyXML很有用!(简介由项目提供)
TinyXPath (http://tinyxpath.sourceforge.net). TinyXPath是一个小巧的XPath语法译码器脚本,用C++写成。
TinyXML++ (http://code.google.com/p/ticpp/). TinyXML++是一个全新的TinyXML接口,使用了许多诸如模板,异常处理和更好的错误处理这些C++强项技术。

特性

使用STL

TinyXML可以被编译成使用或不使用STL。如果使用STL,TinyXML会使用std::string类,而且完全支持 std::istream,std::ostream,operator<<和operator>>。许多API方法都有 ‘const char*’和’const std::string&’两个版本。

如果被编译成不使用STL,则任何STL都不会被包含。所有string类都由TinyXML它自己实现。所有API方法都只提供’const char*’传入参数。

使用运行时定义:

TIXML_USE_STL

来编译成不同的版本。这可以作为参数传给编译器或者在“tinyxml.h”文件的第一行进行设置。

注意:如果在Linux上编译测试代码,设置环境变量TINYXML_USE_STL=YES/NO可以控制STL的编译。而在Windows上,项目文 件提供了STL和非STL两种目标文件。在你的项目中,在tinyxml.h的第一行添加"#define TIXML_USE_STL"应该是最简单的。

UTF-8

TinyXML支持UTF-8,所以可以处理任何语言的XML文件,而且TinyXML也支持“legacy模式”——一种在支持UTF-8之前使用的编码方式,可能最好的解释是“扩展的ascii”。

正常情况下,TinyXML会检测出正确的编码并使用它,然而,通过设置头文件中的TIXML_DEFAULT_ENCODING值,TinyXML可以被强制成总是使用某一种编码。

除非以下情况发生,否则TinyXML会默认使用Legacy模式:
如果文件或者数据流以非标准但普遍的"UTF-8引导字节" (0xef 0xbb 0xbf)开始,TinyXML会以UTF-8的方式来读取它。
如果包含有encoding="UTF-8"的声明被读取,那么TinyXML会以UTF-8的方式来读取它。
如果读取到没有指定编码方式的声明,那么TinyXML会以UTF-8的方式来读取它。
如果包含有encoding=“其它编码”的声明被读取,那么TinyXML会以Legacy模式来读取它。在Legacy模式下,TinyXML会像以前那样工作,虽然已经不是很清楚这种模式是如何工作的了,但旧的内容还得保持能够运行。
除了上面提到的情况,TinyXML会默认运行在Legacy模式下。

如果编码设置错误或者检测到错误会发生什么事呢?TinyXML会尝试跳过这些看似不正确的编码,你可能会得到一些奇怪的结果或者乱码,你可以强制TinyXML使用正确的编码模式。

通过使用LoadFile( TIXML_ENCODING_LEGACY )或者LoadFile( filename, TIXML_ENCODING_LEGACY ), 你可以强制TinyXML使用Legacy模式。你也可以通过设置TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY来强制一直使用Legacy模式。同样的,你也可以通过相同的方法来强制设置成 TIXML_ENCODING_UTF8。

对于使用英文XML的英语用户来说,UTF-8跟low-ASCII是一样的。你不需要知道UTF-8或者一点也不需要修改你的代码。你可以把UTF-8当作是ASCII的超集。

UTF-8并不是一种双字节格式,但它是一种标准的Unicode编码!TinyXML当前不使用或者直接支持wchar,TCHAR,或者微软的 _UNICODE。"Unicode"这个术语被普遍地认为指的是UTF-16(一种unicode的宽字节编码)是不适当的,这是混淆的来源。

对于“high-ascii”语言来说——几乎所有非英语语言,只要XML被编码成UTF-8, TinyXML就能够处理。说起来可能有点微妙,比较旧的程序和操作系统趋向于使用“默认”或者“传统”的编码方式。许多应用程序(和几乎所有现在的应用 程序)都能够输出UTF-8,但是那些比较旧或者难处理的(或者干脆不能使用的)系统还是只能以默认编码来输出文本。

比如说,日本的系统传统上使用SHIFT-JIS编码,这种情况下TinyXML就无法读取了。但是一个好的文本编辑器可以导入SHIFT-JIS的文本然后保存成UTF-8编码格式的。

Skew.org link上关于转换编码的话题做得很好。

测试文件“utf8test.xml”包含了英文、西班牙文、俄文和简体中文(希望它们都能够被正确地转化)。“utf8test.gif”文件是从IE 上截取的XML文件快照。请注意如果你的系统上没有正确的字体(简体中文或者俄文),那么即使你正确地解析了也看不到与GIF文件上一样的输出。同时要注 意在一个西方编码的控制台上(至少我的Windows机器是这样),Print()或者printf()也无法正确地显示这个文件,这不关TinyXML 的事——这只是操作系统的问题。TinyXML没有丢掉或者损坏数据,只是控制台无法显示UTF-8而已。

实体

TinyXML认得预定义的特殊“字符实体”,即:


&amp; &
&lt; <
&gt; >
&quot; "
&apos; ‘

这些在XML文档读取时都会被辨认出来,并会被转化成等价的UTF-8字符。比如下面的XML文本:


Far &amp; Away

从TiXmlText 对象查询出来时会变成"Far & Away"这样的值,而写回XML流/文件时会以“&amp;”的方式写回。老版本的TinyXML“保留”了字符实体,而在新版本中它们会被转化成字符串。

另外,所有字符都可以用它的Unicode编码数字来指定, "&#xA0;"和"&#160;"都表示不可分的空格字符。

打印

TinyXML有几种不同的方式来打印输出,当然它们各有各的优缺点。
Print( FILE* ):输出到一个标准C流中,包括所有的C文件和标准输出。
"相当漂亮的打印", 但你没法控制打印选项。
输出数据直接写到FILE对象中,所以TinyXML代码没有内存负担。
被Print()和SaveFile()调用。

operator<<:输出到一个c++流中。
与C++ iostreams集成在一起。
在"network printing"模式下输出没有换行符,这对于网络传输和C++对象之间的XML交换有好处,但人很难阅读。
TiXmlPrinter:输出到一个std::string或者内存缓冲区中。
API还不是很简练。
将来会增加打印选项。
在将来的版本中可能有些细微的变化,因为它会被改进和扩展。



设置了TIXML_USE_STL,TinyXML就能支持C++流(operator <<,>>)和C(FILE*)流。但它们之间有些差异你需要知道:

C风格输出:
基于FILE*
用Print()和SaveFile()方法

生成具有很多空格的格式化过的输出,这是为了尽可能让人看得明白。它们非常快,而且能够容忍XML文档中的格式错误。例如一个XML文档包含两个根元素和两个声明仍然能被打印出来。

C风格输入:
基于FILE*
用Parse()和LoadFile()方法

速度快,容错性好。当你不需要C++流时就可以使用它。

C++风格输出:
基于std::ostream
operator<<

生成压缩过的输出,目的是为了便于网络传输而不是为了可读性。它可能有些慢(可能不会),这主要跟你系统上ostream类的实现有关。无法容忍格式错误的XML:此文档只能包含一个根元素。另外根级别的元素无法以流形式输出。

C++风格输入:
基于std::istream
operator>>

从流中读取XML使其可用于网络传输。通过些小技巧,它知道当XML文档读取完毕时,流后面的就一定是其它数据了。TinyXML总假定当它读取到根结点 后XML数据就结束了。换句话说,那些具有不止一个根元素的文档是无法被正确读取的。另外还要注意由于STL的实现和TinyXML的限 制,operator>>会比Parse慢一些。

空格

对是保留还是压缩空格这一问题人们还没达成共识。举个例子,假设‘_’代表一个空格,对于"Hello____world",HTML和某些XML解析器 会解释成"Hello_world",它们压缩掉了一些空格。而有些XML解析器却不会这样,它们会保留空格,于是就是“Hello____world” (记住_表示一个空格)。其它的还建议__Hello___world__应该变成Hello___world 。

这是一个解决得不能让我满意的问题。TinyXML一开始就两种方式都支持。调用TiXmlBase::SetCondenseWhiteSpace( bool )来设置你想要的结果,默认是压缩掉多余的空格。

如果想要改变默认行为,你应该在解析任何XML数据之前调用TiXmlBase::SetCondenseWhiteSpace( bool ) ,而且我不建议设置之后再去改动它。

句柄

想要健壮地读取一个XML文档,检查方法调用后的返回值是否为null是很重要的。一种安全的检错实现可能会产生像这样的代码:


TiXmlElement* root = document.FirstChildElement( "Document" );
if ( root )
{
     TiXmlElement* element = root->FirstChildElement( "Element" );
     if ( element )
     {
         TiXmlElement* child = element->FirstChildElement( "Child" );
         if ( child )
         {
             TiXmlElement* child2 = child->NextSiblingElement( "Child" );
             if ( child2 )
             {
                 // Finally do something useful.

用句柄的话就不会这么冗长了,使用TiXmlHandle类,前面的代码就会变成这样:


TiXmlHandle docHandle( &document );
TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
if ( child2 )
{
     // do something useful

这处理起来容易多了。 查阅TiXmlHandle可以得到更多的信息。

行列追踪

对于某些应用程序来说,能够追踪节点和属性在它们源文件中的原始位置是很重要的。另外,知道解析错误在源文件中的发生位置可以节省大量时间。

TinyXML能够追踪所有结点和属性在文本文件中的行列原始位置。TiXmlBase::Row() 和 TiXmlBase::Column() 方法返回结点在源文件中的原始位置。正确的制表符号可以经由TiXmlDocument::SetTabSize() 来配置。

使用与安装

编译与运行xmltest:

提供了一个Linux Makefile和一个Windows Visual C++ .dsw 文件。只需要简单地编译和运行,它就会在你的磁盘上生成demotest.xml文件并在屏幕上输出。它还尝试用不同的方法遍历DOM并打印出结点数。

那个Linux makefile很通用,可以运行在很多系统上——它目前已经在mingw和MacOSX上测试过。你不需要运行 ‘make depend’,因为那些依赖关系已经硬编码在文件里了。

用于VC6的Windows项目文件
tinyxml: tinyxml 库,非STL
tinyxmlSTL: tinyxml 库,STL
tinyXmlTest: 用于测试的应用程序,非STL
tinyXmlTestSTL: 用于测试的应用程序,STL

Makefile

在makefile的顶部你可以设置:

PROFILE,DEBUG,和TINYXML_USE_STL。makefile里有具体描述。

在tinyxml目录输入“make clean”然后“make”,就可以生成可执行的“xmltest”文件。

在某一应用程序中使用:

把tinyxml.cpp,tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, 和 tinystr.h 添加到你的项目和makefile中。就这么简单,它可以在任何合理的C++适用系统上编译。不需要为TinyXML打开异常或者运行时类型信息支持。

TinyXML怎么工作

举个例子可能是最好的办法,理解一下:


<?xml version="1.0" standalone=no>
<!– Our to do list data –>
<ToDo>
<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
<Item priority="2"> Do bills</Item>
</ToDo>

它称不上是一个To Do列表,但它已经足够了。像下面这样读取并解析这个文件(叫“demo.xml”)你就能创建一个文档:

TiXmlDocument doc( "demo.xml" );
doc.LoadFile();

现在它准备好了,让我们看看其中的某些行和它们怎么与DOM联系起来。


<?xml version="1.0" standalone=no>

第一行是一个声明,它会转化成TiXmlDeclaration 类,同时也是文档结点的第一个子结点。

这是TinyXML唯一能够解析的指令/特殊标签。一般来说指令标签会保存在TiXmlUnknown 以保证在它保存回磁盘时不会丢失这些命令。


<!– Our to do list data –>

这是一个注释,会成为一个TiXmlComment对象。


<ToDo>

"ToDo"标签定义了一个TiXmlElement 对象。它没有任何属性,但包含另外的两个元素。


<Item priority="1">

生成另一个TiXmlElement对象,它是“ToDo”元素的子结点。此元素有一个名为“priority”和值为“1”的属性。


Go to the

TiXmlText ,这是一个叶子结点,它不能再包含其它结点,是"Item" TiXmlElement的子结点。


<bold>

另一个TiXmlElement, 这也是“Item”元素的子结点。

等等

最后,看看整个对象树:


TiXmlDocument "demo.xml"
TiXmlDeclaration "version=’1.0′" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills"


文档

本文档由Doxygen使用‘dox’配置文件生成。

许可证

TinyXML基于zlib许可证来发布:

本软件按“现状”提供(即现在你看到的样子),不做任何明确或隐晦的保证。由使用此软件所引起的任何损失都决不可能由作者承担。

只要遵循下面的限制,就允许任何人把这软件用于任何目的,包括商业软件,也允许修改它并自由地重新发布:

1. 决不能虚报软件的来源;你决不能声称是你是软件的第一作者。如果你在某个产品中使用了这个软件,那么在产品文档中加入一个致谢辞我们会很感激,但这并非必要。

2. 修改了源版本就应该清楚地标记出来,决不能虚报说这是原始软件。

3. 本通告不能从源发布版本中移除或做修改。

参考书目

万维网联盟是定制XML的权威标准机构,它的网页上有大量的信息。

权威指南:http://www.w3.org/TR/2004/REC-xml-20040204/

我还要推荐由OReilly出版由Robert Eckstein撰写的"XML Pocket Reference"……这本书囊括了入门所需要的一切。

捐助者,联系人,还有简史

非常感谢给我们建议,漏洞报告,意见和鼓励的所有人。它们很有用,并且使得这个项目变得有趣。特别感谢那些捐助者,是他们让这个网站页面生机勃勃。

有很多人发来漏洞报告和意见,与其在这里一一列出来不如我们试着把它们写到“changes.txt”文件中加以赞扬。

TinyXML的原作者是Lee Thomason

xml dom结构概念图解


                                       实例XML文档内容:
xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="">
  
<book id="bk101">
     
<author>Matthewauthor>
     
<title>XML Developertitle>
     
<genre>Computergenre>
     
<price>44.95price>
     
<publish_date>2000-10-01publish_date>
     
<description>After an inadvertant description>
  
book>
  
<book id="bk109">
     
<author>Kress, Peterauthor>
     
<title>Paradox Losttitle>
     
<genre>Science Fictiongenre>
     
<price>6.95price>
     
<publish_date>2000-11-02publish_date>
     
<description>James Salway discoversdescription>
  
book>
catalog>

对应的概念术语:
 

对应的API接口(暂且这么称呼):
<book id="bk109"> book> 就是 IXMLDOMNode
所有的<book> 就是  IXMLDOMNodeList
authortitleprice 这些则是 IXMLDOMElement 
authortitleprice 的值则是 IXMLDOMText

2012年6月5日星期二

国家公务员-部级-厅级-处级-科级-干部等级排列


国家公务员的级别分为十五级。职务与级别的对应关系是:
(一)国务院总理:一级;
(二)国务院副总理,国务委员:二至三级;
(三)部级正职,省级正职:三至四级;
(四)部级副职,省级副职:四至五级;
(五)司级正职,厅级正职,巡视员:五至七级;
(六)司级副职,厅级副职,助理巡视员:六至八级;
(七)处级正职,县级正职,调研员:七至十级;
(八)处级副职,县级副职,助理调研员:八至十一级;
(九)科级正职,乡级正职,主任科员:九至十二级;
(十)科级副职,乡级副职,副主任科员:九至十三级;
(十一)科员:九至十四级;
(十二)办事员:十至十五级。 股级不属于公务员级别。最低就是办事员,相当于大专学历。本科毕业则是科员待遇,硕士为副科,博士为正科。 国干部级别划分(以政府和军队为例,不含党委、人大、政协)
  国家级:
  国务院总理(一级)
  国务院副总理(二级)
  国务院常委(三级)
  正省级干部(正部级干部):
  国务院各部委正职干部(如教育部部长、国家发改委主任)
  各省、自治区、直辖市政府 正职干部(如江苏省省长、天津市市长)
  部队正军职干部(如江苏省军区司令员、12军军长)
  副省级干部(副部级干部):
  国务院各部委副职干部(如公安部副部长、国家体育总局副局长)
  国务院部委管理的国家局正职干部(如国家文物总局局长)
  各省、自治区、直辖市政府副职干部(如安徽省副省长、重庆市副市长)
  各副省级市政府正职干部(如南京市市长)
  部队副军职干部(如浙江省警备司令部副司令、31军副军长)
  正厅级干部(地市级干部):
  国务院部委各司正职干部(如教育部社会科学研究与思想政治工作司司长)
  各省、自治区、直辖市厅局正职干部(如河北省交通厅厅长,北京市财政局局长)
  各副省级市政府副职干部(如宁波市副市长)
  各地级市政府正职干部(如无锡市市长)
  部队正师职干部(如1军后勤部部长、34师政委)
  注:以上为高级干部副厅级干部:
  国务院部委各司副职干部(如人事部人才流动开发司副司长)
  各省、自治区、直辖市厅局副职干部(如黑龙江省建设厅副厅长、上海市文化局副局长)
  副省级市所属各局及各区县政府正职干部(如南京市教育局局长、江宁区区长)
  各地级市政府副职干部(如苏州市副市长)
  部队副师职干部(如35师副政委、179旅旅长)
  正处级干部(县团级干部):
  国务院部委各司所属处室正职干部(如农业部种植业管理司经济作物处处长)
  各省、自治区、直辖市厅局所属处室正职干部(如江苏省科技厅农村科技处处长)
  副省级市所属各局及各区县政府副职干部(如沈阳市卫生局副局长、浦口区副区长)
  地级市所属各局及各区县政府正职干部(如扬州市劳动局局长、滨海县县长)
  部队正团职干部(如105团政委)
  副处级干部:
  国务院部委各司所属处室副职干部(如农业部兽医局防疫处副处长)
  各省、自治区、直辖市厅局所属处室副职干部(如江苏省教育厅人事处副处长)
  副省级市所属各局处室及区县各局正职干部(如南京市科技局科技成果处处长、玄武区卫生局局长)
  地级市所属
  各局及各区县政府副职干部(如镇江市民政局副局长、张家港市副市长)
  部队副团职干部(如105团参谋长)
  正科级、副科级干部略注:各高等院校、科研院所、医院等事业单位,其各级干部参照政府各级干部待遇,但不具有行政级别,不属于公务员编制政府各级干部如为上一级党委常委,则其行政级别升一级。如张家港市市长为正处级干部
,若为苏州市市委常委,则为副厅级干部按例,高级干部在60或65岁以后往往调往相应级别的人大、政协担任领导职务,俗称“退居二线”正省级干部约略相当于清代之巡抚与布政使,为从二品副省级干部约略相当于清代之按察使,为正
三品正厅级干部约略相当于清代之知府,为从四品副厅级干部约略相当于清代之同知,为正五品正处级干部约略相当于清代之知县,为正七品副处级干部约略相当于清代之县丞,为正八品副处级干部约略相当于清代之县丞,为正八品 。
《中华人民共和国公务员法》第十六条 :
公务员职务分为领导职务和非领导职务。
领导职务层次分为:国家级正职、国家级副职、省部级正职、省部级副职、厅局级正职、厅局级副职、县处级正职、县处级副职、乡科级正职、乡科级副职。
非领导职务层次在厅局级以下设置。
1.国家级正职:
(包括国家主席、中央军委主席、中共中央政治局常委、国务院总理、全国政协主席、全国人大常委会委员长等国家头号人物)
2.国家级副职:
(包括国家副主席、中央军委副主席、中共中央政治局委员、国务委员、全国政协副主席、全国人大常委会副委员长、全国人大常委等)
3.省部级正职:
(包括各个省级行政区的省委书记、省长、省政协主席、省人大常委会主席等、特别行政区行政长官、直辖市市委书记等。以及国家各部部长等)
国务院各部委正职干部(如教育部部长、国家发改委主任)
各省、自治区、直辖市政府正职干部(如江苏省省长、天津市市长)
部队正军职干部(如江苏省军区司令员、12军军长)
4.省部级副职:
(包括各个省级行政区的省委副书记、副省长、省政协副主席、省人大常委会副主席、省人大常委等(行、直辖市市委副书记等。以及国家各部副部长等,还有一些行政级别是正厅但是必须要副布来兼任的,一般认为那个单位是副部单位
如省宣传部、组织部、纪委等必须由省委常委或者省委副书记兼任。
国务院各部委副职干部(如公安部副部长、国家体育总局副局长)
国务院部委管理的国家局正职干部(如国家文物总局局长)
各省、自治区、直辖市政府副职干部(如安徽省副省长、重庆市副市长)
各副省级市政府正职干部(如南京市市长)
部队副军职干部(如浙江省警备司令部副司令、31军副军长)
5.厅局级正职:
以前叫地厅级,主要是地级市(各自治州)市委书记、市长、市人大主席、市政协主席、省级下属单位,如省公安厅厅长、国家各部下属单位,如外交部新闻司司长
国务院部委各司正职干部(如教育部社会科学研究与思想政治工作司司长)
各省、自治区、直辖市厅局正职干部(如河北省交通厅厅长,北京市财政局局长)
各副省级市政府副职干部(如宁波市副市长)
各地级市政府正职干部(如无锡市市长)
部队正师职干部(如1军后勤部部长、34师政委)
注:以上为高级干部
6.厅局级副职:
地级市市委副书记、市委常委、副市长、市人大副主席、市政副协主席、,省级下属单位,如省委宣传部副部长、国家各部下属单位,如外交部新闻司副司长等,还有一些行政级别是正处但是必须要副厅来兼任的,一般认为那个单位是副
厅单位,如市政法委,市宣传部、组织部、纪委等必须由市委常委或者市委副书记兼任。
国务院部委各司副职干部(如人事部人才流动开发司副司长)
各省、自治区、直辖市厅局副职干部(如黑龙江省建设厅副厅长、上海市文化局副局长)
副省级市所属各局及各区县政府正职干部(如南
部队副师职干部(如35师副政委、179旅旅长)
7.县处级正职:
包括县(县级市、区、旗等)委书记、(区)县长、(区)县人大、(区)县政协主席、市各单位局长,如市公安局、司法局等,还有厅级各单位下属,如省公安厅X处,省委办公厅主任等
国务院部委各司所属处室正职干部(如农业部种植业管理司经济作物处处长)
各省、自治区、直辖市厅局所属处室正职干部(如江苏省科技厅农村科技处处长)
副省级市所属各局及各区县政府副职干部(如沈阳市卫生局副局长、浦口区副区长)
地级市所属各局及各区县政府正职干部(如扬州市劳动局局长、滨海县县长)
部队正团职干部(如105团政委)
8.县处级副职:
包括县(县级市、区、旗等)委副书记、县(区)委常委、(区)副县长、(区)县人大、(区)县政协主席、市各单位局长,如市公安局、司法局等,还有厅级各单位下属,如省公安厅X处,省委办公厅主任等。
国务院部委各司所属处室副职干部(如农业部兽医局防疫处副处长)
各省、自治区、直辖市厅局所属处室副职干部(如江苏省教育厅人事处副处长)
副省级市所属各局处室及区县各局正职干部(如南京市科技局科技成果处处长、玄武区卫生局局长)
地级市所属各局及各区县政府副职干部(如镇江市民政局副局长、张家港市副市长)
部队副团职干部(如105团参谋长)
9.乡科级正职:
包括各乡、镇、办事处党委书记、乡长、镇长、办事处主任、以及镇级人大等,还有处级下属,如县公安局长等
10.乡科级副职:
包括各乡、镇、办事处党委副书记、党委委员、副乡长、副镇长、办事处副主任、以及镇级人大副主任等,还有处级下属,如县公安副局长等
乡科级在往下,就是所谓股级,是中国行政当中最小的,一般是乡里边财政所、派出所之类的