??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲成AV人综合在线观看,亚洲AV无码成人精品区狼人影院 ,亚洲午夜国产精品无码http://www.tkk7.com/faintbear/风嗖嗖的刮着......zh-cnFri, 09 May 2025 12:49:13 GMTFri, 09 May 2025 12:49:13 GMT60静态局部变?/title><link>http://www.tkk7.com/faintbear/archive/2010/01/06/308408.html</link><dc:creator>力力力</dc:creator><author>力力力</author><pubDate>Wed, 06 Jan 2010 03:37:00 GMT</pubDate><guid>http://www.tkk7.com/faintbear/archive/2010/01/06/308408.html</guid><wfw:comment>http://www.tkk7.com/faintbear/comments/308408.html</wfw:comment><comments>http://www.tkk7.com/faintbear/archive/2010/01/06/308408.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/faintbear/comments/commentRss/308408.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/faintbear/services/trackbacks/308408.html</trackback:ping><description><![CDATA[在局部变量前加上“static”关键字,成了静态局部变量。静态局部变量存攑֜内存的全局数据区。函数结束时Q静态局部变量不会消失,每次该函数调? Ӟ也不会ؓ光新分配空间。它始终ȝ在全局数据区,直到E序q行l束。静态局部变量的初始化与全局变量cMQ如果不为其昑ּ初始化,则C++自动为其 初始化ؓ0?br /> 静态局部变量与全局变量׃n全局数据区,但静态局部变量只在定义它的函C可见。静态局部变量与局部变量在存储位置上不同,使得其存在的旉也不同,D对这两者操?的运行结果也不同?br /> 例如Q下面的E序定义了全局变量、静态局部变量和局部变量:<br /> <span id="7hfl7zh" class="ff0000"><font color="#ff0000"> //*********************<br /> //**   ch5_2.cpp  **<br /> //********************* </font></span> <p class="ff0000"><font color="#ff0000">    #include <iostream.h></font></p> <p class="ff0000"><font color="#ff0000">    void func();<br /> int n=1; //全局变量</font></p> <p class="ff0000"><font color="#ff0000">    void main()<br /> {<br /> <em><strong>static</strong></em> int a; // 静态局部变?br /> int b= -10; // 局部变?br /> cout <<"a:" <<a<br /> <<" b:" <<b<br /> <<" n:" <<n <<endl;<br /> b+=4;<br /> func();<br /> cout <<"a:" <<a<br /> <<" b:" <<b<br /> <<" n:" <<n <<endl;<br /> n+=10;<br /> func();<br /> }</font></p> <p class="ff0000"><font color="#ff0000">    void func()<br /> {<br /> <em><strong>static</strong></em> int a=2; // 静态局部变?br /> int b=5; // 局部变?br /> a+=2;<br /> n+=12;<br /> b+=5;<br /> cout <<"a:" <<a<br /> <<" b:" <<b<br /> <<" n:" <<n <<endl;<br /> }</font></p> <p class="p14">  q行l果为:<br /> <span id="7rvr1rp" class="ff0000">   <font color="#ff0000"> a:0 b:-10 n:l<br /> a:4 b:10 n:13<br /> a:0 b:-6 n:13<br /> a:6 b:10 n:35</font></span><br /> E序中主函数main()两次调用了func()函数Q从q行l果可以看出Q程序控制每ơ进入func()函数Ӟ局部变量b都被初始化。而静态局? 变量a仅在W一ơ调用时被初始化Q第二次q入该函数时Q不再进行初始化Q这时它的值是W一ơ调用后的结果?? main()函数中的变量a和b与func()函数中的变量a和bI间位置是不一LQ所以相应的g不一栗关于变量作用域和可见性的q一步讨W? 章?br /> 静态局部变量的用途有许多Q可以用它定某函数是否被调用q。用它保留多次调用的倹{?/p> <p class="p14"><strong><font size="5">寚w态局部变量的说明Q?/font></strong> <br /> (1) 静态局部变量在静态存储区内分配存储单元。在E序整个q行期间都不释放。而自动变量(卛_态局部变量)属于动态存储类别,存储在动态存储区I间(而不是静态存储区I间)Q函数调用结束后即释放?<br /> (2) 为静态局部变量赋初值是在编译时q行值的Q即只赋初gơ,在程序运行时它已有初倹{以后每ơ调用函数时不再重新赋初D只是保留上ơ函数调用结束时? 倹{而ؓ自动变量赋初|不是在编译时q行的,而是在函数调用时q行Q每调用一ơ函数重新给一ơ初|相当于执行一ơ赋D句?<br /> <br /> (3) 如果在定义局部变量时不赋初值的话,寚w态局部变量来_~译时自动赋初?(Ҏ值型变量)或空字符(对字W型变量)。而对自动变量来说Q如果不赋初 |则它的值是一个不定的倹{这是由于每ơ函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的值是不确定的?<br /> (4) 虽然静态局部变量在函数调用l束后仍然存在,但其他函数是不能引用它的Q也是_在其他函C它是“不可?#8221;的?/p> <img src ="http://www.tkk7.com/faintbear/aggbug/308408.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/faintbear/" target="_blank">力力力</a> 2010-01-06 11:37 <a href="http://www.tkk7.com/faintbear/archive/2010/01/06/308408.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>走近GPRShttp://www.tkk7.com/faintbear/archive/2006/09/07/68215.html力力力力力力Thu, 07 Sep 2006 03:45:00 GMThttp://www.tkk7.com/faintbear/archive/2006/09/07/68215.htmlhttp://www.tkk7.com/faintbear/comments/68215.htmlhttp://www.tkk7.com/faintbear/archive/2006/09/07/68215.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/68215.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/68215.html

走近GPRS


崔绘


对于一个技术h员而言QGPRS是一个美丽而又复杂的系l,它承了无线领域几代技术的_֍Q又吸收了数据网l数十年成功的经验。如此种U,决非一文章可以尽数。本文试图从原理角度介绍GPRS|络元素、数据传输协议和操作程Q希望能揭开冰山的一角,为大家了解GPRS技术提供帮助?
作ؓ一个用P他所见到GPRS|络是一个承载网Q与以太|,帧中l网无异。而从pȝ工程师的角度看,q个|络复杂多了,Z提供二层承蝲QGPRS|络引入了许多新的网l元素和数据处理Ҏ?
数据qL手机到因特网要经q四个设备,MSQMobile StationQ手机)、BSSQBase Station SystemQ基站系l)、SGSNQServing GPRS Support NodeQ服务GPRS节点Q和GGSNQGateway GPRS Support NodeQ网关GPRS节点Q。其中,SGSN和GGSN是新增设备,而MS和BSS需要进行设备的软硬件升U?
它们的主要功能如下:
MSQ一斚wQ处理空中接口的上下行传输;另一斚wQ将数据信息发给与之q接的计机?
BSSQ通常包括一pd讑֤。负责分配空中的信道资源Qƈ在手机和SGSN之间转发信息?
SGSNQ是无线部分和数据网部分的分界线Q负责管理手机的UdQƈ与GGSN协作完成用户数据在Gn|络上的传输?
GGSNQ是GPRS|络与外|的分界U,对内负责Gn|络的传输,对外是一台因特网路由器。其中的BGGSNQBorder GGSNQ负责连接不同运营商之间的Gn|络Q实现网间O游。上q四个设备将用户的计机和因特网q接hQ完成了无线上网的数据传输工作。这之间用到的接口有Q?
RQ计机与GPRS手机之间的接口。可以基于多U传输方法,如RS232、红外等{?
UmQ空中接口,在手ZBSS之间。接口上的传输格式与GSM无异Q但逻辑信道的定义和分配有很大差别?
GbQBSS和SGSN之间的接口。可以是U用的中|络或者是q行帧中l封装协议的专线?
GnQSGSN和GGSN之间的接口。所有的SGSN和GGSN构成了GPRS的骨q网Q这个网l是q营商的U有|络Q与外网之间没有路由。GGSN外|的信息装后在Gn|络上传输?
GiQGGSN和外|之间的接口。在q个接口上可以设|隧道(TunnelQ,以保证用户到企业内部|之间的安全性?除此之外Q还有Gp接口Q在BGGSN和其他运营商的网l之_以便实现|间漫游。所有这些设备和接口如图所C(双线标出的是数据通\Q:

图:GPRS|络的设备与接口
在上图中Q还包括一些传l的GSM讑֤Q如MSCQMobile Switch CenterQ移动交换中心)、HLRQHome Location RegisterQ用户位|寄存器Q、SMSQShort Message ServiceQ短消息服务中心Q等{。这些设备与GPRS|络元素之间的接口主要是信o接口。比如:
Gr接口Q在SGSN和HLR之间。用户向SGSNdӞSGSN在HLR中获得用L登记信息和鉴权信息?
Gs接口Q在SGSN和MSC之间。主要ؓ了便于一些组合的操作Q例如,一个用戯同时dGPRS和GSM两个|络QSGSNp通过q个接口对GSM|络的登录请求{发给MSC?
Gd接口Q在SGSN和SMS之间。有了这个接口,短消息就可以通过GPRS|络传送,而不必占用GSM的资源?
Gc接口Q在GGSN和HLR之间。设|它的目的是Z支持外网L发vq接。通常q接是由手机发v的,SGSN在对用户鉴权之后Q找到指定的GGSNQƈ与之建立数据通\。如果联接是由外|主机发LQ信息到达GGSN之后QGGSN需要通过Gc接口查询HLRQ(1Q目的IP对应哪一台手机;Q?Q这台手机现在由哪一个SGSN控制。这个接口目前还没有实现?
上面的所有这些设备和接口是从|络功能上讲的。在现实的GPRS|络中,q需要一些其它的辅助讑֤。例如网l管理设备、Gn|络的\由器、交换机和应用支持设备(DNS和DHCP服务所在的LQ等{?
了解一个系l,除了它的l成之外Q我们最兛_的莫q于pȝ中所使用的协议。GPRS引入了许多新的协议,它们大多出现在数据传输通\上,如下图所C:

?GPRS所使用的数据传输协?/td>
数据包从外网传到手机要经q四个接口,Gi、Gn、Gb和Um。下面我们就序介绍在这个过E中所使用到的传输协议?
Gi接口Q外|与GGSN之间的接?/b>
在这个接口上没有新的协议。与普通的路由器一PGGSN利用现有的传输方法,接收二层数据帧。之后,做处理Q得到IP数据包。分析该IP包的目的地址Q恰为本地PDP Context所标示的某一手机地址Q则此数据包送至Gn接口的Y件模块,做进一步处理?
Gn接口QGGSN与SGSN之间的接?/b>
最先对数据包做处理的GTPQGPRS Tunneling ProtocolQ协议,它实C从GGSN到SGSN的虚拟传输通\Q即隧道。隧道的优点有二Q一是便于手机的UdQ当手机׃个SGSN转移到另外一个SGSN的控制下Ӟ只需改变GTP的配|,佉K道的末端发生变化卛_Q对于被承蝲的IP数据包来说是透明的;二来Q在Gi和Gn两个|络之间Q即外网和运营商|络之间不存在\由,只有装关系Q安全性得C保障?
Gn|络本n是一个TCP/IP|络QGn|络中的元素都是靠IP来寻址的。GTP协议数据包对于Gn|络来说是高层的应用数据Q需要由TCP或UDP承蝲Q对应GTP应用的四层端口号?386。之后, TCP或UDP的数据包q一步封装成IP包,此包的目的地址即ؓ目标SGSN的地址?
Gn|络中的IP包传送也是靠一pd的\由器和交换机来完成的。注意,q时传送的是运营商内网IPQ或者内层IP、下层IPQ,与此相对应,装在GTP协议内部的IP叫做外网IPQ或者外层IP、上层IPQ?
数据到达SGSN之后Q层层解,最l还原出用户的IP数据包,交给IP Relay软g模块?
Gb接口QSGSN和BSS之间的接?/b>
首先QSNDCPQSub-Network Dependent Convergence ProtocolQ对IP数据包做同一化处理,q一步的目的是提高GPRS的可扩展性,未来Q只需改变SNDCP可以适应新的三层协议Q比如IPv6。除此之外,SNDCPq负责数据的压羃和分D,压羃的目的是节约IZ接口带宽Q分D늚目的是适应下层LLC的MTUQMaximum Transmission UnitQ最大传输单元)?
LLCQLogical Link ControlQ协议负责从SGSN到手机的数据传输。它的服务对象有三,SNDCP数据包(即用h据)、用户信令和短消息。服务的cd有面向连接和无连接两U,用户可以ҎQoS要求选择?
BSSGPQBase Station System GPRS ProtocolQ是SGSN与BSS通讯的最上层协议Q故而它不但发送上层的LLC数据Q还传输SGSN对BSS的控制信息,如对手机的呼叫(PagingQ等{?
NSQNetwork ServiceQ提供网l传输服务,目前Q这个服务是Z帧中lPVC的。也是_Gb接口是中接口Q可以租用中服务商的U\Q也可以在专U上q行帧中l协议?
数据到达BSS之后Q同h层层解封Q最l得到的是LLC数据帧,BSSq不对LLC帧做处理Q而只是透明转发?
Um接口QBSS和手Z间的接口
Mq中接口传输的数据Q必dl过两个协议的处理,RLCQRadio Link ControlQ和MACQMedia Access ControlQ?RLCLLC数据帧拆分成便于IZ传输的数据块Qƈ负责IZ接口的可靠性保障。数据块的大依Coding Scheme的不同,可能?81bits?68bits?12bits?28bits?
MAC的功能是控制IZ资源的用,׃一个用户可以用多个信道,多个用户也可以用一个信道,而且Q资源的分配是动态的Q所以下行传输时QMAC必须标识当前的数据块是给哪一个手机的Q上行传输时Q必L定当前资源由谁用?
加上LLC和MAC头之后,数据块被LQConvolutional CodingQ和交织QInterleavingQ。卷U指在数据中d冗余信息Q以减少非连l比牚w误。卷U处理之后的数据块统一?56比特。交l是数据块交叉分散到四个突发序列(Normal BurstQ中Q可以抵抗连l比牚w误?
l过上述处理Q最l得到的H发序列与GSM无异Q每个包?14比特的数据信息。它们采用和GSM同样的方式,通过IZ接口Q到达手机。手机做如图的解之后,q原出IP数据包。至此,IP包通过了GPRS|络Q承载的功能完成了?
控制GPRS操作的有两个重要的ContextQ在SGSN之前Q靠q手Z侧)有MM ContextQSGSN之后Q靠q网l一侧)有PDP Context?
MM Context负责Ud理Q它有三U状态,I闲QIdleQ、就l(ReadyQ和守候(StandbyQ。手机开机,执行d|络操作Q手机的状态由I闲转至qA。在qA状态下Q手机可以收发数据。一D|间没有数据收发,手机{入守候状态。这Ӟ|络中有手机的注册信息,但手机基本不占用|络资源。在守候状态下Q手机可以申误源进行上行传输,位置更新Q网l方也可以通过Paging发v下行传输Q传输一旦开始,手机p回就序状态。在正常状态下Q手机的MM Context在就l和守候两者之间。也是_无论|络q是手机都随时可以发h据传输,q就是GPRS宣称的一直在U(Always OnlineQ功能,与传l的上网Ҏ相比Q效率着实提高不?
PDP Context负责数据的传输,M数据传送之前,手机要徏立PDP ContextQ必备的参数包括手机的IP地址QAPNQAccess Point NameQ访问点名字Q等{。有了这些参敎ͼSGSN可以发v建立一条到GGSN的数据传输通\。IP地址的动态分配也是在q个q程中完成的?
GPRS服务的Qos服务质量可以从五个方面规定?
  • 优先U。分为高中低三种?/li>
  • 可靠性。GPRS从四个方面评价可靠性,GTP是否重传QLLC是否重传QLLC是否带数据校验和IZ接口是否重传。目前的实现大多是GTP、LLC不重传,LLC带数据校验,IZ接口有重传?/li>
  • 延迟。协议规定了三种量化的gq标准和最大可能传输。目前实现的是尽最大可能传输。所有的延迟量都是在Gi和R接口之间q行的?/li>
  • q_速率。分为十九Q目前实现的最大可能传输?/li>
  • H发速率。分ZU,?Kbps到未来的2Mbps?/li>
合理的数据传输计Ҏ法应该综合考虑数据量与服务质量。不q,计费q不是GPRS协议规定的内容,它的方式由pȝq营商决定?
正如本文开所aQGPRS是一个非常复杂的pȝQ决非一文章可以尽q。如果你x加系l地了解GPRSQ最好的Ҏ莫过于阅读ETSI的GSM 03.60协议 GPRS Service Description?

Q网늼辑:嘉佳Q?/td>


力力力 2006-09-07 11:45 发表评论
]]>
C/C++ E序设计员应聘常见面试试题深入剖?http://www.tkk7.com/faintbear/archive/2006/07/27/60321.html力力力力力力Thu, 27 Jul 2006 06:08:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/27/60321.htmlhttp://www.tkk7.com/faintbear/comments/60321.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/27/60321.html#Feedback2http://www.tkk7.com/faintbear/comments/commentRss/60321.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/60321.html C/C++ E序设计员应聘常见面试试题深入剖?
旉Q?006-5-30 17:06:00  
.引言

  本文的写作目的ƈ不在于提供C/C++E序员求职面试指|而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛Q部分试题解{也参考了|友的意见?br />
  许多面试题看似简单,却需要深厚的基本功才能给出完的解答。企业要求面试者写一个最单的strcpy函数都可看出面试者在技术上I竟辑ֈ了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自pQ可是我们写出的strcpy很可能只能拿?0分中?分。读者可从本文看到strcpy 函数?分到10分解{的例子Q看看自己属于什么样的层ơ。此外,q有一些面试题考查面试者敏L思维能力?

  分析q些面试题,本n包含很强的趣x;而作Z名研发h员,通过对这些面试题的深入剖析则可进一步增w的内功?br />
  2.N?br />
  试题1Q?br />
void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}

  试题2Q?br />
void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1[i] = 'a';
 }
 strcpy( string, str1 );
}

  试题3Q?br />
void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}

  解答Q?br />
  试题1字符串str1需?1个字节才能存放下Q包括末’\0’)Q而string只有10个字节的I间Qstrcpy会导致数l越界;

  对试?Q如果面试者指出字W数lstr1不能在数l内l束可以l?分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存h复制的字节数h不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;

  对试?Qif(strlen(str1) <= 10)应改为if(strlen(str1) < 10)Q因为strlen的结果未l计’\0’所占用?个字节?br />
  剖析Q?br />
  考查对基本功的掌握:

  (1)字符串以’\0’结;

  (2)Ҏl越界把握的敏感度;

  (3)库函数strcpy的工作方式,如果~写一个标准strcpy函数的dgؓ10Q下面给出几个不同得分的{案Q?br />
  2?br />
void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != ‘\0?);
}

  4?br />
void strcpy( char *strDest, const char *strSrc )
//源字符串加constQ表明其入参敎ͼ??br />{
  while( (*strDest++ = * strSrc++) != ‘\0?);
}

  7?br />
void strcpy(char *strDest, const char *strSrc)
{
 //Ҏ地址和目的地址加非0断言Q加3?br /> assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != ‘\0?);
}

  10?br />
//Z实现铑ּ操作Q将目的地址q回Q加3分!

char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘\0?);
  return address;
}

  ?分到10分的几个{案我们可以清楚的看刎ͼ小的strcpy竟然暗藏着q么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完的strcpy啊!

  (4)对strlen的掌握,它没有包括字W串末尾?\0'?br />
  读者看了不同分值的strcpy版本Q应该也可以写出一?0分的strlen函数了,完美的版本ؓQ?int strlen( const char *str ) //输入参数const

{
 assert( strt != NULL ); //断言字符串地址?
 int len;
 while( (*str++) != '\0' )
 {
  len++;
 }
 return len;
}

  试题4Q?br />
void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( str );
 strcpy( str, "hello world" );
 printf( str );
}

  试题5Q?br />
char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}

void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}

  试题6Q?br />
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}

  试题7Q?br />
void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它语?br />}

  解答Q?br />
  试题4传入中GetMemory( char *p )函数的Ş参ؓ字符串指针,在函数内部修改Ş参ƈ不能真正的改变传入Ş参的|执行?br />
char *str = NULL;
GetMemory( str );

  后的str仍然为NULLQ?br />
  试题5?br />
char p[] = "hello world";
return p;

  的p[]数组为函数内的局部自动变量,在函数返回后Q内存已l被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期?br />
  试题6的GetMemory避免了试?的问题,传入GetMemory的参Cؓ字符串指针的指针Q但是在GetMemory中执行申请内存及赋D?br />
*p = (char *) malloc( num );

  后未判断内存是否甌成功Q应加上Q?br />
if ( *p == NULL )
{
 ...//q行甌内存p|处理
}

  试题7存在与试?同样的问题,在执?br />
char *str = (char *) malloc(100);

  后未q行内存是否甌成功的判断;另外Q在free(str)后未|str为空Q导致可能变成一个“野”指针,应加上:

str = NULL;

  试题6的Test函数中也未对malloc的内存进行释放?br />
  剖析Q?br />
  试题4?考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正的回答其中50~60的错误。但是要完全解答正确Q却也绝非易事?br />
  对内存操作的考查主要集中在:

  Q?Q指针的理解Q?br />
  Q?Q变量的生存期及作用范围Q?br />
  Q?Q良好的动态内存申请和释放习惯?br />
  再看看下面的一D늨序有什么错误:

swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}

  在swap函数中,p是一个“野”指针,有可能指向系l区Q导致程序运行的崩溃。在VC++中DEBUGq行时提C错误“Access Violation”。该E序应该改ؓQ?br />
swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}

 3.内功?br />
  试题1Q分别给出BOOLQintQfloatQ指针变?与“零值”比较的 if 语句Q假讑֏量名为varQ?br />
  解答Q?br />
   BOOL型变量:if(!var)

   int型变量: if(var==0)

   float型变量:

   const float EPSINON = 0.00001;

   if ((x >= - EPSINON) && (x <= EPSINON)

   指针变量Q  if(var==NULL)

  剖析Q?br />
  考查?值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0)Q而int型变量也可以写成if(!var)Q指针变量的判断也可以写成if(!var)Q上q写法虽然程序都能正运行,但是未能清晰地表辄序的意思?


  const关键字至有下列n个作用:

  Q?Q欲L一个变量被改变Q可以用const关键字。在定义该const变量Ӟ通常需要对它进行初始化Q因Z后就没有Z再去改变它了Q?br />
  Q?Q对指针来说Q可以指定指针本wؓconstQ也可以指定指针所指的数据为constQ或二者同时指定ؓconstQ?br />
  Q?Q在一个函数声明中Qconst可以修饰形参Q表明它是一个输入参敎ͼ在函数内部不能改变其|

  Q?Q对于类的成员函敎ͼ若指定其为constcdQ则表明其是一个常函数Q不能修改类的成员变量;

  Q?Q对于类的成员函敎ͼ有时候必L定其q回gؓconstcdQ以使得其返回g为“左值”。例如:

const classA operator*(const classA& a1,const classA& a2);

  operator*的返回结果必L一个const对象。如果不是,q样的变态代码也不会~译出错Q?br />
classA a, b, c;
(a * b) = c; // 对a*b的结果赋?/td>

  操作(a * b) = c昄不符合编E者的初衷Q也没有M意义?br />
  剖析Q?br />
  惊讶吗?小的static和const居然有这么多功能Q我们能回答几个Q如果只能回{?~2个,那还真得闭关再好好修g点{?br />
  q个题可以考查面试者对E序设计知识的掌握程度是初、中U还是比较深入,没有一定的知识q度和深度,不可能对q个问题l出全面的解{。大多数人只能回{出static和const关键字的部分功能?br />
  4.技巧题

  试题1Q请写一个C函数Q若处理器是Big_endian的,则返?Q若是Little_endian的,则返?

  解答Q?br />
int checkCPU()
{
 {
  union w
  {
   int a;
   char b;
  } c;
  c.a = 1;
  return (c.b == 1);
 }
}

  剖析Q?br />
  嵌入式系l开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPUҎ作数的存放方式是从低字节到高字节Q而Big-endian模式Ҏ作数的存放方式是从高字节C字节。例如,16bit宽的?x1234在Little- endian模式CPU内存中的存放方式Q假设从地址0x4000开始存放)为:

内存地址存放内容
0x40000x34
0x40010x12

  而在Big-endian模式CPU内存中的存放方式则ؓQ?br />
内存地址存放内容
0x40000x12
0x40010x34

  32bit宽的?x12345678在Little-endian模式CPU内存中的存放方式Q假设从地址0x4000开始存放)为:

内存地址存放内容
0x40000x78
0x40010x56
0x40020x34
0x40030x12

  而在Big-endian模式CPU内存中的存放方式则ؓQ?br />
内存地址存放内容
0x40000x12
0x40010x34
0x40020x56
0x40030x78

  联合体union的存N序是所有成员都从低地址开始存放,面试者的解答利用该特性,L地获得了CPU对内存采用Little-endianq是Big-endian模式d。如果谁能当场给个解{,那简直就是一个天才的E序员?br />
  试题2Q写一个函数返?+2+3+?n的|假定l果不会过长整型变量的范围Q?

  解答Q?br />
int Sum( int n )
{
 return ( (long)1 + n) * n / 2;  //或return (1l + n) * n / 2;
}

  剖析Q?br /> 
  对于q个题,只能_也许最单的{案是最好的{案。下面的解答Q或者基于下面的解答思\M化,不管怎么“折䏀,其效率也不可能与直接return ( 1 l + n ) * n / 2相比Q?

int Sum( int n )
{
 long sum = 0;
 for( int i=1; i<=n; i++ )
 {
  sum += i;
 }
 return sum;
}

  所以程序员们需要敏感地数学等知识用在E序设计中?


力力力 2006-07-27 14:08 发表评论
]]>
c 语言隄分析整理 (?http://www.tkk7.com/faintbear/archive/2006/07/18/58871.html力力力力力力Tue, 18 Jul 2006 15:29:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/18/58871.htmlhttp://www.tkk7.com/faintbear/comments/58871.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/18/58871.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/58871.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/58871.html
c 语言隄分析整理
原创Qimy 2003q??0?

q篇文章主要是介l一些在复习C语言的过E中W者个为比较重点的地方Q较好的掌握q些重点会对C的运用更加得心应手。此外会包括一些细节、易错的地方。涉及的主要内容包括Q变量的作用域和存储cd、函数、数l、字W串、指针、文件、链表等。一些最基本的概念在此就不多作解释了Q仅希望能有只言片语l同是C语言初学者的学习和上E提供一点点的帮助?br />

变量作用域和存储cdQ?/strong>

了解了基本的变量cd后,我们要进一步了解它的存储类别和变量作用域问题?/p>
变量cd子类?/td>
局部变?/td>静态变量(d函数Q变量g保留Q?/td>
自动变量
寄存器变?/td>
全局变量静态变量(只能在本文g中用Q?/td>
非静态变量(允许其他文g使用Q?/td>

换一个角?/p>
变量cd子类?/td>
静态存储变?/font>静态局部变量(函数Q?/font>
静态全局变量Q本文gQ?/font>
非静态全局/外部变量Q其他文件引用)
动态存储变?/td>自动变量
寄存器变?/td>
形式参数

extern型的存储变量在处理多文g问题时常能用刎ͼ在一个文件中定义extern型的变量卌明这个变量用的是其他文g的。顺便说一下,W者在做课设时遇到out of memory的错误,于是Ҏ做多文gQ再把它includeq来Q注意自己写?.h要用“”不?lt;>Q,能vC定的效用。static型的在读E序写结果的试题中是个考点。多数时候整个程序会出现多个定义的变量在不同的函CQ考查在不同位|同一变量的值是多少。主要是遵@一个原则,只要本函数内没有定义的变量就用全局变量Q而不是main里的Q,全局变量和局部变量重名时局部变量v作用Q当然还要注意静态与自动变量的区别?

函数Q?/strong>

对于函数最基本的理解是从那个叫main的单词开始的Q一开始M觉得把语句一q写在main里不是挺好的么,Z么偏择出厅R其实这是因为对函数q不够熟l,否则函数的运用会l我们编E带来极大的便利。我们要知道函数的返回值类型,参数的类型,以及调用函数时的形式。事先的函数说明也能起到一个提醒的好作用。所谓Ş参和实参Q即在调用函数时写在括号里的是实参Q函数本w用的就是Ş参,在画程图时用^行四边Ş表示传参?/p>

函数的另一个应用例子就是递归了,W者开始比较头疼的问题Q反应L比较q钝Q按照老师的方法,把递归的过E耐心准确的逐d来,学习的效果还是比较好的,会觉得这U递归的运用是挺y的,事实上,著名的八皇后、汉诺塔{问题都用到了递归?/p>
例子Q?br />long fun(int n)
{
long s;
if(n==1||n==2) s=2;
   else s=n-fun(n-1);
return s;
}
main()
{
printf("%ld",fun(4));
}

数组Q?/strong>

分ؓ一l数l和多维数组Q其存储方式Mؓ表格的话׃一目了Ӟ其实是把相同类型的变量有序的放在一赗因此,在处理比较多的数据时Q这也是大多数的情况Q数l的应用范围是非常广的?/p>

具体的实际应用不便D例,而且l大多数是与指针相结合的Q笔者个为学习数l在更大E度上是为学习指针做一个铺垫。作为基的基要明白几U基本操作:xl赋倹{打印、排序(冒排序法和选择排序法)、查找。这些都不可避免的用到@环,如果觉得反应不过来,可以先一点点的把循环展开Q就会越来越熟悉Q以后自q写一个功能的时候就会先扑և内在规律Q较好的q用了。另外数l做参数Ӟ一l的[]里可以是I的Q二l的W一个[]里可以是I的但是W二个[]中必规定大?/p>
冒法排序函敎ͼ
void bubble(inta[],int n)
{
int i,j,k;
for(i=1,i<n;i++)
   for(j=0;j<n-i-1;j++)
   if(a[j]>a[j+1])
    {
    k=a[j];
       a[j]=a[j+1];
       a[j+1]=k;
       }

}

选择法排序函敎ͼ
void sort(inta[],int n)
{
int i,j,k,t;
for(i=0,i<n-1;i++)
   {
   k=i;
   for(j=i+1;j<n;j++)
      if(a[k]<a[j]) k=j;
      if(k!=i)
         {
         t=a[i];
         a[i]=a[k];
         a[k]=t;
         }
   }
}

折半查找函数Q原数组有序Q:
void search(inta[],int n,int x)
{
int left=0,right=n-1,mid,flag=0;
while((flag==0)&&(left<=right))
   {
   mid=(left+right)/2;
   if(x==a[mid])
      {
      printf("%d%d",x,mid);
      flag =1;
      }
      elseif(x<a[mid]) right=mid-1;
                   elseleft=mid+1;
   }
}

相关常用的算法还?strong>判断回文Q求阶乘QFibanacci数列QQ意进制{换,杨辉三角形计?/strong>{等?/strong>

字符Ԍ

字符串其实就是一个数l(指针Q,在scanf的输入列中是不需要在前面加?amp;”符LQ因为字W数l名本n即代表地址。值得注意的是字符串末‘\0’,如果没有的话Q字W串很有可能会不正常的打印。另外就是字W串的定义和赋值问题了Q笔者有一ơ的比较l合的上Z业就是字W串打印老是qQ上上下下找了一圈问题,最后发现是因ؓ

char *name;

而不?/p>
char name[10];

前者没有说明指向哪儿,更没有确定大,D了ؕ码的错误Q印象挺深刻的?

另外Q字W串的赋g是需要注意的Q如果是用字W指针的话,既可以定义的时候赋初|?/p>
char *a="Abcdefg";

也可以在赋D句中赋|?/p>
char *a;
a="Abcdefg";

但如果是用字W数l的话,只能在定义时整体赋初|即char a[5]={"abcd"};而不能在赋D句中整体赋倹{?

常用字符串函数列表如下,要会自己实现Q?/p>
函数作用函数调用形式备注
字符串拷贝函?/td>strcpy(char*,char *)后者拷贝到前?/td>
字符串追加函?/td>strcat(char*,char *)后者追加到前者后Q返回前者,因此前者空间要_?/td>
字符串比较函?/td>strcmp(char*,char *)前者等于、小于、大于后者时Q返?、正倹{负倹{注意,不是比较长度Q是比较字符ASCII码的大小Q可用于按姓名字母排序等?/td>
字符串长?/td>strlen(char *)q回字符串的长度Q不包括'\0'.转义字符一个字W?/td>
字符串型->整型atoi(char *)
整型->字符串型itoa(int,char *,int)做课设时挺有用的
sprintf(char *,格式化输入)赋给字符Ԍ而不打印出来。课设时用也比较方便

注:对字W串是不允许?=或!=的运的Q只能用字符串比较函?/p>

指针Q?/strong>

指针可以说是C语言中最关键的地方了Q其实这个“指针”的名字对于q个概念的理解是十分形象的。首先要知道Q指针变量的|x针变量中存放的|是指针(卛_址Q。指针变量定义Ş式中Q基本类?*指针变量?中的?”代表的是这是一个指向该基本cd的指针变量,而不是内容的意思。在以后使用的时候,?ptr=aӞ?”才表示ptr所指向的地址里放的内Ҏa?/p>

指针比较典型又简单的一应用例子是两C换,看下面的E序Q?/p>
swap(intc,intd)
{
int t;
t=c;
c=d;
d=t;
}
main()
{
int a=2,b=3;
swap(a,b);
printf(?d,%d?a,b);
}

q是不能实现a和b的数g换的Q实际上只是形参在这个函C换来换去Q对实参没什么媄响。现在,用指针类型的数据做ؓ参数的话Q更改如下:

swap(#3333FF *p1,int *p2)
{
int t;
t=*p1;
*p1=*p2;
*p2=t;
}
main()
{
int a=2,b=3;
int *ptr1,*ptr2;
ptr1=&a;
ptr2=&b;
swap(prt1,ptr2);
printf(?d,%d?a,b);
}

q样在swap中就把p1,p2 的内容给换了Q即把aQb的g换了?/p>

指针可以执行增、减q算Q结?+q算W的法则Q我们可以看?

*++s

取指针变量加1以后的内?/p>

*s++取指针变量所指内容后s再加1
(*s)++指针变量指的内容?

指针和数l?/strong>实际上几乎是一LQ数l名可以看成是一个常量指针,一l数l中ptr=&b[0]则下面的表示法是{h的:

a[3]{h?(a+3)
ptr[3]{h?(ptr+3)

下面看一个用指针来自己实现atoiQ字W串?>整型Q函敎ͼ

int atoi(char *s)
{
int sign=1,m=0;
if(*s=='+'||*s=='-') /*判断是否有符?/
sign=(*s++=='+')?1:-1;/*用到三目q算W?/
while(*s!='\0') /*Ҏ一个字W进行操?/
   {
   m=m*10+(*s-'0');
   s++;
/*指向下一个字W?/
   }
return m*sign;
}

指向多维数组的指针变量也是一个比较广泛的q用。例如数la[3][4]Qa代表的实际是整个二维数组的首地址Q即W?行的首地址Q也是一个指针变量。而a+1׃是简单的在数g加上1了,它代表的不是a[0][1]Q而是W?行的首地址Q?amp;a[1][0]?/p>

指针变量常用的用途还有把指针作ؓ参数传递给其他函数Q即指向函数的指?/strong>?br />看下面的几行代码Q?/p>
void Input(ST *);
void Output(ST *);
void Bubble(ST *);
void Find(ST *);
void Failure(ST *);
/*函数声明Q这五个函数都是以一个指向ST型(事先定义q)l构的指针变量作为参敎ͼ无返回倹{?/

void(*process[5])(ST *)={Input,Output,Bubble,Find,Failure};
/*process被调用时提供5U功能不同的函数共选择(指向函数的指针数l)*/

printf("\nChoose:\n?");
scanf("%d",&choice);
if(choice>=0&&choice<=4)
(*process[choice])(a); /*调用相应的函数实C同功?;/

MQ指针的应用是非常灵zdq泛的,不是三言两语能说完的Q上面几个小例子只是个引子,实际~程中,会逐渐发现q用指针所能带来的便利和高效率?

文gQ?/strong>

函数调用形式说明
fopen("路径","打开方式")打开文g
fclose(FILE *)防止之后被误?/td>
fgetc(FILE *)从文件中d一个字W?/td>
fputc(ch,FILE *)把ch代表的字W写入这个文仉
fgets(FILE *)从文件中d一?/td>
fputs(FILE *)把一行写入文件中
fprintf(FILE *,"格式字符?,输出表列Q?/td>把数据写入文?/td>
fscanf(FILE *,"格式字符?,输入表列Q?/td>从文件中d
fwriteQ地址QsizeofQ)QnQFILE *Q?/td>把地址中n个sizeof大的数据写入文g?/td>
freadQ地址QsizeofQ)QnQFILE *Q?/td>把文件中n个sizeof大的数据d地址?/td>
rewindQFILE *Q?/td>把文件指针拨回到文g?/td>
fseekQFILE *QxQ?/1/2Q?/td>Ud文g指针。第二个参数是位U量Q?代表从头U,1代表从当前位|移Q?代表从文件尾UR?/td>
feof(FILE *)判断是否C文g末尾

文g打开方式说明
r打开只能ȝ文g
w建立供写入的文gQ如果已存在抹d有数?/td>
a打开或徏立一个把数据q加到文件尾的文?/td>
r+打开用于更新数据的文?/td>
w+建立用于更新数据的文Ӟ如果已存在就抹去原有数据
a+打开或徏立用于更新数据的文gQ数据追加到文g?/td>

注:以上用于文本文g的操作,如果是二q制文g在上述字母后加“b”?/p>

我们用文件最大的目的是能让数据保存下来。因此在要用文g中数据的时候,是要把数据d一个结构(一般保存数据多用结构,便于理Q中去,再对l构q行操作卛_。例如,文gaa.data中存储的?0个学生的成W{信息,要遍历这些信息,对其q行成W输出、排序、查扄工作Ӟ我们把q些信息先读入到一个结构数l中Q再对这个数l进行操作。如下例Q?/p>
#include<stdio.h>
#include<stdlib.h>
#define N 30

typedef struct student /*定义储存学生成W信息的数l?/
{
char *name;
int chinese;
int maths;
int phy;
int total;
}ST;

main()
{
ST a[N]; /*存储N个学生信息的数组*/
FILE *fp;
void(*process[3])(ST *)={Output,Bubble,Find}; /*实现相关功能的三个函?/
int choice,i=0;
Show();
printf("\nChoose:\n?");
scanf("%d",&choice);
while(choice>=0&&choice<=2)
   {
   fp=fopen("aa.dat","rb");
   for(i=0;i<N;i++)
      fread(&a[i],sizeof(ST),1,fp);/*把文件中储存的信息逐个d数组中去*/
   fclose(fp);
   (*process[choice])(a); /*前面提到的指向函数的指针Q选择操作*/
   printf("\n");
   Show();
   printf("\n?");
   scanf("%d",&choice);
   }
}

void Show()
{
printf("\n****Choices:****\n0.Display the data form\n1.Bubble it according to the total score\n2.Search\n3.Quit!\n");
}

void Output(ST *a) /*文件中存储的信息逐个输出*/
{
int i,t=0;
printf("Name Chinese Maths Physics Total\n");
for(i=0;i<N;i++)
   {
   t=a[i].chinese+a[i].maths+a[i].phy;
   a[i].total=t;
   printf("%4s%8d%8d%8d%8d\n",a[i].name,a[i].chinese,a[i].maths,a[i].phy,a[i].total);
   }
}

void Bubble(ST *a)/*Ҏl进行排序,q输出结?/
{
int i,pass;
ST m;
for(pass=0;pass<N-1;pass++)
   for(i=0;i<N-1;i++)
      if(a[i].total<a[i+1].total)
         {
         m=a[i]; /*l构互换*/
         a[i]=a[i+1];
         a[i+1]=m;
         }
Output(a);
}

void Find(ST *a)
{
int i,t=1;
char m[20];
printf("\nEnter the name you want:");
scanf("%s",m);
for(i=0;i<N;i++)
   if(!strcmp(m,a[i].name))/*Ҏ姓名匚w情况输出查找l果*/
   {
   printf("\nThe result is:\n%s, Chinese:%d, Maths:%d,     Physics:%d,Total:%d\n",m,a[i].chinese,a[i].maths,a[i].phy,a[i].total);
   t=0;
   }
if(t)
   printf("\nThe name is not in the list!\n");
}

链表Q?/strong>
链表是C语言中另外一个难炏V牵扯到l点、动态分配空间等{。用l构作ؓ链表的结Ҏ非常适合的,例如Q?/p>
struct node
{
int data;
struct node *next;
};

其中next是指向自w所在结构类型的指针Q这样就可以把一个个l点相连Q构成链表?/p>

链表l构的一大优势就是动态分配存储,不会像数l一样必d定义时确定大,造成不必要的费。用malloc和free函数卛_实现开辟和释放存储单元。其中,malloc的参数多用sizeofq算W计得到?/p>

链表的基本操作有Q?strong>正、反向徏立链表;输出链表Q删除链表中l点Q在链表中插入结?/strong>{等Q都是要熟练掌握的,初学者通过d的方式能比较形象地理解徏立、插入等实现的过E?/p>
typedef struct node
{
char data;
struct node *next;
}NODE; /*l点*/

正向建立链表Q?br />NODE *create()
{
char ch='a';
NODE *p,*h=NULL,*q=NULL;
while(ch<'z')
   {
   p=(NODE *)malloc(sizeof(NODE)); /*强制cd转换为指?/
   p->data=ch;
   if(h==NULL) h=p;
      elseq->next=p;
   ch++;
   q=p;
   }
q->next=NULL; /*链表l束*/
return h;
}

逆向建立Q?/p>
NODE *create()
{
char ch='a';
NODE *p,*h=NULL;
while(ch<='z')
   {
   p=(NODE *)malloc(sizeof(NODE));
   p->data=ch;
   p->next=h; /*不断地把head往前挪*/
   h=p;
   ch++;
   }
return h;
}

用递归实现链表逆序输出Q?/p>
void output(NODE *h)
{
if(h!=NULL)
   {
   output(h->next);
   printf("%c",h->data);
   }
}

插入l点Q已有升序的链表Q:

NODE *insert(NODE *h,int x)
{
NODE *new,*front,*current=h;
while(current!=NULL&&(current->data<x)) /*查找插入的位|?/
   {
   front=current;
   current=current->next;
   }
new=(NODE *)malloc(sizeof(NODE));
new->data=x;
new->next=current;
if(current==h) /*判断是否是要插在表头*/
   h=new;
else front->next=new;
return h;
}

删除l点Q?/p>
NODE *delete(NODE *h,int x)
{
NODE *q,*p=h;
while(p!=NULL&&(p->data!=x))
   {
   q=p;
   p=p->next;
   }
if(p->data==x) /*扑ֈ了要删的l点*/
   {
   if(p==h) /*判断是否要删表头*/
   h=h->next;
      elseq->next=p->next;
   free(p);
/*释放掉已删掉的结?/
   }
return h;
}

l常有链表相关的E序填空题,做这L题要注意看下面提到的变量是否定义了,用到的变量是否赋初gQ是否有l分配空间的没有分配I间Q最后看看返回值是否正?/p>

W者水qx限,隑օ有疏漏、错误的地方Q浅显之处,q望指正见谅。上q内容仅是个提示作用Qƈ不包括C语言的全部内宏V?



力力力 2006-07-18 23:29 发表评论
]]>
链表3http://www.tkk7.com/faintbear/archive/2006/07/17/58657.html力力力力力力Mon, 17 Jul 2006 14:56:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/17/58657.htmlhttp://www.tkk7.com/faintbear/comments/58657.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/17/58657.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/58657.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/58657.html 链表的运?02)

发表日期Q?003q??日    作者:C语言之家搜集整理  已经?462位读者读q此?/td>

3.链表节点的插?br />4.链表节点的删?/font>



3.链表节点的插?/font>
解:
    1) 首先声明一个新节点供输入要插入节点的内?br />    2) q戯入一个节点内?Key)Q表C欲插入在哪一个节点之?br />    3) 持箋往下一个节点,直到节点内容Key或节Ҏ针ؓNULL为止(x不到该节?
    4) 如果该节点不存在Q则插入在节点前
        New->Next=Head
        Head=New
    5) 如果扑ֈ该节点,?br />        New->Next=Pointer->Next
        Pointer->Next=New
*E序代码如下Q?br />#include<stdlib.h>
#include<stdio.h>
#define Max 10
struct List            /*节点l构声明*/
{
    int Number;
    int Total;
    struct List *Next;
};
typedef struct List Node;
typedef Node *Link;
int Data[2][Max]={1,3,5,7,2,4,6,8,9,0,15,35,10,67,25,65,38,70,30,20};
/*插入节点至链表内*/
Link Insert_List(Link Head,Link New,int Key)
{
    Link Pointer;        /*声明节点*/
    Pointer=Head;        /*Pointer指针设ؓ首节?/
    while(1)
    {
        if(Pointer==NULL)    /*插入在首节点?/
        {
            New->Next=Head;
            Head=New;
            break;
        }
        if(Pointer->Number==Key)    /*插入在链表中间或*/
        {
            New->Next=Pointer->Next;
            Pointer->Next=New;
            break;
        }
        Pointer=Pointer->Next;    /*指向下一个节?/
    }
    return Head;
}
/*输出链表数据*/
void Print_List(Link Head)
{
    Link Pointer;        /*节点声明*/
    Pointer=Head;        /*Pointer指针设ؓ首节?/
    while(Pointer!=NULL)    /*当节点ؓNULLl束循环*/
    {
        printf("[%d,%d]",Pointer->Number,Pointer->Total);
        Pointer=Pointer->Next;    /*指向下一个节?/
    }
    printf("\n");
}
/*释放链表*/
void Free_List(Link Head)
{
    Link Pointer;        /*节点声明*/
    while(Head!=NULL)    /*当节点ؓNULLl束循环*/
    {
        Pointer=Head;
        Head=Head->Next;
        free(Pointer);
    }
}
/*建立链表*/
Link Create_List(Link Head)
{
    Link New;        /*节点声明*/
    Link Pointer;    /*节点声明*/
    int i;
    Head=(Link)malloc(sizeof(Node));    /*分配内存*/
    if(Head==NULL)
        printf("Memory allocate Failure!\n");    /*内存分配p|*/
    else
    {
        Head->Number=Data[0][0];        /*定义首节Ҏ据编?/
        Head->Total=Data[1][0];
        Head->Next=NULL;
        Pointer=Head;        /*Pointer指针设ؓ首节?/
        for(i=1;i<Max;i++)
        {
            New=(Link)malloc(sizeof(Node));    /*分配内存*/
            New->Number=Data[0][i];
            New->Total=Data[1][i];
            New->Next=NULL;
            Pointer->Next=New;        /*新节点串连在原列表*/
            Pointer=New;            /*列表节点为新节点*/
        }
    }
    return Head;
}
/*ȝ?/
void main()
{
    Link Head;        /*节点声明*/
    Link New;
    int Key;
    Head=Create_List(Head);    /*建立链表*/
    if(Head!=NULL)
    {
        Print_List(Head);    
        while(1)
        {
            printf("Input 0 to Exit\n");    /*数据输入提示*/
            New=(Link)malloc(sizeof(Node));    /*分配内存*/
            printf("Please input Data number:");
            scanf("%d",&New->Number);
            if(New->Number==0)        /*输入0时结束@?/
                break;
            printf("Please input the data total:");
            scanf("%d",&New->Total);
            printf("Please input the data number for Insert:");
            scanf("%d",&Key);
            Head=Insert_List(Head,New,Key);    /*插入节点*/
            Print_List(Head);                /*输出链表数据*/
        }
        Free_List(Head);        /*释放链表*/
    }
}
*E序q行l果如下Q?br />

------------------------------------------------------------------

4.链表节点的删?/font>
解:
    持箋往下一个节Ҏ找要删除的节点,直到节点内容扑ֈ或节Ҏ针ؓNULL(x不到该节??br />    在删除时Q必记录前一个节点的位置(Back)
    如果该节点不存在Q输Z个节点不存在的提C?br />    如果该节点存在,且是首节点:
        Head=Pointer->Next
        free(Pointer)
    如果该节点存在,但不是首节点(即链表内节点或尾端节?Q则Q?br />        Back->Next=Pointer->Next
        free(Pointer)
*E序代码如下Q?br />#include<stdio.h>
#include<stdlib.h>
#define Max 10
struct List            /*节点l构声明 */
{
    int Number;
    int Total;
    struct List *Next;
};
typedef struct List Node;
typedef Node *Link;
int Data[2][Max]={1,3,5,7,2,4,6,8,9,10,15,35,10,67,25,65,38,70,30,20};
/*删除链表内节?/
Link Delete_List(Link Head,int Key)
{
    Link Pointer;        /*节点声明*/
    Link Back;
    Pointer=Head;        /*Pointer 指针设ؓ首节?/
    while(1)
    {
        if(Pointer->Next==NULL)
        {
            printf("Not Found!\n");
            break;
        }
        if(Head->Number==Key)        /*删除首节?/
        {
            Head=Pointer->Next;
            free(Pointer);
            break;
        }
        Back=Pointer;
        Pointer=Pointer->Next;    /*指向下一个节?/
        if(Pointer->Number==Key)    /*插入在链表中间或*/
        {
            Back->Next=Pointer->Next;
            free(Pointer);
            break;
        }
    }
    return Head;
}
/*输出链表数据*/
void Print_List(Link Head)
{
    Link Pointer;        /*节点声明*/
    Pointer=Head;        /*Pointer指针设ؓ首节?/
    while(Pointer!=NULL)    /*当节点ؓNULLl束循环*/
    {
        printf("[%d,%d]",Pointer->Number,Pointer->Total);
        Pointer=Pointer->Next;    /*指向下一个节?/
    }
    printf("\n");
}
/*释放链表*/
void Free_List(Link Head)
{
    Link Pointer;        /*节点声明*/
    while(Head!=NULL)    /*当节点ؓNULLl束循环*/
    {
        Pointer=Head;
        Head=Head->Next;        /*指向下一个节?/
        free(Pointer);
    }
}
/*建立链表*/
Link Create_List(Link Head)
{
    Link New;        /*节点声明*/
    Link Pointer;
    int i;
    Head=(Link)malloc(sizeof(Node));        /*分本内存*/
    if(Head==NULL)
        printf("Memory allocate Failure!\n");    /*内存分配p|*/
    else
    {
        Head->Number=Data[0][0];        /*定义首节Ҏ据编?/
        Head->Total=Data[1][0];
        Head->Next=NULL;
        Pointer=Head;        /*Pointer指针设ؓ首节?/
        for(i=1;i<Max;i++)
        {
            New=(Link)malloc(sizeof(Node));        /*分配内存*/
            New->Number=Data[0][i];
            New->Total=Data[1][i];
            New->Next=NULL;
            Pointer->Next=New;        /*新节点串连在原列表*/
            Pointer=New;            /*列表节点为新节点*/
        }
    }
    return Head;
}
/*ȝ?/
void main()
{
    Link Head=NULL;        /*节点声明*/
    int Key;
    Head=Create_List(Head);        /*建立链表*/
    if(Head!=NULL)
    {
        Print_List(Head);
        while(1)
        {
            printf("Input 0 to exit\n");    /*数据输入提示*/
            printf("Please input the data number for Delete:");
            scanf("%d",&Key);
            if(Key==0)        /*时结束@?/
                break;
            Head=Delete_List(Head,Key);    /*删除节点*/
            Print_List(Head);              /*输出链表*/
        }
        Free_List(Head);        /*释放链表*/
    }
}

*E序q行l果如下Q?/font>

  


力力力 2006-07-17 22:56 发表评论
]]>
链表2http://www.tkk7.com/faintbear/archive/2006/07/17/58656.html力力力力力力Mon, 17 Jul 2006 14:54:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/17/58656.htmlhttp://www.tkk7.com/faintbear/comments/58656.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/17/58656.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/58656.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/58656.html2.设计一个查N表中的数据的E序
解:
    单链表中的数据查找,只能采用U性查找法往下一个节Ҏ找。采用线性查找法查找链表中的数据时与数组不同的是Q原来数l是用递增数组索引来查找数据,在链表中是往下一个节Ҏ找?br />E序代码如下Q?br />#include<stdio.h>
#include<stdlib.h>
#define Max 10
struct List        /*l节点结构声?/   
{
    int Number;
    int Total;
    struct List *Next;
};
typedef struct List Node;
typedef Node *Link;
int Data[2][Max]=              /*初始化数?/
        {3,9,25,5,7,26,65,80,2,6,1050,3850,1000,5670,2250,9650,2380,
            1700,3000,2000};
int SearchTime=0;        /*查找ơ数*/
/*链表查找*/
int List_Search(int Key,Link Head)
{
    Link Pointer;
    Pointer=Head;        /*Pointer指针设ؓ首节?/
    while(Pointer!=NULL)    /*当节点ؓNULLl束循环*/
    {
        SearchTime++;
        if(Pointer->Number==Key)
        {
            printf("Data Number: %d\n",Pointer->Number);
            printf("Data Total: %d\n",Pointer->Total);
            return 1;
        }
        Pointer=Pointer->Next;      /*指向下一个节?/
    }
    return 0;
}
/*释放链表*/
void Free_List(Link Head)
{
    Link Pointer;        /*节点声明*/
    while(Head!=NULL)    /*当节点ؓNULLl束循环*/
    {
        Pointer=Head;
        Head=Head->Next;    /*指向下一个节?/
        free(Pointer);
    }
}
/*建立链表*/
Link Create_List(Link Head)
{
    Link New;        /*节点声明*/
    Link Pointer;    /*节点声明*/
    int i;
    Head=(Link)malloc(sizeof(Node));    /*分配内存*/
    if(Head==NULL)
        printf("Memory allocate Failure!\n");    /*内存分配p|*/
    else
    {
        Head->Number=Data[0][0];        /*定义首节Ҏ据编?/
        Head->Total=Data[1][0];
        Head->Next=NULL;
        Pointer=Head;            /*Pointer指针设ؓ首节?/
        for(i=1;i<Max;i++)
        {
            New=(Link)malloc(sizeof(Node));    /*分配内存*/
            New->Number=Data[0][i];
            New->Total=Data[1][i];
            New->Next=NULL;
            Pointer->Next=New;        /*新节点串连在原列表*/
            Pointer=New;              /*列表节点为新节点*/
        }
    }
    return Head;
}
/*ȝ?/
void main()
{
    Link Head=NULL;        /*节点声明*/
    int Num;          /*Ʋ查找数据编?/
    Head=Create_List(Head);    /*建立链表*/
    if(Head!=NULL)
    {
        printf("Please input the data number:");
        scanf("%d",&Num);
        if(List_Search(Num,Head))
            printf("Search Time=%d\n",SearchTime);
        else
            printf("Not Found!\n");
        Free_List(Head);        /*释放链表*/
    }
}
*q行l果如下Q?br />



力力力 2006-07-17 22:54 发表评论
]]>
链表http://www.tkk7.com/faintbear/archive/2006/07/17/58655.html力力力力力力Mon, 17 Jul 2006 14:53:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/17/58655.htmlhttp://www.tkk7.com/faintbear/comments/58655.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/17/58655.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/58655.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/58655.html 链表的运?01)

发表日期Q?003q??日    作者:C语言之家搜集整理  已经?901位读者读q此?/td>

1.设计一个程序将输入的数据徏立成链表、输出链表数据ƈ在程序结束后释放?br />2.设计一个查N表中的数据的E序



1.设计一个程序将输入的数据徏立成链表、输出链表数据ƈ在程序结束后释放?br />解:
    1)链表的徏立:先声明一个首节点HeadQƈHead->Next设ؓNULL。每输入一个数据就声明一个新节点NewQ把New->Next设ؓNULLQƈ且链接到之前列表的尾端?br />    2)链表数据的输出:先将Pointer节点的指针指向第一个节点,Pointer节点(即第一个节?的数据输出。然后再Pointer节点的指针指向Pointer指针的的指针(即下一节点)Q将pointer节点(即第一节点)的数据输出。重复执行此步聚直到Pointer指针指向NULL为止?br />    3)链表的释放:先将Pointer节点的指针指向第一个节点,然后再将首节点设为首节点的指?即下一节点)。将Pointer节点(即第一节点)释放。重复执行此步聚直到首节点的指针指向NULL为止?br />E序代码如下Q?br />#include<stdlib.h>
#include<stdio.h>
#define Max 10
struct List             /*节点l构声明*/
{
    int Number;
    char Name[Max];
    struct List *Next;
};
typedef struct List Node;
typedef Node *Link;
/*释放链表*/
void Free_List(Link Head)
{
    Link Pointer;      /*节点声明*/
    while(Head!=NULL)      /*当节点ؓNULLQ结束@?/
    {
        Pointer=Head;
        Head=Head->Next;   /*指向下一个节?/
        free(Pointer);
    }
}
/*输出链表*/
void Print_List(Link Head)
{
    Link Pointer;          /*节点声明*/
    Pointer=Head;          /*Pointer指针设ؓ首节?/
    while(Pointer!=NULL)   /*当节点ؓNULLl束循环*/
    {
        printf("##Input Data##\n");
        printf("Data Number: %d\n",Pointer->Number);
        printf("Data Name: %s\n",Pointer->Name);
        Pointer=Pointer->Next;     /*指向下一个节?/
    }
}
/*建立链表*/
Link Create_List(Link Head)
{
    int DataNum;         /*数据~号*/
    char DataName[Max];        /*数据名称*/
    Link New;            /*节点声明*/
    Link Pointer;        /*节点声明*/
    int i;
    Head=(Link)malloc(sizeof(Node));     /*分配内存*/
    if(Head==NULL)
        printf("Memory allocate Failure!\n");    /*内存分配夫|*/
    else
    {
        DataNum=1;      /*初始数据~号*/
        printf("Please input the data name:");
        scanf("%s",DataName);
        Head->Number=DataNum;     /*定义首节Ҏ据编?/
        for(i=0;i<=Max;i++)
            Head->Name[i]=DataName[i];
        Head->Next=NULL;
        Pointer=Head;          /*Pointer指针设ؓ首节?/
        while(1)
        {
            DataNum++;         /*数据~号递增*/
            New=(Link)malloc(sizeof(Node));     /*分配内存*/
            printf("Please input the data Name:");
            scanf("%s",DataName);
            if(DataName[0]=='0')    /*输入0则结?/
                break;
            New->Number=DataNum;
            for(i=0;i<Max;i++)
            {
                New->Name[i]=DataName[i];
            }
            New->Next=NULL;
            Pointer->Next=New;     /*新节点串连在原列表*/
            Pointer=New;         /*列表节点为新节点*/
        }
    }
    return Head;
}
/*ȝ?/
void main()
{
    Link Head;       /*节点声明*/
    Head=Create_List(Head);     /*调用建立链表函数*/
    if(Head!=NULL)
    {
        Print_List(Head);      /*调用输出链表数据函数*/
        Free_List(Head);       /*调用释放链表函数*/
    }
}

q行l果如下Q?br />



力力力 2006-07-17 22:53 发表评论
]]>
MIDP2.0及其UL技术分??http://www.tkk7.com/faintbear/archive/2006/07/12/57798.html力力力力力力Wed, 12 Jul 2006 06:32:00 GMThttp://www.tkk7.com/faintbear/archive/2006/07/12/57798.htmlhttp://www.tkk7.com/faintbear/comments/57798.htmlhttp://www.tkk7.com/faintbear/archive/2006/07/12/57798.html#Feedback0http://www.tkk7.com/faintbear/comments/commentRss/57798.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/57798.html 摘要Q?/b>MIDP即移动信息设备规范,是专门基于资源和|络q接有限的移动设备之上的J2ME应用规范。本文在分析MIDP2.0的基上,详细阐述MIDP的事件处理、文件系l、用户图形接口和|络{主要部分在不同q_间移植的实现q程?

    关键词:J2ME MIDP UL q_无关 本地代码

1 MIDP2.0?/b>

随着C信息化社会的发展Q小型移动通信讑֤已经从最初的一U单U的通信工具转变成如今集通信、工作、娱乐等功能Z体的l合讑֤Q但仅有q些q不能满用L要求。个性永q是千变万化的,时尚也不会始lؓ一U模式。因此,在移动终端上开发通用的、丰富的应用已成为必然的势。这些应用可以按用户的意愉K时安装和删除?/p>

J2MEQJAVA2 Micro EditionQ正是这样一UJAVA应用开发^台。实际上QJAVA语言从其诞生起就以其q行的^台无x这一强大的优势而成为网l应用的宠儿。J2ME是JAVA2标准版本的微型版本,专门为小型移动设备所设计。这些设备处理器的处理能力都不强Q可使用的资源也有限。因此,J2ME只包含了J2SE中在Ud通信讑֤上所必需的功能和lgQ其能够在Ud讑֤及其有限的资源上开发出丰富多彩且^台无关的应用。J2ME在结构上分ؓCDCQConnecte Device ConfigurationQ和Z其上Q以Foundation ProfileZ的规范,以及CLDCQConnecte Limited Device ConfigurationQ和Z其上Q以MIDPZ的规范?/p>

MIDPQMobile Information Device ProfileQ是UM息设备规范的U。规范具体定义了J2ME适用的硬件和软g框架Qƈ提供了这个框架要实现的基本功能及其标准接口;而应用开发者就可以Zq个框架开发出各种应用?000q?月,SUN公司发布了MIDP的第一个正式版本MIDP1.0。它J2ME适用的设备定位在臛_拥有数百KB RAM和ROMQƈh基本|络和显C功能的Ud通信讑֤上;在该基础上定义了一pd软g接的Ud通信讑֤上;在该上基上定义了一pd软g接口Q其中包括基本输入输出、图形化用户接口QGUIQ、网l、事件机制、文件系l、应用管理系l(AMSQ等之后Q随着JAVA技术的不断发展和用户需求的不断提高QSUN公司又于2002q?1月发布了MIDP2.0。它对设备的内存资源和处理能力的要求?.0要高Q但MIDP2.0也ؓ应用开发者提供了更方ѝ更丰富多彩的Y件包Q主要增加了游戏接口的实现、声韌出接口的实现安全|络机制的实现。MIDP2.0的这些特性将使基于移动设备的JAVA应用h更加qK的前景,也必C代的Ud讑֤发生革命性的变化q导时潮。MIDP2.0接口包如?所列?br />
? MIDP2.0接口包及其功?/b>

?/td> 功    ??/td>
javax.microedition.lcdui 提供一pd用户界面接口
javax.microedition.lcdui.game 专门用于游戏设计的接?/td>
javax.microedition.rms 数据理Q用于保存数据记?/td>
javax.microedition.midlet JAVA应用理接口
javax.microedition.io 基本|络q接接口
javax.microedition.media 媒体接口规范QJSR-135Q的实现?/td>
javax.microedition.media.control 媒体播放器的控制c?/td>
javax.microedition.pki 数字{֐规范的实现接口(用于安全|络Q?/td>
java.io JAVA基本输入输出接口
java.lang JAVA基本数据cd接口
java.util JAVA基本应用接口

2 MIDP2.0的移?/b>

既然MIDP2.0是定位在Ud通信讑֤之上的一pdJAVA应用开发接口,我们必考虑如何整个MIDPpȝ嵌入到特定的g讑֤和其上的操作pȝ中。只有这PJAVA应用E序才能q行在该讑֤上,q利用MIDP提供的强大功能将用户带入一个全新的JAVA世界。在一个完全不同的操作pȝq_上,用该q_上对应的pȝAPI调用Q或一pd操作Q,替换MIDP参考实C所有与操作q_相关的调用(或操作)QMIDP能在目标q_上正地执行所有要求的功能Q同Ӟ调用该^CҎ的能充分发挥目标讑֤gҎ的接口Q替换参考实C相应的接口,使MIDP能在目标q_上更高效地运行,q个q程q为MIDP的移植?/p>

MIDPp多不同的部分l成Q每一部分完成MIDP一个特定的功能接口。其中需要移植的部分主要包括事g处理、文件系l、用户图形化接口、网l、AMS、多媒体。它们都分ؓ高端的JAVA层和低端的本地方法层。JAVA层是用JAVA语言实现的,由KVM解释执行Q因此没有涉及到与操作系l^台相关的调用和操作,可以不经修改在M操作q_上运行,是^台无关的QPlateForm IndependentQ。它的移植主要是为满用LҎ要求而进行的个性化工作。本地方法层QNativeCodeQ是指ؓ提高代码的执行效率,保持JAVA语言的^台无x而用C语言实现的部分MIDP功能的代码。本地即是指它是与当前的操作q_相关的,它的UL才是涉及到具体^台和执行效率而进行的具体调用和操作的替换q程Q其l构如图1所C?/p>

下面Q我们就具体到MIDP的每一个部分的ULq行讨论?/p>

2.1 事g处理

MIDP的事件处理部分要处理的事件主要来自两个方面:①来自虚拟机底层的事Ӟ如虚拟机的异常消息;②来自MIDP内部的事Ӟ如屏q刷新、按键消息、触控笔点击消息、时钟消息等。由于不同的q_可能使用不同的事件消息获取和传递机Ӟ因此MIDP事g处理的移植也集中在这上面Q其实现被放在本地方法层的文件nativeGUI.c中的函数GetAndStoreKVMEvent中。我们只需Ҏ目标q_获取和传递事件的要求修改该文件中的相应函数即可?/p>

例如QWindows采用消息响应机制来处理各U事Ӟ所有消息都可以通过pȝAPI调用GetMessage获取Q系l会调用消息处理函数WndProc(HWND hwnd、UINTiMsg、WPARAM wParam、LRARAM 1Param)Q在其中处理和传递不同的事g。其大致实现q程如下Q?/p>

void

GetAndStoreNextKVMEvent(bool_t forever,ulong64 waitUntil){

MSG msgQ?/p>

…?/p>

while(GetMessage(&msg,NULL,0,0)){

…?/p>

TranslateMessage(&msg);

DispatchMessage(&msg);

if(gotEvent){

StoreMIDPEvent(&kvmEvent);

Return;

}

}

return;

}

static LRESULT CALLBACK

WndProc (HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam){

…?/p>

switch(iMsg){

case WM_CREATE:

…?/p>

case WM_KEYDOWN:

case WM_KEYUP:

…?/p>

}

}

MIDP在GetAndStoreNextKVMEvent中获取事件后Q就完全独立C递和处理事g消息Q与q_无关Q因此无需UL?br />
    2.2 文gpȝ

ZMIDP的JAVA应用以及MIDP本n在某些时候要求数据能够长期保存,即在应用退出或pȝ掉电的情况下Q数据也不能丢失。这必d助于MIDP的文件系l。MIDP的文件系l同样分为JAVA层(UCؓRMSQ即Record Manage SystemQ和本地Ҏ层。一般情况下Q文件系l的JAVA层不用移植就可以在Q何^Cq行Q但如果目标q_的文件系l较为特D,例如采用数据库的记录方式保存数据Q甚x本就没有提供高效的数据存取接口,我们必自己实现数据存取接口。这PJAVA层就需要蟩qRMS而直接通过本地Ҏ调用本地接口Q相应的RMS的JAVA代码可以从MIDP中删厅R?/p>

而在文gpȝ的本地方法层QMIDP会调用目标^台的数据存取接口来实现MIDP本n的数据存取。这些接口是q_相关的,是文件系l中需要移植的部分。这些调用被攑֜文gsrc/share/native/storage.c中,主要包括文g的打开QopenQ、文件的关闭QcloseQ、文件的dQread、writeQ、文件属性的获取Qsize、freesize{)、文件的删除QdeleteQ、文件的定位QseekQ、文件的删节QtruncateQ等。以下便是MIDP文gpȝ在Windows下的部分实现?/p>

文g的打开Q?/p>

int storageOpen(char**ppszError,char*pszAsciiFilename,int ioMode){

…?/p>

handle=open(pszAsciiFilename,flags,creationMode)Q?/p>

…?/p>

}

文g的关闭:

void storageClose(char**ppszError,int handle){

…?/p>

status=close(handle)Q?/p>

…?/p>

}

文g的读取:

int storageRead(char**ppszError,int handle,char*buffer,int length)

{

…?/p>

bytesRead=read(handle,buffer,length);

…?/p>

}

文g的写入:

void storageWrite(char**ppszError,int handle,char*buffer,int length){

…?/p>

bytesWritten=write(handle,buffer,length);

…?/p>

}

q有许多其它有关文g的操作,UL时只需使用目标q_的API替换以上的Widnows调用Q这里就不再逐一列D?/p>

2.3 用户囑Ş化接?/p>

用户囑Ş化接口包括画炏V画Uѝ作圆、作椭圆、位图拷贝等基本作图函数Q可在GRAPHICS.C中找刎ͼQ有兛_时器、屏q刷新和键盘触控W消息等有关与用户交互的操作Q可在TEXT.C中找刎ͼQ它是整个MIDPUL中工作量最大,也是对上层应用的执行效率影响最大的一个部分。这是因为用户在应用中看到的各种囑Ş和文字都是调用底层的囑Ş函数在屏q上作图的结果。由于屏q要频繁hQ图形函C成为应用调用最多的接口。因此,UL者必M每一个底层作囑ևCg讑֤紧密配合hQƈ使用最高效的算法?/p>

在不同的q_上,能最大地发挥其作囑֊能的函数和算法不相Q这p求移植者作大量l致的工作,按照MIDP规范的要求逐一重新实现每一个作囑և数和屏幕h?数。下面我们就以将ȝ函数和位图拷贝函数在Windows上的实现ZQ简单说明移植要做的工作Q键盘、触控笔是以事g消息的方式实现的Q它们的UL与事件消息的UL相同Q?/p>

Windows的画U函数接口:

Void LCDUIdrawLine(int pixel,short*clip,void*dst,int dotted,int x1,int y1,int x2,int y2){

…?/p>

Polyline(hdc,pts,2);/*lx1,y1点像素信?/

…?/p>

}

Windwos的屏q刷新函敎ͼ

Void refreshPaintWindow(int x1,int y1,int x2,int y2){

RECT rQ?/p>

If(x1<x2){

r.left=x1+x_offset;r.right=x2+x_offset;

}else{

r.left=x2+x_offset;r.right=x1+x_offset;

}

if(y1<y2){

r.top=y1+y_offset;r.bottom=y2+y_offset;

}else{

r.top=y2+y_offset;r.bottom=y1+y_offsetQ?/p>

}

++r.bottom;++r.right;

InvalidateRect(hMainWindow,&r,KNI_TRUE);

}

如果目标q_对这些GUI接口函数有不同实现法Q可以用q些Ҏ替换以上的Windowspȝ调用Q这h能MIDP囑Ş化用h口正地工作Qƈ充分发挥目标q_的工作效率?/p>

2.4 |络

MIDP的网l功能是指基于MIDP的J2ME应用可以通过HTTP{网l协议进行下载安装,不同的MIDlet实体也可以通过它交换信息,实现资源׃n。遵循HTTP协议的规定,UL者必d用目标^台的底层|络接口重新实现|络的初始化QnetworkInitQ、徏立连接(open0Q、断开q接Qclose0Q、接收数据(read0Q、获取缓冲区的剩余空_available0Q、关闭发送(shutdownOutputQ。如果目标设备具有服务器功能Q还要实现serversocket所有上q功能。所有上q接口都在文件socketProtocol_md.c中实现?/p>

Windwos中获取IP地址的实玎ͼ

Int prim_com_sun_midp_io_j2me_socket_Protocol_getIpNumber

(char*host)

{

…?/p>

hp=gethostbyname(host);

…?/p>

}

如果目标q_q需要其它网l协议(datagram、commQ,其移植过E与Socket的移植基本相同?/p>

2.5 应用理pȝQAMSQ?/p>

MIDP的应用管理系l?application management system)负责理当前讑֤中安装的J2ME应用Q其功能包括MIDlet的加载、安装、显C、更新和删除。AMS从main.c中的函数main()开始执行,Ҏ其输入初始化一些系l参敎ͼ包括pȝ路径QclassJ2ME MIDP UL q_无关 本地代码Q、堆I间大小QheapsizeQ、命令行Qcommand lineQ等Q然后就启动KVMQ而KVM׃从AMS的JAVA界面main.java开始解释执行java代码。AMS的所有管理功能都是用JAVA语言实现的,因此AMS的实现是与^台无关的。但不同的^台可能有不同的系l参数和格式Q对AMS的界面网l也可能有不同的要求。所以,UL者有可能要修改main.c中解析系l参数的部分Q保证AMS能正解析目标^台的所有参敎ͼ同时修改AMS的JAVA层,使其界面|络满用户的需求?/p>

2.6 多媒?/p>

MIDP2.0较MIDP1.0最大的改变是在MIDP2.0中向应用提供了音频接口(Audio APIQ的支持。音频接口是Ud讑֤媒体接口MMAPIQMobile Media APIQ的一部分。音频的播放q程?个部分(unrealized、realized、prefetched、started、closedQ,同时它有自己的音频播放事件的传道和处理过E。MIDP音频播放部分所要做的移植工作就主要集中在声x放接口,事g的处理方式和兼容不同的音频文件格式上?/p>

播放接口的移植:不同的目标^収ͼ提供的音频系lAPI是不同的Q有的系l甚x本没有提供播N频的API。这ӞUL者就要根据目标^台的实现情况替换或自己实现音频的播放接口?/p>

Windows的音频播放接口(win32/native/MMATONE.CQ:

Java_javax_microedition_media_Manager_nPlayTone(KNITRAPS)

{

…?/p>

chn1=getMidiChnl();

if(chnl==-1){

KNI_ReturnInt(0)Q?/p>

}

tones[chn].msg=((note&0xff)<<8)|0x00000090|(chnl&0xf);

msg=((vol&0xff)<<16)|((note&0xff)<<8)|0x90|(chnl &0xf);

midiOutShortMsg(midiOut,msg);

timerID=timeSetEvent(dur,TIMERES,(LPTIME CALLBACK)timeToneProc,(DWORD)chnl,TIME_ONESHOT);

tones[chnl].timerID=timerID;

…?/p>

}

事g传递的ULQMIDP中音频播攄束的事gQEOMQ是专门通过pȝ的消息机制传递,而不是通过MIDP的事件传递,因此也需要移植:

Windows---OM的传递(win32/native/MMAEVT.CQ?void injectNativeEvent(int pID,int curMTime){

PostMessage(hMain Window,WM_APP,(WPARAM)(pID),(LPARAM)(curMTime));

return;

}

3 ȝ

lg所qͼMID2.0的移植要以两个方面ؓ出发点:①兼Ҏ。移植后的MIDP实现必须能够在目标^C正常q行Q所有与目标q_不兼容的调用都必L换ؓ能完成相同功能且兼容的目标^台的pȝ调用或过E。②高效性。移植后的MIDP实现必须能充分发挥目标^台的效率和特性,用最的代h完成MIDP的功能。另外,MIDP的移植还要分满最l用L个性化要求Qؓ它们设计Z富多彩的界面|络?



力力力 2006-07-12 14:32 发表评论
]]>
Linux以及各大发行版介l?/title><link>http://www.tkk7.com/faintbear/archive/2006/02/21/31868.html</link><dc:creator>力力力</dc:creator><author>力力力</author><pubDate>Tue, 21 Feb 2006 14:13:00 GMT</pubDate><guid>http://www.tkk7.com/faintbear/archive/2006/02/21/31868.html</guid><wfw:comment>http://www.tkk7.com/faintbear/comments/31868.html</wfw:comment><comments>http://www.tkk7.com/faintbear/archive/2006/02/21/31868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/faintbear/comments/commentRss/31868.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/faintbear/services/trackbacks/31868.html</trackback:ping><description><![CDATA[<STRONG>什么是LinuxQ?/STRONG> <BR><BR>也许很多Z不屑的说QLinux不就是个操作pȝ么。错QLinux不是一个操作系l,严格来讲Q?STRONG>Linux只是一个操作系l中的内?/STRONG>。内核是什么?内核建立了计机软g与硬件之间通讯的^収ͼ内核提供pȝ服务Q比如文件管理、虚拟内存、设备I/O{?<BR><BR>既然Linux只是一个内核。那么我们通常所说的Linux操作pȝ又是什么?我们通常所说的LinuxQ指 <STRONG>GNU/Linux</STRONG> Q即采用Linux内核的GNU操作pȝ。是的,操作pȝ的实际名U是GNU。什么是GNUQGNU代表<STRONG>G</STRONG>NU’s <STRONG>N</STRONG>ot <STRONG>U</STRONG>nix。可以说是一个操作系l又可以说是一U规范。比如,众所周知的PHPQ原名ؓPersonal HomePageQ个Z)Q根据GNU的Y件命名规则,PHP现已更名?STRONG>P</STRONG>HP: <STRONG>H</STRONG>ypertext <STRONG>P</STRONG>reprocessorQ超文本预处理程序)?<BR><BR><STRONG>谁编?创造了LinuxQ?/STRONG> <BR><BR>Linux最早由Linus Torvalds?991q开始编写。在q之前,Richard Stallman创徏了Free Software FoundationQFSFQ组l以及GNU目Qƈ不断的编写创建GNUE序Q程序的许可方式均ؓ<STRONG>GPL</STRONG>: General Public LicenseQ。在不断的有E序员和开发者加入到GNUl织中后Q变造就了今天我们所看到的LinuxQ或UGNU/Linux?<BR><BR><STRONG>什么是Linux发行版?</STRONG> <BR><BR>正如之前所说的QLinux只是一个内核。然而,一个完整的操作pȝ不仅仅是内核而已。所以,许多个h、组l和企业Q开发了ZGNU/Linux的Linux发行版。这其中最著名的便是Red Hat公司的Red Hatpd以及C֌QcommunityQ组l的Debianpd?<BR><BR>下面我就单得介绍一下目前比较著名、流行的Linux发行版本。部分资料来源:<A target=_new rel=nofollow>DistroWatch.com</A> <BR><BR><STRONG>Mandriva</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/mandrake.png src="http://www.noobu.com/img/linux_distro/mandrake.png"> <BR><BR>Mandriva原名MandrakeQ最早由Gaël Duval创徏q在1998q?月发布。记得前两年国内刚开始普及LinuxӞMandrake非常行。说起Mandrake的历Ԍ其实最早Mandrake的开发者是ZRedhatq行开发的。Redhat默认采用GNOME桌面pȝQ而Mandrake之改ؓKDE。而由于当时的Linux普遍比较隑֮装,不适合W一ơ接触Linux的新手,所以Mandrakeq简化了安装pȝ。我惌也是当时Mandrake在国内如此红火的原因之一。Mandrake在易用性方面的是下了不少功夫Q包括默认情况下的硬件检等?<BR><BR>Mandrake的开发完全透明化,包括“cooker”。当pȝ有了新的试版本后,便可以在cooker上找到。之前Mandrake的新版本的发布速度很快Q但?.0之后便开始减~。估计是希望能够廉版本的生命力以确保稳定和安全性?<BR><BR>优点Q友好的操作界面Q图形配|工P庞大的社区技术支持,NTFS分区大小变更 <BR>~点Q部分版本bug较多Q最新版本只先发布给Mandrake׃部的成员 <BR>软g包管理系l:urpmi (RPM) <BR>免费下蝲QFTPx发布下蝲QISO在版本发布后数星期内提供 <BR>官方主页Q?A target=_new rel=nofollow>http://www.mandrivalinux.com/</A> <BR><BR><STRONG>Red Hat</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/fedora.png src="http://www.noobu.com/img/linux_distro/fedora.png"> <BR><BR>国内Q乃x全世界的Linux用户所最熟悉、最耳闻能详的发行版惛_是Red Hat了。Red Hat最早由Bob Young和Marc Ewing?995q创建。而公司在最q才开始真正步入盈利时代,归功于收费的Red Hat Enterprise LinuxQRHELQRed Hat的企业版Q。而正l的Red Hat版本早已停止技术支持,最后一版是Red Hat 9.0。于是,目前Red Hat分ؓ两个pdQ由Red Hat公司提供收费技术支持和更新的Red Hat Enterprise LinuxQ以及由C֌开发的免费的Fedora Core。Fedora Core 1发布?003q年末,而FC的定位便是桌面用戗FC提供了最新的软g包,同时Q它的版本更新周期也非常短,仅六个月。目前最新版本ؓFC 3Q而FC4也预定将于今q?月发布。这也是Z么服务器上一般不推荐采用Fedora Core?<BR><BR>适用于服务器的版本是Red Hat Enterprise LinuxQ而由于这是个收费的操作系l。于是,国内外许多企业或I间商选择<A target=_new rel=nofollow>CentOS</A>。CentOS可以是RHEL的克隆版Q但它最大的好处是免费!菜鸟油目前的服务器便采用的CentOS 3.4?<BR><BR>优点Q拥有数量庞大的用户Q优U的社区技术支持,许多创新 <BR>~点Q免费版QFedora CoreQ版本生命周期太短,多媒体支持不?<BR>软g包管理系l:up2date (RPM), YUM (RPM) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.redhat.com/</A> <BR><BR><STRONG>SUSE</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/suse.png src="http://www.noobu.com/img/linux_distro/suse.png"> <BR><BR>SUSE是d国最著名的Linux发行版,在全世界范围中也享有较高的声誉。SUSE自主开发的软g包管理系lYaST也大受好评。SUSE?003q年末被Novell收购?<BR><BR>SUSE之后的发布显得比较؜乱,比如9.0版本是收费的Q?0.0版本Q也许由于各U压力)又免费发布。这使得一部分用户感到困惑Q也转而用其它发行版本。但是,瑕不掩瑜QSUSE仍然是一个非怸业、优U的发行版?<BR><BR>优点Q专业,易用的YaST软g包管理系l?<BR>~点QFTP发布通常要比零售版晚1~3个月 <BR>软g包管理系l:YaST (RPM), W三方APT (RPM) 软g库(repositoryQ?<BR>免费下蝲Q取决于版本 <BR>官方主页Q?A target=_new rel=nofollow>http://www.suse.com/</A> <BR><BR><STRONG>Debian GNU/Linux</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/debian.png src="http://www.noobu.com/img/linux_distro/debian.png"> <BR><BR>Debian是菜鸟a服务器之前所采用的操作系l。Debian最早由Ian Murdock?993q创建。可以算是迄今ؓ止,最遵@GNU规范的Linuxpȝ。Debianpȝ分ؓ三个版本分支QbranchQ:stable, testing ?unstable。截?005q?月,q三个版本分支分别对应的具体版本为:Woody, Sarge ?Sid。其中,unstable为最新的试版本Q其中包括最新的软g包,但是也有相对较多的bugQ适合桌面用户。testing的版本都l过unstable中的试Q相对较为稳定,也支持了不少新技术(比如SMP{)。而Woody一般只用于服务器,上面的Y件包大部分都比较q时Q但是稳定和安全性都非常的高。菜鸟a之前所采用的是Debian Sarge?<BR><BR>Z有如此多的用Lq于Debian呢(包括W者在内)Qapt-get / dpkg是原因之一。dpkg是DebianpdҎ的Y件包理工具Q它被誉为所有Linux软g包管理工P比如RPMQ最强大的!配合apt-getQ在Debian上安装、升U、删除和理软g变得异常Ҏ。许多Debian的用户都开玩笑的说QDebian他们养懒了Q因为只要简单得敲一下”apt-get upgrade && apt-get update”,机器上所有的软g׃自动更新了…?<BR><BR>优点Q遵循GNU规范Q?00%免费Q优U的网l和C֌资源Q强大的apt-get <BR>~点Q安装相对不易,stable分支的Y件极度过?<BR>软g包管理系l:APT (DEB) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.debian.org/</A> <BR><BR><STRONG>Ubuntu</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/ubuntu.png src="http://www.noobu.com/img/linux_distro/ubuntu.png"> <BR><BR>W者的桌面电脑便用的Ubuntu。依照笔者的理解Q简单而言QUbuntu是一个拥有Debian所有的优点Q以及自己所加强的优点的q乎完美的Linux操作pȝ?) Ubuntu是一个相对较新的发行版,但是Q它的出现可能改变了许多潜在用户对Linux的看法。也许,从前Z会认为Linux难以安装、难以用,但是QUbuntu出现后,q些都成Z历史。UbuntuZDebian SidQ所以这也就是笔者所说的QUbuntu拥有Debian的所有优点,包括apt-get。然而,不仅如此而已QUbuntu默认采用的GNOME桌面pȝ也将Ubuntu的界面装饰的易而不失华丽。当Ӟ如果你是一个KDE的拥护者的话,Kubuntu同样适合你! <BR><BR>Ubuntu的安装非常的人性化Q只要按照提CZ步一步进行,安装和Windows同样便!q且QUbuntu被誉为对g支持最好最全面的Linux发行版之一Q许多在其他发行版上无法使用Q或者默认配|时无法使用的硬Ӟ在Ubuntu上轻松搞定。ƈ且,Ubuntu采用自行加强的内核(kernelQ,安全性方面更上一层楼。ƈ且,Ubuntu默认不能直接root登陆Q必MW一个创建的用户通过su或sudo来获取root权限Q这也许不太方便Q但无疑增加了安全性,避免用户׃_心而损坏系l)。Ubuntu的版本周期ؓ六个月,弥补了Debian更新~慢的不?<BR><BR>优点Qh气颇高的论坛提供优秀的资源和技术支持,固定的版本更新周期和技术支持,可从Debian Woody直接升 <BR>~点Q还未徏立成熟的商业模式 <BR>软g包管理系l:APT (DEB) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.ubuntulinux.org/</A> <BR><BR><STRONG>Gentoo</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/gentoo.png src="http://www.noobu.com/img/linux_distro/gentoo.png"> <BR><BR>Gentoo最初由Daniel RobbinsQ前Stampede Linux和FreeBSD的开发者之一Q创建。由于开发者对FreeBSD的熟识,所以Gentoo拥有媲美FreeBSD的广受美誉的portspȝ——portage。(Ports和Portage都是用于在线更新软g的系l,cMapt-getQ但q是有很大不同)Gentoo的首个稳定版本发布于2002q?<BR><BR>Gentoo的出名是因ؓ光度的自定制性:因ؓ它是一个基于源代码的(source-basedQ发行版。尽安装时可以选择预先~译好的软g包,但是大部分用Gentoo的用户都选择自己手动~译。这也是Z么Gentoo适合比较有Linux使用l验的老手使用的原因。但是要注意的是Q由于编译Y仉要消耗大量的旉Q所以如果你所有的软g都自q译,q安装KDE桌面pȝ{比较大的Y件包Q可能需要几天时间才能编译完…?<BR><BR>优点Q高度的可定制性,完整的用手册,媲美Ports的PortagepȝQ适合“臭”的高手使用^^ <BR>~点Q编译耗时多,安装~慢 <BR>软g包管理系l:Portage (SRC) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.gentoo.org/</A> <BR><BR><STRONG>Slackware</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/slackware.png src="http://www.noobu.com/img/linux_distro/slackware.png"> <BR><BR>Slackware由Patrick Volkerding创徏?992q。算h应当是历史最悠久的Linux发行版。曾lSlackware非常的流行,但是当Linux来普及,用户的技术层面越来越q(更多的新手)后,Slackware渐渐的被新来的h们所遗忘。在其他L发行版强调易用性的时候,Slackware依然固执的追求最原始的效率——所有的配置均还是要通过配置文g来进行?<BR><BR>管如此QSlackware仍然深入人心Q大部分都是比较有经验的Linux老手Q。SlackwareE_、安全,所以仍然有大批的忠实用戗由于Slackware量采用原版的Y件包而不q行M修改Q所以制造新bug的几率便低了很多。Slackware的版本更新周期较长(大约1q_Q但是新版本的Y件仍然不间断的提供给用户下蝲?<BR><BR>优点Q非常稳定、安全,高度坚持UNIX的规?<BR>~点Q所有的配置均通过~辑文g来进行,自动g能力较?<BR>软g包管理系l:Slackware Package Management (TGZ) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.slackware.com/</A> <BR><BR><STRONG>Knoppix</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/knoppix.png src="http://www.noobu.com/img/linux_distro/knoppix.png"> <BR><BR>由d国的Klaus Knopper开发的KnoppixQ是一个基于Debian的发行版。Knoppix严格v来是一ƾLiveCD LinuxQ所谓的LiveCD是整个操作pȝ都在一张光盘上Q只要开Z光盘启动Q就能拥有一个完整的LinuxpȝQ无需安装Q当ӞKnoppix也能够非常轻杄安装到硬盘上。其强大的硬件检能力、系l修复能力、即时压~传输技术,都o人大加称赞。可以说Q在LiveCD界,Knoppix是无及的Q?<BR><BR>优点Q无需安装可直接运行于CD上,优秀的硬件检能力,可作为系l急救盘?<BR>~点QLiveCD׃光盘的数据读取速度限制D性能大幅下降 <BR>软g包管理系l:APT (DEB) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.knoppix.com/</A> <BR><BR><STRONG>MEPIS</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/mepis.png src="http://www.noobu.com/img/linux_distro/mepis.png"> <BR><BR>MEPIS由Warren Woodford?003q徏立。MEPIS虽然刚徏立不久,但是q速的传播在Linux用户间。简单来_MEPIS是一个集合了Debian Sid和Knoppix的物。用户即能将之当作LiveCD使用Q也能用常规的囑Ş界面q行安装?<BR><BR>MEPIS默认集成安装了Java Runtime Environment、Flash插g、nVidia加速驱动等许多常用的程序。用户可以非常轻杄安装完系l后q接开始用,而不用到处寻找资料如何下载、如何安装、如何配|这些Y件。这不仅lLinux新手带来了便P也给老手们节U了相当多的旉?<BR><BR>优点QLiveCD与常规安装两用,优秀的硬件检能力,预装了许多实用的软g <BR>~点Q徏立时间不长,默认的界面有些寒?<BR>软g包管理系l:APT (DEB) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.mepis.org/</A> <BR><BR><STRONG>Xandros</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/xandros.png src="http://www.noobu.com/img/linux_distro/xandros.png"> <BR><BR>Xandros建立在已l成为历史的Corel Linux之上。当初Corel Linux的公司由于胦政上的困难,被迫l止了Corel Linux的开发,而Xandros适时的将Corel Linux部门CQ于2002q?0月推出全新的Xandros Desktop?<BR><BR>Xandros的卖点在于极其简单的安装和用,所以它的市场定位是那些没有MLinux使用l验的新手,或是习惯使用Windows的用戗Xandros的标准版和增强版都是商业软gQ分别售?40?99元。不q你仍然可以?A target=_new rel=nofollow>q里</A>下蝲到免费的公开发行版?<BR><BR>优点Q适合完全没有l验的新手,安装完以后就能立x入用,自带非常不错的工?<BR>~点Q商业Y?<BR>软g包管理系l:Xandros Networks (DEB) ?APT (DEB) Q可选,但不提供技术支持) <BR>免费下蝲Q?A target=_new rel=nofollow>公开发行?/A> <BR>官方主页Q?A target=_new rel=nofollow>http://www.xandros.com/</A> <BR><BR><STRONG>FreeBSD</STRONG> <BR><IMG alt=http://www.noobu.com/img/linux_distro/freebsd.png src="http://www.noobu.com/img/linux_distro/freebsd.png"> <BR><BR>首先要强调的是:<STRONG>FreeBSD不是一个LinuxpȝQ?/STRONG> 可是Qؓ什么笔者要介绍FreeBSD呢?因ؓFreeBSD的用户也相当多,其许多特性都与Linux相类伹{事实上QLinux和BSDQBerkeley Software DistributionQ均是UNIX的演化分支。ƈ且,Linux中相当多的特性和功能Q比如用于配|DNS的Bind软gQ都是取自于BSD的。而FreeBSD便是BSD家族中最出名Q用h量最多的一个发行版。MEZOC之前所采用的便是FreeBSDpȝ?<BR><BR>FreeBSD建立?993q_拥有相当长的历史。FreeBSD拥有两个分支Qstable和current。顾名思义Qstable是稳定版Q而current则是d了新技术的试版。另外,FreeBSD会不定期的发布新的版本,UCؓRELEASEQstable和current均有自己的RELEASE版本。比?.11-RELEASE?.3-RELEASEQ请注意Q这q不代表后者比前者的版本新。这仅仅代表前者(数字的版本Q是stable版本Q后者(数字大的版本Q是current版本?<BR><BR>FreeBSD除了作ؓ服务器系l外Q也适合桌面用户。不q,考虑到Y件方面的兼容性,一般用户选择FreeBSD作ؓ桌面pȝ不是很明智。作为服务器而言QFreeBSD是相当优U的。曾l有q,同样的服务器g配置Q运行同L一个vBulletin论坛QFreeBSD所用的资源要比Linux。这也是Z么许多空间商极力推崇FreeBSD的原因?) <BR><BR>优点Q速度快,非常E_Q优U的用手册,Portspȝ <BR>~点Q比起Linux而言对硬件的支持较差Q对于桌面系l而言软g的兼Ҏ是个问?<BR>软g包管理系l:Ports (TBZ) <BR>免费下蝲Q是 <BR>官方主页Q?A target=_new rel=nofollow>http://www.freebsd.org/</A> <BR><BR>以上介绍了目前较为流行的各Linux发行版本Q希望对大家有所帮助。同ӞW者也希望来多的朋友投入到Linux的大家庭中!\^O^/ <img src ="http://www.tkk7.com/faintbear/aggbug/31868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/faintbear/" target="_blank">力力力</a> 2006-02-21 22:13 <a href="http://www.tkk7.com/faintbear/archive/2006/02/21/31868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RISC和CISC http://www.tkk7.com/faintbear/archive/2006/02/20/31698.html力力力力力力Mon, 20 Feb 2006 12:46:00 GMThttp://www.tkk7.com/faintbear/archive/2006/02/20/31698.htmlhttp://www.tkk7.com/faintbear/comments/31698.htmlhttp://www.tkk7.com/faintbear/archive/2006/02/20/31698.html#Feedback3http://www.tkk7.com/faintbear/comments/commentRss/31698.htmlhttp://www.tkk7.com/faintbear/services/trackbacks/31698.htmlRISC和CISC 

  CPU从指令集的特点上可以分ؓ两类QCISC和RISC。我们所熟悉?nbsp;Intel pdCPU是 CISC ?nbsp;CPU 的典型代表? 那么QRISC 又是什么呢QRISC是英文Reduced Instruction Set Computer的羃写,汉语意思ؓ"_指opȝ计算? "。相对应的CISC是"复杂指opȝ计算?的意思?nbsp;

  随着大规模集成电路技术的发展Q计机的硬件成本不断下降,软g成本不断提高Q得指令系l增加了更多更复杂的指oQ以提高操作pȝ的效率? 另外Q同一pd的新型机对其指opȝ只能扩充而不能减L型机的Q意一条,以达到程序兼宏V这样一来,指opȝ来复杂,有的计算机指令甚臌到数? 条。h们就U这U计机为CISCQComplex Instruction Set ComputerQ。如IBM公司的大、中型计机QIntel? 司的8086?0286?0386微处理器{?nbsp;

  日益庞大的指令系l不仅计算机研制周期变长,而且q有难以调试、难以维护等一些自w无法克服的~点?nbsp;

后来Z发现机器执行的指令中85Q左右的都是单指令,复杂指o甚少Q因此开始研制精指opȝ计算?RISC)。于是RISC技术在高端? 务器和工作站上更是得Cq泛的应用。Intel的Pentium问世以来(92q末)Q融合了RISC技术,也逐步渗透到了中工作站和服务器市场?nbsp;
   
q种U因素计算机指令生了“简单指令”和“复杂指令”之分?0q代以前的计机均用传统的CISC指ol构Q即完全采用复杂指o来支持高U语a、应用程序和操作pȝ。这UPC不但成本高且效率较低Q速度受限?nbsp;



  目前QRISC和CISC各有优势Q而且界限q不那么明显了。现代的CPU往往采用CISC的外_内部加入了RISC的特性。就q? Intel最新的Pentium II{CISC芯片也具有了明显的RISC特征。另外,长指o集CPU׃融合了RISC和CISC的优势,成ؓ未来 的CPU发展方向之一?/font>

力力力 2006-02-20 20:46 发表评论
]]>
վ֩ģ壺 ɫ͵͵Ů˵| Ů18ëƬƵ| wwwѸƵ| ŮƵһ| þùƷۺ| ĻƷѾþ| ޻ɫվ| Av뾫Ʒ | ҹ޹ϼ| ˼˼99re66߾Ʒѹۿ| ޾ƷƵ| 99ƵѹۿƵ | þAVӰ | ޹Ƶһ| ˺ݺۺϾþ޸| Ƭ߹ۿ| ޾ƷƷ߹ۿ| ߿ƬѲ˳Ƶ| 99þó˹Ʒ| | һһ| www.һ| ŮëƬѲ| Թ24 | þ޹˾Ʒ| ĻƵ| һ234 | ƷƵ| ŮëƬƵ| 91Ƶѹۿ| Ʒþþþþ| ޾Ʒٸ30P| ɫavɫ߹| ۺɫ¶| ƷƵһ| 鶹˾þþƷ| һѵӰ| ˾þþƷС˵| | ޲Ƶ߹ۿ| þ|