一、这里只介绍简单的三个客户端异步通信(完全图拓扑结构)

  //建立管道
mkfifo

open顺序:

cl1 读 , cl2 cl3 向 cl1写

cl2 读 , cl1 cl3 向 cl2写

cl3 读 , cl1 cl2 向 cl3写

顺序的规律就是 第i个 客户端读 其他各个客户端 ,其他的各个客户端 向 i 写 ,i 从 1 到 3.

cl1 代码:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include <sys/time.h>
#include<sys/select.h>
#include <sys/select.h> /* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> int main(int argc, char* argv[])//
{ int fd21, fd31,fd12,fd13 ;
fd21 = open("", O_RDONLY);
fd31 = open("", O_RDONLY); fd12 = open("",O_WRONLY); fd13 = open("",O_WRONLY);
printf("OK!\n"); printf("OK!\n");
fd_set read_sets ;
fd_set write_sets ;
int iret,iwrt ;
char buf[] ;
struct timeval tm ;
while()
{ tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&read_sets);
FD_ZERO(&write_sets); FD_SET(fd21, &read_sets);
FD_SET(fd31, &read_sets);
FD_SET( , &write_sets);
//FD_SET(fd12, &write_sets);
//FD_SET(fd13, &write_sets); iret = select(, &read_sets, NULL, NULL, &tm);
iwrt = select(,&write_sets,NULL,NULL,&tm); //读
if(iret != )
{
printf("active: %d\n", iret); if(FD_ISSET(fd21, &read_sets))
{
memset(buf, , );
read(fd21, buf, );
printf("from 2: %s\n", buf);
}
if(FD_ISSET(fd31, &read_sets))
{
memset(buf, , );
read(fd31, buf, );
printf("from 3: %s\n", buf);
}
} // write
if(iwrt != )
{
printf("active: %d\n", iwrt);
if(FD_ISSET( /*fd12*/, &write_sets))
{
memset(buf, , );
read(, buf, ) ;
write(fd12, buf, strlen(buf));
write(fd13, buf, strlen(buf));
}
/*if(FD_ISSET(fd13, &write_sets))
{
memset(buf, 0, 128);
read(0, buf, 127) ;
write(fd13, buf, strlen(buf));
}*/
} }
return ;
}

cl2 代码:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/select.h>
int main(int argc, char* argv[])//
{
int fd12, fd32,fd21,fd23 ;
fd21 = open("",O_WRONLY); fd12 = open("", O_RDONLY);
fd32 = open("", O_RDONLY); fd23 = open("",O_WRONLY); fd_set read_sets ,write_sets ;
int iret ,iwrt;
char buf[] ;
struct timeval tm ;
while()
{ tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&read_sets);
FD_ZERO(&write_sets);
FD_SET(fd12, &read_sets);
FD_SET(fd32, &read_sets);
FD_SET( , &write_sets);
//FD_SET(fd21,&write_sets);
//FD_SET(fd23,&write_sets); iret = select(, &read_sets, NULL, NULL, &tm);
iwrt = select(,&write_sets,NULL,NULL,&tm); if(iret != )
{
printf("active: %d\n", iret); if(FD_ISSET(fd12, &read_sets))
{
memset(buf, , );
read(fd12, buf, );
printf("from 1: %s\n", buf);
}
if(FD_ISSET(fd32, &read_sets))
{
memset(buf, , );
read(fd32, buf, );
printf("from 3: %s\n", buf);
}
} // write
if(iwrt != )
{
printf("active: %d\n", iwrt);
if(FD_ISSET( , &write_sets))
{
memset(buf, , );
read(, buf, ) ;
write(fd21, buf, strlen(buf));
write(fd23, buf, strlen(buf));
}
/* if(FD_ISSET(fd23, &write_sets))
{
memset(buf, 0, 128);
read(0, buf, 127) ;
write(fd23, buf, strlen(buf));
}*/
} }
return ;
}

cl3 代码:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/select.h>
int main(int argc, char* argv[])//
{
int fd13, fd23,fd31,fd32 ;
fd31 = open("",O_WRONLY); fd32 = open("",O_WRONLY); fd13 = open("", O_RDONLY);
fd23 = open("", O_RDONLY); printf("OK!\n");
fd_set read_sets ,write_sets ;
int iret,iwrt ;
char buf[] ;
struct timeval tm ;
while()
{ tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&read_sets);
FD_ZERO(&write_sets);
FD_SET(fd13, &read_sets);
FD_SET(fd23, &read_sets);
//FD_SET(fd31,&write_sets);
//FD_SET(fd32,&write_sets);
FD_SET( , &write_sets); iret = select(, &read_sets, NULL, NULL, &tm);
iwrt = select(,&write_sets,NULL,NULL,&tm); //读
if(iret != )
{
printf("active: %d\n", iret); if(FD_ISSET(fd13, &read_sets))
{
memset(buf, , );
read(fd13, buf, );
printf("from 1: %s\n", buf);
}
if(FD_ISSET(fd23, &read_sets))
{
memset(buf, , );
read(fd23, buf, );
printf("from 2: %s\n", buf);
}
} // write
if(iwrt != )
{
printf("active: %d\n", iwrt);
if(FD_ISSET( , &write_sets))
{
memset(buf, , );
read(, buf, ) ;
write(fd31, buf, strlen(buf));
write(fd32, buf, strlen(buf));
}
/*if(FD_ISSET(fd32, &write_sets))
{
memset(buf, 0, 128);
read(0, buf, 127) ;
write(fd32, buf, strlen(buf));
}*/
}
} return ;
}

二 、n个客户端异步通信 (线性链表的拓扑结构)

很显然的,如果用上述的方法需要每个客户端和其他客户端都直接相邻,即完全图。

建立n个客户端通信,需要 2*((n-1)+(n-2)+(n-3)+……3+2+1) = 2*(n-1 + 1)*(n -1)/2 =n * (n-1) 根管道,

这么多的管道连接会使得代码实现变得非常冗杂、而且系统浪费资源管道。

这里,用线性链表的拓扑结构,可以解决这个问题:

1、         客户端以线性存储

2、         当 pre 发来数据时, 打印出来,并且转发给next(若next存在)。

3、         当 next 发来数据时, 打印出来,并且转发给pre(若pre存在)。

4、         当键盘发来数据时,转发给next(若next存在),转发给pre(若pre存在)。

例子:

1、客户端拓扑结构为 1——3——2——4

在文件存储如下:

2、我还编写一个读取topo.txt 文件 ,自动生成管道的代码:

BuildFIFO.cpp 如下:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include <sys/time.h>
#include<sys/select.h>
using namespace std;
int main(int argc, char* argv[])//
{ FILE* topu = fopen("topo.txt","r");
int fir = ;
char dir[],DIR[];
string str1,str2,str ;
while(!feof(topu))
{
fscanf(topu ,"%s\n",dir);
str1 = dir;
if(fir)
{
fir = ;
str2=str1;
continue;
}
str=str1+"T"+str2;
strcpy(DIR,str.c_str());
mkfifo(DIR,); str=str2+"T"+str1;
strcpy(DIR,str.c_str());
mkfifo(DIR,);
str2 = str1;
} fclose(topu); return ;
}

3、从客户端3键盘输入数据后,发送到各个客户端:

4、这里也有个 open 的 顺序的问题,但其实这种拓扑结构很好解决这个问题:

只需要每个相邻的客户端 读写顺序相反就能解决了

如下:

 if(count & == ) //判断节点的位置是奇数 还是 偶数 ,如果是 奇数 就 先读后写
{
if(strcmp("-1",pre->val)!=)
{ fdReadFromPre = My_Open(pre->val,p->val,);
fdWriteToPre = My_Open(p->val,pre->val,);
} if(p->next!=NULL)
{
fdReadFromNext = My_Open(p->next->val,p->val,);
fdWriteToNext = My_Open(p->val,p->next->val,);
}
}
else //如果是偶数,先写后读
{
if(strcmp("-1",pre->val)!=)
{
fdWriteToPre = My_Open(p->val,pre->val,);
fdReadFromPre = My_Open(pre->val,p->val,);
} if(p->next!=NULL)
{
fdWriteToNext = My_Open(p->val,p->next->val,);
fdReadFromNext = My_Open(p->next->val,p->val,);
} }

5、各客户端代码:

这里只发 cl1.cpp

其他客户端就是

  while( strcmp("",p->val)!=)
  char tembuf[] = "Form1 :";

这两句代码不一样而已

如下:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include <sys/time.h>
#include<sys/select.h> #define fdNULL -9999 struct node
{
char val[];
node* next;
}; int My_Open(char A[],char B[],int type)
{
char Cstr[];
memset( Cstr, '\0', sizeof(Cstr) );
strcat(Cstr,A);
strcat(Cstr,"T");
strcat(Cstr,B);
if(type == ) return open(Cstr, O_RDONLY);
else return open(Cstr, O_WRONLY);
} int main(int argc, char* argv[])//
{ FILE* topu = fopen("/home/soso/Desktop/1-30/LineSelect/topo.txt","r");
char a[]; node* L = (node*)calloc(, sizeof(node)); //save topo
strcpy(L->val,"-1");
L->next = NULL;
node* tem , *p ,*pre;
p=L;
while(!feof(topu))
{
fscanf(topu ,"%s\n",a);
tem= (node*)calloc(, sizeof(node));
strcpy(tem->val,a);
tem->next = NULL;
p->next=tem;
p=p->next;
}
fclose(topu); pre=L;
p= L->next;
int count = ;
while( strcmp("",p->val)!=)
{
p=p->next;
pre=pre->next;
++count;
} int fdReadFromPre,fdReadFromNext,fdWriteToPre,fdWriteToNext ;
fdReadFromPre=fdReadFromNext=fdWriteToPre=fdWriteToNext=fdNULL;
if(count & == ) //判断节点的位置是奇数 还是 偶数 ,如果是 奇数 就 先读后写
{
if(strcmp("-1",pre->val)!=)
{ fdReadFromPre = My_Open(pre->val,p->val,);
fdWriteToPre = My_Open(p->val,pre->val,);
} if(p->next!=NULL)
{
fdReadFromNext = My_Open(p->next->val,p->val,);
fdWriteToNext = My_Open(p->val,p->next->val,);
}
}
else //如果是偶数,先写后读
{
if(strcmp("-1",pre->val)!=)
{
fdWriteToPre = My_Open(p->val,pre->val,);
fdReadFromPre = My_Open(pre->val,p->val,);
} if(p->next!=NULL)
{
fdWriteToNext = My_Open(p->val,p->next->val,);
fdReadFromNext = My_Open(p->next->val,p->val,);
} } printf("OK!\n"); fd_set read_sets ;
fd_set write_sets ;
int iret,iwrt ;
char buf[] ;
struct timeval tm ;
while()
{ tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&read_sets);
FD_ZERO(&write_sets);
if(fdReadFromPre != fdNULL)
FD_SET(fdReadFromPre, &read_sets);
if(fdReadFromNext != fdNULL)
FD_SET(fdReadFromNext, &read_sets);
FD_SET( , &write_sets); iret = select(, &read_sets, NULL, NULL, &tm);
iwrt = select(,&write_sets,NULL,NULL,&tm); //读
if(iret != )
{ if(FD_ISSET(fdReadFromPre, &read_sets))
{
memset(buf, , );
read(fdReadFromPre, buf, );
if(fdWriteToNext!=fdNULL) //把从pre读过来的数据转发到next去
write(fdWriteToNext, buf, strlen(buf));
printf("%s\n" ,buf);
}
if(FD_ISSET(fdReadFromNext, &read_sets))
{
memset(buf, , );
read(fdReadFromNext, buf, );
if(fdWriteToPre!=fdNULL) //把从next读过来的数据转发到pre去
write(fdWriteToPre, buf, strlen(buf));
printf("%s\n", buf);
}
} // write
if(iwrt != )
{ if(FD_ISSET( , &write_sets))
{
memset(buf, , );
read(, buf, ) ;
char tembuf[] = "Form1 :";
strcat(tembuf,buf);
if(fdWriteToNext!=fdNULL) //把从键盘输入的数据向next、pre 转发
write(fdWriteToNext, tembuf, strlen(tembuf));
if(fdWriteToPre!=fdNULL)
write(fdWriteToPre, tembuf, strlen(tembuf));
}
} }
return ;
}

6、添加的客户端

1、在topo.txt 添加 客户名 再 换行

2、再按一下 已经生成的 BuildFIFO 可执行文件,及自动生成所需的管道

3、vim 出客户端,代码只需 改动两处(见5) 便可以完成客户端的添加。

三 、n个客户端异步通信 (无环图的拓扑结构)

线性拓扑结构有个很大的缺陷

如图:

客户端1 发送消息,要经过 3、2 的转发才能到达 4。当客户端数量很大时,链表前部和后部之间的通信的延迟会很大。

如果改进,用树形拓扑机构就会很大的缓解这个问题。

1、 《计算机网络》的OSPF路由算法里面提到的泛洪法+无环图拓扑结构

如图 为Zhu客户端键盘输入数据:

2、存储结构

在文件topo.txt 中以类似于邻接的方式存储:

topo文件格式为:

顶点 节点个数 节点1 节点2 ……

如图:

客户端读取文件后的邻接表存储代码:

 map<string,bool> visit;

 struct TreeLine
{
vector<string> TreeNode;
int level; //层号
}; map<string,TreeLine> Tree;
     FILE* topu = fopen("topo.txt","r");
int fir = ;
int i,j;
char strtem[],strtem2[],tem,Lval[];
int num;
while(!feof(topu))
{
fscanf(topu ,"%s %d",strtem,&num);
if(fir) //记录第一个客户端的名称
{
fir = ;
strcpy(Lval,strtem);
} TreeLine TemLine;
for(int i = ;i< num;i++)
{
fscanf(topu," %s",strtem2);
TemLine.TreeNode.push_back(strtem2);
}
fgetc(topu); Tree[strtem]=TemLine;
visit[strtem] = false; //初始化访问位
}
fclose(topu);

3、DFS来标注奇偶层号,判断open顺序(只要奇偶层顺序相反)

 void DFS(string val,int level)
{
visit[val] = true ;
Tree[val].level = level;
//cout<<val<<":"<<level<<" "<<Tree[val].TreeNode.size()<<endl;
int i;
for(i = ;i<Tree[val].TreeNode.size();++i)
{
if(visit[Tree[val].TreeNode[i]] == false)
DFS(Tree[val].TreeNode[i],level+);
}
}
 int level = ;
DFS(Lval,level); vector<int> fdReadOpen,fdWriteOpen; string TemString;
if(Tree[UserName].level & == ) //判断层号 奇数先读后写
{
for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
} for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString = UserName;
TemString+="TO"+Tree[UserName].TreeNode[i];
fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
} }
else //判断层号 偶数数先写后读
{
for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString = UserName;
TemString+="TO"+Tree[UserName].TreeNode[i];
fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
} for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
}
}

3、各客户端代码:

这次用了宏定义,每个客户端只需修改:

 #define UserName "Ye"

其他代码都相同。

这里分析客户端 Ye 的代码:

 #include <vector>
#include<map>
#include<string>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include <sys/time.h>
#include<sys/select.h>
using namespace std; #define MaxSize 10000 #define UserName "Ye" map<string,bool> visit; struct TreeLine
{
vector<string> TreeNode;
int level; //层号
}; map<string,TreeLine> Tree; void DFS(string val,int level)
{
visit[val] = true ;
Tree[val].level = level;
//cout<<val<<":"<<level<<" "<<Tree[val].TreeNode.size()<<endl;
int i;
for(i = ;i<Tree[val].TreeNode.size();++i)
{
if(visit[Tree[val].TreeNode[i]] == false)
DFS(Tree[val].TreeNode[i],level+);
}
} int main(int argc, char* argv[])
{ FILE* topu = fopen("topo.txt","r");
int fir = ;
int i,j;
char strtem[],strtem2[],tem,Lval[];
int num;
while(!feof(topu))
{
fscanf(topu ,"%s %d",strtem,&num);
if(fir) //记录第一个客户端的名称
{
fir = ;
strcpy(Lval,strtem);
} TreeLine TemLine;
for(int i = ;i< num;i++)
{
fscanf(topu," %s",strtem2);
TemLine.TreeNode.push_back(strtem2);
}
fgetc(topu); Tree[strtem]=TemLine;
visit[strtem] = false; //初始化访问位
}
fclose(topu); int level = ;
DFS(Lval,level); vector<int> fdReadOpen,fdWriteOpen; string TemString;
if(Tree[UserName].level & == ) //判断层号 奇数先读后写
{
for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
} for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString = UserName;
TemString+="TO"+Tree[UserName].TreeNode[i];
fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
} }
else //判断层号 偶数数先写后读
{
for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString = UserName;
TemString+="TO"+Tree[UserName].TreeNode[i];
fdWriteOpen.push_back(open(TemString.c_str(),O_WRONLY));
} for(i= ;i<Tree[UserName].TreeNode.size();++i)
{
TemString=Tree[UserName].TreeNode[i]+"TO"+UserName;
fdReadOpen.push_back(open(TemString.c_str(), O_RDONLY));
}
} printf("OK!\n"); fd_set read_sets ;
fd_set write_sets ;
int iret,iwrt ;
char buf[] ;
struct timeval tm ;
while()
{ tm.tv_sec = ;
tm.tv_usec = ;
FD_ZERO(&read_sets);
FD_ZERO(&write_sets);
for(i=;i<fdReadOpen.size();i++)
FD_SET(fdReadOpen[i], &read_sets);
FD_SET( , &write_sets); iret = select(, &read_sets, NULL, NULL, &tm);
iwrt = select(,&write_sets,NULL,NULL,&tm); //读
if(iret != )
{ for(i=;i<fdReadOpen.size();i++) //遍历ReadOpen
{
if(FD_ISSET(fdReadOpen[i], &read_sets)) //当收到ReadOpen[i]时
{
memset(buf, , );
read(fdReadOpen[i], buf, );
printf("%s\n" ,buf); //打印出来
for(j=;j<fdWriteOpen.size();j++) //向其他客户端转发
{
if(j != i) //AtoB 和 BtoA 的fdOpen存储位置是对应的
write(fdWriteOpen[j], buf, strlen(buf));
}
}
}
} // write
if(iwrt != )
{
if(FD_ISSET( , &write_sets))
{
memset(buf, , );
read(, buf, ) ;
char tembuf[] = UserName;
strcat(tembuf," :");
strcat(tembuf,buf);
for(i = ;i< fdWriteOpen.size();i++)
write(fdWriteOpen[i], tembuf, strlen(tembuf));
}
} } return ;
}

4、添加的客户端

1、按照输入格式在topo.txt 添加

2、再按一下 已经生成的 BuildFIFO 可执行文件,及自动生成所需的管道

3、vim 出客户端,代码只需 改动一处(见3) 便可以完成客户端的添加。

select 函数实现 三种拓扑结构 n个客户端的异步通信 (完全图+线性链表+无环图)的更多相关文章

  1. JavaScript创建函数的三种方式

    ㈠函数(function) ⑴函数也是一个对象 ⑵函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码) ⑶函数中可以保存一些代码在需要的时候调用 ⑷使用typeof检查一个函数对象时,会返 ...

  2. epoll函数及三种I/O复用函数的对比

    epoll函数 #include <sys/epoll.h>int epoll_create(int size)int epoll_ctl(int epfd, int op, int fd ...

  3. Sql函数的三种写法

    以前复制的创建sql函数比较乱,现在将我自己项目中的三种sql函数做下对比,一目了然: (1)表值函数——方法一:直接创建临时表,并返回临时表.优点:函数体中间可以直接申明临时变量,并做各种逻辑处理, ...

  4. 利用Objective-C运行时hook函数的三种方法

    版权声明:转载请注明出处:http://blog.csdn.net/hursing 方法一,hook已有公开头文件的类: 首先写一个Utility函数: #import <objc/runtim ...

  5. js 函数定义三种方式

    <p>Js 函数定义的三种方式:</p> <br> <p>方式一:function</p> <script type="te ...

  6. 第十篇----------javascript函数的三种定义方式及区别

    javascript定义函数有3种方式: //3种函数定义方式,前两种常用 /** * 1,function 语句式 * 形式:句子 * 名称:有名 * 性质:静态 * 解析时机:优先解析 * 作用域 ...

  7. JS函数的三种方式

    函数,一段能够自动完成某些功能的代码块,函数的出现,既解决了重复使用重一功能的需求,又可以避免代码的臃肿性. 使用函数有两个要求:必须调用后才可以执行;函数名不要和关键字以及系统函数相同; 函数主要有 ...

  8. js函数的三种成创建方式以及它们各自的不同

    js有三种创建函数的方式: 1.function语句(也叫函数声明) function sum(a, b) { return a + b; } sum(1, 2); // 3 2. 函数直接量,又叫函 ...

  9. js自调用匿名函数的三种写法

    第一种: (function(){ console.log(‘hello world”) })() 第二种: (function(){ console.log(‘hello world’) }()) ...

随机推荐

  1. Java基础知识强化102:线程间共享数据

    一.每个线程执行的代码相同: 若每个线程执行的代码相同,共享数据就比较方便.可以使用同一个Runnable对象,这个Runnable对象中就有那个共享数据. public class MultiThr ...

  2. UVA442 Matrix Chain Multiplication 矩阵运算量计算(栈的简单应用)

    栈的练习,如此水题竟然做了两个小时... 题意:给出矩阵大小和矩阵的运算顺序,判断能否相乘并求运算量. 我的算法很简单:比如(((((DE)F)G)H)I),遇到 (就cnt累计加一,字母入栈,遇到) ...

  3. Codeforces Round 190 div.2 322C 321A Ciel and Robot

    唔...这题是数学题. 比赛时做出来,但题意理解错了,以为只要判断那点是不是在线上就行了,发现过不了样例就没提交. 思路:记录每一步的偏移,假设那点是在路径上的某步,然后回推出那一个周期的第一步,判断 ...

  4. alfresco 5.0 document

    http://docs.alfresco.com/community/tasks/imagemagick-config.html

  5. CSS text-transform 属性——转换文本的大小写格式

    可能的值 值 描述 none 默认.定义带有小写字母和大写字母的标准的文本. capitalize 文本中的每个单词以大写字母开头. uppercase 定义仅有大写字母. lowercase 定义无 ...

  6. Evaluation of Expression Tree

    Evaluation of Expression Tree Given a simple expression tree, consisting of basic binary operators i ...

  7. Git CMD - reset: Reset current HEAD to the specified state

    命令格式 git reset [-q] [<tree-ish>] [--] <paths>…​ git reset (--patch | -p) [<tree-ish&g ...

  8. Java集合类 java.util包

    概述   软件包  类  使用  树  已过时  索引  帮助  JavaTM Platform Standard Ed. 6  上一个软件包   下一个软件包 框架    无框架           ...

  9. ios开发入门篇(二):Objective-C的简单语法介绍

    一:面向对象的思想 objective-c与C语言的编程思想不同,C语言是面向过程的编程,而objective-c则是面向对象的编程,所谓面向对象,我个人的理解,就是抽象.将具有一定共同点的实物抽象成 ...

  10. VxWorks 6.9 内核编程指导之读书笔记 -- VxWorks Small-Footprint Configuration

    什么是Small-footprint? Small-footprint常见关键配置? 如何配置Small-footprint? 什么是Small-footprint? Small-footprint配 ...