![]() |
慷慨大方的保温杯 · 《南沙方案》一周年丨穗港澳非遗,在南沙一次性 ...· 2 月前 · |
![]() |
爱运动的移动电源 · 海事及水務局– 澳門特別行政區政府入口網站· 2 月前 · |
![]() |
酷酷的牙膏 · 范思哲花瓶- 包豪斯运动– 原创设计经典与文化· 3 月前 · |
![]() |
开朗的小笼包 · 瑞金时期苏维埃政府机关事务工作(一)· 7 月前 · |
![]() |
眼睛小的米饭 · 非典型展品等待观众细细解读新闻发布会揭秘古埃 ...· 1 年前 · |
|
|
有副作用的表达式是指:表达式的作用本质是用于计算的,原则上只返回一个计算结果,而不会改变表达式中的变量的值。这种 不改变表达式中变量值的表达式叫做无副作用的表达式 。如:x+y,y-z等。除此之外,若 表达式中变量的值被改变则成为有副作用的表达式 ,如x++,y+=2;
由于在宏中宏可能出现在程序的很多位置,也就是表达式会被计算多次,这个时候若表达式有副作用就会GG。
注意不管是到达文件为还是出错,这个时候三个函数的返回值都一样。为了区分这两种情况,常调用ferror或feof函数。
|
|
在大多数的实现中,为每个流在FILE对象中维护了两个标志:
调用clearerr可以清除这两个标志。
从流中读取字符以后,可以使用ungetc将字符押送回流中,压回的字符又可以从流中读出,读出的顺序与压送的顺序相反。
压送的字符不会被写到流中。
|
|
###输出函数
输出函数为以下三个,与输入对应,区别与联系和输入函数相同。
|
|
|
|
|
|
若读取成功返回buf,若读取失败或者读取到文件结尾返回NULL.
虽然ISO要求提供gets函数,但一般使用fgets不要使用gets函数。
|
|
|
|
|
|
返回值为实际读取或写入的对象的个数。对于fread,若文件出错或者读到文件结尾处都可以少于nobj,对于fwrite,若返回值小于nobj,则写入出错。
使用这两个函数存在一个问题就是,他们只能用于读写在同一个系统上已写的数据。若是通过网络挂载的文件则不可行。
fread,fwrie可移植,而read,write不可移植。
|
|
前三个函数若输出成功,则返回输出字符的个数;若输出出错,则返回负值。
sprintf和snprintf若执行成功,则返回存入buf中的字符串的长度,否则返回负值。
|
|
注意:fldwidth可以用*作为占位符,然后在后面对其进行指定。
|
|
FILE实际上是一个struct的typedef,可以在/usr/include/stdio.h中找到它的定义为:
|
|
_IO_FILE_的定义在文件/usr/include/libio.h中,我们可以看到它的具体定义为:
|
|
从上面的struct中可以观察到FILE中是有文件描述符标志的,即为fileno参数。
|
|
上述三个函数 区别以及使用场景 说明:
参数说明:
打开模式说明:
上述所有的模式后面都加上b表示对二进制文件的操作(rb,wb,ab,rb+,wb+,ab+)。
注意:对于fdopen函数由于文件已经由文件描述符打开,此时w模式时将不清除文件内容,追加模式不常见文件。
当以读写模式打开文件时候,将有一些限制。如果中间没有fflush,fseek,fsetpos以及rewind函数,标注输出之后不能直接进行输入;如果没有fseek,fsetpos或者rewind,或者一个输入没有到达文件尾,则输入操作之后不能跟输出操作。
一般情况下在关闭文件流之前通常先使用fflush刷新缓冲区防止数据丢失,关闭标准文件流使用的函数为:
|
|
TCP为一个连接定义了11中状态,并且规定了如何基于当前状态以及该状态下接收的分节(TCP报文段)从一个状态转换为另一个状态。其状态转换图如下所示:
具体转化过程和转换条件如上图所示。
TCP报文段是由首部字段和一个数据字段组成的,数据字段中包含应用程序需要发送的数据。通常报文段中通过MSS(max segment size)来限制报文段数据字段的最大长度。报文段的结构如下:
经过上述三个步骤之后,TCP连接建立成功。客户端进入连接建立状态(ESTABLISHED)。然后就可以相互发送数据了。
为什么要经过三次握手?
三次握手的目的是为了防止失效的报文段突然传送到服务端而出现问题。
上述已经失效的报文段是指:如果客户端在发送第一次连接请求的过程中,由于网络原因导致此报文段在某个网络节点滞留较长时间,这个时候TCP传输协议会视为此报文段已经丢失,于是重传。若此滞留的报文段在连接断开之后才到达服务器,这个时候就会出现问题。
若不是使用三次握手,服务器收到失效的报文段之后会建立连接,故之后无法释放TCP资源。导致资源浪费以致于长期会使服务器宕机。
一段时间(大约4分钟)之后等待状态结束,连接两端进入CLOSED状态。
参考链接:
本系列文章以例子的方式进行呈现。
|
|
本系列文章以例子的方式进行呈现。
|
|
本系列文章以例子的方式进行呈现。
|
|
本系列文章以例子的方式进行呈现。
|
|
protobuffer是google开发的一种数据描述语言,它能够将结构化的数据序列化,并切可以将序列化的数据进行反序列化恢复原有的数据结构。一般用于数据存储以及通信协议方面。
如果是第一次使用protobuffer,我们可以将其与json或者xml进行类比,其实它与json或xml类似都可以作为数据的存储方式,不同的是json和xml是文本格式,而protobuffer是二进制格式。二进制格式不利于使用者直观的阅读,但是与json以及xml相比它有更多的优点。
|
|
由于一些历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。
一般情况下慎重使用required字段,当此字段一定是必要的时候才使用。
repeated使用实例:
|
|
|
|
protobuffer中的数据类型与C++数据类型之间的关联如下图:
protobuffer类型 C++类型当需要定义一个消息类型的时候,我们可能想为某一个字段指定预定义列表中的值。这个时候就需要用到枚举
如:
|
|
在proto数据结构中,每一个变量都有唯一的数字标识。这些标识符的作用是在二进制格式中识别各个字段的,一旦开始使用就不可再改变。
此处需要注意的是1-15之内的标号在存储的时候只占一个字节,而大于15到162047之间的需要占两个字符,所以
我们尽量为频繁使用的字段分配1-15内的标识号
。另外19000-19999之内的标识号已经被预留,不可用。最大标识号为2^29-1。
protobuffer中的消息可以嵌套消息,也就是在一个message中定义另一个message。如上面实例可以看出。
我们可以通过扩展对proto文件进行扩展,而不需要直接区编辑原文件。
例如有原文件:
|
|
上述extensions 100 to 199表示此范围内的标识号被保留为扩展用。我们在扩展文件中就可以使用这些标识号了。
|
|
上述为扩展。当用户的Foo消息被编码的时候,数据的传输格式与用户在Foo里定义新字段的效果是完全一样的。然而,要在程序代码中访问扩展字段的方法与访问普通的字段稍有不同——生成的数据访问代码为扩展准备了特殊的访问函数来访问它。例如,下面是如何在C++中设置bar的值:
|
|
当在需求不断增加的过程中,数据结构也会不断变化,这个时候就需要我们去更新消息。怎么才能做到更新消息不会影响之前的数据和代码。这个时候我们更新消息需要遵循以下几个原则:
为了防止消息明明冲突,我们往往会在文件的开始出生命包,包的作用相当于命名空间。在编译成C++代码时也是namespace。例如:
|
|
在C++对open进行访问的时候的访问方式为:
|
|
按照上面的规则我们可以设计出合理的protobuffer类型。然后下一步就是将proto文件生成C++头文件和实现文件,将.proto文件编译成C接口的方法如下:
|
|
使用proto生成的头文件进行编译时需要链接protobuffer库。具体为:
|
|
对于C++来说,编译器会为每个.proto文件生成一个.h文件和.cc文件。.proto文件中的每一个消息对应一个类。
protobuffer中常用的函数:
|
|
|
|
|
|
|
|
参考链接:
http://blog.csdn.net/mycwq/article/details/19622571
http://colobu.com/2015/01/07/Protobuf-language-guide/
https://worktile.com/tech/share/prototol-buffers
http://tech.meituan.com/serialization_vs_deserialization.html
http://blog.csdn.net/weiwangchao_/article/details/16797763
![]() |
爱运动的移动电源 · 海事及水務局– 澳門特別行政區政府入口網站 2 月前 |
![]() |
酷酷的牙膏 · 范思哲花瓶- 包豪斯运动– 原创设计经典与文化 3 月前 |
![]() |
开朗的小笼包 · 瑞金时期苏维埃政府机关事务工作(一) 7 月前 |