﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Look into it ~-随笔分类-计算机基础科学</title><link>http://www.blogjava.net/lukewange-hit1983/category/35923.html</link><description>present</description><language>zh-cn</language><lastBuildDate>Thu, 13 Nov 2008 23:48:02 GMT</lastBuildDate><pubDate>Thu, 13 Nov 2008 23:48:02 GMT</pubDate><ttl>60</ttl><item><title>linux设备模型</title><link>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240185.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 12 Nov 2008 15:14:00 GMT</pubDate><guid>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240185.html</guid><wfw:comment>http://www.blogjava.net/lukewange-hit1983/comments/240185.html</wfw:comment><comments>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240185.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lukewange-hit1983/comments/commentRss/240185.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lukewange-hit1983/services/trackbacks/240185.html</trackback:ping><description><![CDATA[Linux
2.6内核的一个重要特色是提供了统一的内核设备模型。随着技术的不断进步，系统的拓扑结构越来越复杂，对智能电源管理、热插拔以及plug and
play的支持要求也越来越高，2.4内核已经难以满足这些需求。为适应这种形势的需要，2.6内核开发了全新的设备模型。<br />
１． Sysfs文件系统<br />
Sysfs文件系统是一个类似于proc文件系统的特殊文件系统，用于将系统中的设备组织成层次结构，并向用户模式程序提供详细的内核数据结构信息。其顶层目录主要有：<br />
Block目录：包含所有的块设备<br />
Devices目录：包含系统所有的设备，并根据设备挂接的总线类型组织成层次结构<br />
Bus目录：包含系统中所有的总线类型<br />
Drivers目录：包括内核中所有已注册的设备驱动程序<br />
Class目录：系统中的设备类型（如网卡设备，声卡设备等）<br />
２． 内核对象机制关键数据结构<br />
2.1  kobject内核对象<br />
Kobject 是Linux 2.6引入的新的设备管理机制，在内核中由struct
kobject表示。通过这个数据结构使所有设备在底层都具有统一的接口，kobject提供基本的对象管理，是构成Linux
2.6设备模型的核心结构，它与sysfs文件系统紧密关联，每个在内核中注册的kobject对象都对应于sysfs文件系统中的一个目录。<br />
Kobject结构定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;{<br />
</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;k_name;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向设备名称的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;name[KOBJ_NAME_LEN];&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;设备名称</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kref&nbsp;kref;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;对象引用计数</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;entry;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;挂接到所在kset中去的单元</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;parent;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向父对象的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kset;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所属kset的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobj_type&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ktype;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向其对象类型描述符的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;dentry&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dentry;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;sysfs文件系统中与该对象对应的文件节点路径指针</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">};</span></div>
<br />
其中的kref域表示该对象引用的计数，内核通过kref实现对象引用计数管理，内核提供两个函数kobject_get()、kobject_put()分别用于增加和减少引用计数，当引用计数为0时，所有该对象使用的资源将被释放。<br />
Ktype
域是一个指向kobj_type结构的指针，表示该对象的类型。Kobj_type数据结构包含三个域：一个release方法用于释放kobject占
用的资源；一个sysfs_ops指针指向sysfs操作表和一个sysfs文件系统缺省属性列表。Sysfs操作表包括两个函数store()和
show()。当用户态读取属性时，show()函数被调用，该函数编码指定属性值存入buffer中返回给用户态；而store()函数用于存储用户态
传入的属性值。<br />
2.2　kset内核对象集合<br />
Kobject通常通过kset组织成层次化的结构，kset是具有相同类型的kobject的集合，在内核中用kset数据结构表示，定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset&nbsp;{<br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;subsys;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所在的subsystem的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobj_type&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;ktype;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向该kset对象类型描述符的指针</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;list;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;用于连接该kset中所有kobject的链表头</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;kobj;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;嵌入的kobject</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset_hotplug_ops&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;hotplug_ops;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向热插拔操作表的指针</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">};</span></div>
<br />
包 含在kset中的所有kobject被组织成一个双向循环链表，list域正是该链表的头。Ktype域指向一个kobj_type结构，被该
kset中的所有kobject共享，表示这些对象的类型。Kset数据结构还内嵌了一个kobject对象（由kobj域表示），所有属于这个kset
的kobject对象的parent域均指向这个内嵌的对象。此外，kset还依赖于kobj维护引用计数：kset的引用计数实际上就是内嵌的
kobject对象的引用计数。<br />
2.3  subsystem内核对象子系统<br />
Subsystem是一系列kset的集合，描述系统中某一
类设备子系统，如block_subsys表示所有的块设备，对应于sysfs文件系统中的block目录。类似的，devices_subsys对应于
sysfs中的devices目录，描述系统中所有的设备。Subsystem由struct subsystem数据结构描述，定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;{<br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset&nbsp;kset;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;内嵌的kset对象</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;rw_semaphore&nbsp;rwsem;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;互斥访问信号量</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">};</span></div>
<br />
每 个kset必须属于某个subsystem，通过设置kset结构中的subsys域指向指定的subsystem可以将一个kset加入到该
subsystem。所有挂接到同一subsystem的kset共享同一个rwsem信号量，用于同步访问kset中的链表。<br />
<br />
３． 内核对象机制主要相关函数<br />
针对内核对象不同层次的数据结构，linux 2.6内核定义了一系列操作函数，定义于lib/kobject.c文件中。<br />
3.1　kobject相关函数<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_init(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;kobject初始化函数。设置kobject引用计数为1，entry域指向自身，其所属kset引用计数加１</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;kobject_set_name(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">kobj,&nbsp;</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">format,&nbsp;<img src="http://www.blogjava.net/Images/dot.gif"  alt="" />)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;设置指定kobject的名称。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_cleanup(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj);<br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_release(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kref&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">kref)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;kobject清除函数。当其引用计数为０时，释放对象占用的资源。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">kobject_get(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;将kobj&nbsp;对象的引用计数加1，同时返回该对象的指针。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_put(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;将kobj对象的引用计数减1，如果引用计数降为0，则调用kobject_release()释放该kobject对象。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;kobject_add(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;将kobj对象加入Linux设备层次。挂接该kobject对象到kset的list链中，增加父目录各级kobject的引用计数，在其parent指向的目录下创建文件节点，并启动该类型内核对象的hotplug函数。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;kobject_register(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;kobject注册函数。通过调用kobject_init()初始化kobj，再调用kobject_add()完成该内核对象的注册。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_del(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;从Linux设备层次(hierarchy)中删除kobj对象。</span><span style="color: #008000;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;kobject_unregister(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;kobj)；</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;kobject注销函数。与kobject_register()相反，它首先调用kobject_del从设备层次中删除该对象，再调用kobject_put()减少该对象的引用计数，如果引用计数降为0，则释放该kobject对象。</span></div>
<br />
3.2  kset相关函数<br />
与kobject
相似，kset_init()完成指定kset的初始化，kset_get()和kset_put()分别增加和减少kset对象的引用计数。
Kset_add()和kset_del()函数分别实现将指定keset对象加入设备层次和从其中删除；kset_register()函数完成
kset的注册而kset_unregister()函数则完成kset的注销。<br />
3.3  subsystem相关函数<br />
subsystem有一组完成类似的函数，分别是：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;subsystem_init(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys);<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;subsystem_register(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys);<br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;subsystem_unregister(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys);<br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys_get(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys)<br />
</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;subsys_put(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">subsys);</span></div>
<br />
４． 设备模型组件<br />
在上述内核对象机制的基础上，Linux的设备模型建立在几个关键组件的基础上，下面我们详细阐述这些组件。<br />
4.1 devices<br />
系统中的任一设备在设备模型中都由一个device对象描述，其对应的数据结构struct device定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;{<br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;g_list;<br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;node;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;bus_list;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;driver_list;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;children;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">parent;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;kobj;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;bus_id[BUS_ID_SIZE];<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;bus_type&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">bus;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device_driver&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">driver;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">driver_data;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;Several&nbsp;fields&nbsp;omitted&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
};</span></div>
<br />
g_list
将该device对象挂接到全局设备链表中，所有的device对象都包含在devices_subsys中，并组织成层次结构。Node域将该对象挂接
到其兄弟对象的链表中，而bus_list则用于将连接到相同总线上的设备组织成链表，driver_list则将同一驱动程序管理的所有设备组织为链
表。此外，children域指向该device对象子对象链表头，parent域则指向父对象。Device对象还内嵌一个kobject对象，用于引
用计数管理并通过它实现设备层次结构。Driver域指向管理该设备的驱动程序对象，而driver_data则是提供给驱动程序的数据。Bus域描述设
备所连接的总线类型。<br />
内核提供了相应的函数用于操作device对象。其中Device_register()函数将一个新的device对象插
入设备模型，并自动在/sys/devices下创建一个对应的目录。Device_unregister()完成相反的操作，注销设备对象。
Get_device()和put_device()分别增加与减少设备对象的引用计数。通常device结构不单独使用，而是包含在更大的结构中作为一
个子结构使用，比如描述PCI设备的struct pci_dev，其中的dev域就是一个device对象。<br />
4.2  drivers<br />
系统中的每个驱动程序由一个device_driver对象描述，对应的数据结构定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device_driver&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">name;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;设备驱动程序的名称</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;bus_type&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">bus;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;该驱动所管理的设备挂接的总线类型</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kobject&nbsp;kobj;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;内嵌kobject对象</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;list_head&nbsp;devices;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;该驱动所管理的设备链表头</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">probe)(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">dev);&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;指向设备探测函数，用于探测设备是否可以被该驱动程序管理</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">remove)(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">dev);&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;用于删除设备的函数</span><span style="color: #008000;"><br />
/*</span><span style="color: #008000;">&nbsp;some&nbsp;fields&nbsp;omitted</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
}；</span></div>
<br />
与device 结构类似，device_driver对象依靠内嵌的kobject对象实现引用计数管理和层次结构组织。内核提供类似的函数用于操作
device_driver对象，如get_driver()增加引用计数，driver_register()用于向设备模型插入新的driver对
象，同时在sysfs文件系统中创建对应的目录。Device_driver()结构还包括几个函数，用于处理热拔插、即插即用和电源管理事件。<br />
4.3&nbsp;&nbsp;  buses<br />
系统中总线由struct bus_type描述，定义为：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;bus_type&nbsp;{<br />
</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;name;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;总线类型的名称</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;subsystem&nbsp;subsys;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;与该总线相关的subsystem</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset&nbsp;drivers;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所有与该总线相关的驱动程序集合</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;kset&nbsp;devices;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所有挂接在该总线上的设备集合</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;bus_attribute&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;bus_attrs;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;总线属性</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device_attribute&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dev_attrs;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;设备属性</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;driver_attribute&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;drv_attrs;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;驱动程序属性</span><span style="color: #008000;"><br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">match)(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dev,&nbsp;</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device_driver&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;drv);<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">hotplug)&nbsp;(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">dev,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">**</span><span style="color: #000000;">envp,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;num_envp,&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">buffer,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;buffer_size);<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">suspend)(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dev,&nbsp;u32&nbsp;state);<br />
</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">*</span><span style="color: #000000;">resume)(</span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;device&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;dev);<br />
}；</span></div>
<br />
每 个bus_type对象都内嵌一个subsystem对象，bus_subsys对象管理系统中所有总线类型的subsystem对象。每个
bus_type对象都对应/sys/bus目录下的一个子目录，如PCI总线类型对应于/sys/bus/pci。在每个这样的目录下都存在两个子目
录：devices和drivers（分别对应于bus_type结构中的devices和drivers域）。其中devices子目录描述连接在该总
线上的所有设备，而drivers目录则描述与该总线关联的所有驱动程序。与device_driver对象类似，bus_type结构还包含几个函数
（match()、hotplug()等）处理相应的热插拔、即插即拔和电源管理事件。<br />
4.4  classes<br />
系统中的设备类由 struct
class描述，表示某一类设备。所有的class对象都属于class_subsys子系统，对应于sysfs文件系统中的/sys/class目录。
每个class对象包括一个class_device链表，每个class_device对象表示一个逻辑设备，并通过struct
class_device中的dev域（一个指向struct
device的指针）关联一个物理设备。这样，一个逻辑设备总是对应于一个物理设备，但是一个物理设备却可能对应于多个逻辑设备。此外，class结构中
还包括用于处理热插拔、即插即拔和电源管理事件的函数，这与device对象和driver对象相似。<br />
<img src ="http://www.blogjava.net/lukewange-hit1983/aggbug/240185.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lukewange-hit1983/" target="_blank">LukeW</a> 2008-11-12 23:14 <a href="http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240185.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>位运算</title><link>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240082.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 12 Nov 2008 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240082.html</guid><wfw:comment>http://www.blogjava.net/lukewange-hit1983/comments/240082.html</wfw:comment><comments>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lukewange-hit1983/comments/commentRss/240082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lukewange-hit1983/services/trackbacks/240082.html</trackback:ping><description><![CDATA[<strong>C中的位运算</strong><br />
能够运用到任何整形的数据类型上(包括char, int), 无论有没有short, long, unsigned这样的限定词.<br />
<br />
<br />
位运算的应用<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;交换指针变量x,y所指向的存储位置处存放的值<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;优势是不需要第三个位置来临时存储另一个值<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;但是这个方法并没有明显的性能优势,只是一个智力上的消遣</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;inplace_swap(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y)<br />
{<br />
&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br />
&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br />
&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x&nbsp;</span><span style="color: rgb(0, 0, 0);">^</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">y;<br />
}<br />
</span></div>
<br />
<strong>位运算常见用法:</strong><br />
实现掩码运算<br />
<br />
<br />
<br />
-----------------------------------<br />
<strong>Java中的位运算</strong><br />
<br />
<br />
<img src ="http://www.blogjava.net/lukewange-hit1983/aggbug/240082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lukewange-hit1983/" target="_blank">LukeW</a> 2008-11-12 13:53 <a href="http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>大端小端 -- 各系统及机器的信息表示</title><link>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240053.html</link><dc:creator>LukeW</dc:creator><author>LukeW</author><pubDate>Wed, 12 Nov 2008 03:58:00 GMT</pubDate><guid>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240053.html</guid><wfw:comment>http://www.blogjava.net/lukewange-hit1983/comments/240053.html</wfw:comment><comments>http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240053.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lukewange-hit1983/comments/commentRss/240053.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lukewange-hit1983/services/trackbacks/240053.html</trackback:ping><description><![CDATA[因为现行的计算机都是以八位一个字节为存储单位,那么一个16位的整数,也就是C语言中的short,在内存中可能有两种存储顺序big- <br />
<br />
endian和litte-endian.考虑一个short整数0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可<br />
<br />
能有如下两种情况:<br />
大端字节(Big-endian):<br />
<br />
short变量地址<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1001<br />
___________________________________<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x31&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x32<br />
|________________ | ________________<br />
高位字节在低位字节的前面,也就是高位在内存地址低的一端.可以这样记住(大端-&gt;高位-&gt;在前-&gt;正常的逻辑顺序)<br />
&nbsp;<br />
小端字节(little-endian):<br />
<br />
short变量地址<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x1001<br />
_____________________________________<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br />
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x32&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0x31<br />
|________________ | __________________<br />
低位字节在高位字节的前面,也就是低位在内存地址低的一端.可以这样记住(小端-&gt;低位-&gt;在前-&gt;与正常逻辑顺序相反)<br />
&nbsp;<br />
可以做个实验<br />
在windows上下如下程序<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">assert.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">&nbsp;test;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;fp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0x3132</span><span style="color: rgb(0, 0, 0);">;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">(31ASIIC码的&#8217;1&#8217;,32ASIIC码的&#8217;2&#8217;)</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;((fp&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;fopen&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c:</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">test.txt</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">wb</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">))&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NULL)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">test,&nbsp;</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">),&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);<br />
}</span></div>
<br />
&nbsp;&nbsp;&nbsp; 然后在C盘下打开test.txt文件,可以看见内容是21,而test等于0x3132,可以明显的看出来x86的字节顺序是低位在前.如果我们<br />
把这段同样的代码放到(big-endian)的机器上执行,那么打出来的文件就是12.这在本机中使用是没有问题的.但当你把这个文件从一<br />
个big- endian机器复制到一个little-endian机器上时就出现问题了.<br />
<br />
&nbsp;&nbsp;&nbsp; 如上述例子,我们在big-endian的机器上创建了这个test文件,把其复制到little-endian的机器上再用fread读到一个 short里<br />
面,我们得到的就不再是0x3132而是0x3231了,这样读到的数据就是错误的,所以在两个字节顺序不一样的机器上传输数据时需要特别<br />
小心字节顺序,理解了字节顺序在可以帮助我们写出移植行更高的代码.<br />
<br />
正因为有字节顺序的差别,所以在网络传输的时候定义了所有字节顺序相关的数据都使用big-endian,BSD的代码中定义了四个宏来处<br />
理:<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;ntohs(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">网络字节顺序到主机字节顺序&nbsp;n代表net,&nbsp;h代表host,&nbsp;s代表short</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;htons(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">主机字节顺序到网络字节顺序&nbsp;n代表net,&nbsp;h代表host,&nbsp;s代表short</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;ntohl(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">网络字节顺序到主机字节顺序&nbsp;n代表net,&nbsp;h代表host,&nbsp;s代表&nbsp;long</span><span style="color: rgb(0, 0, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;htonl(n)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">主机字节顺序到网络字节顺序&nbsp;n代表net,&nbsp;h代表host,&nbsp;s代表&nbsp;long</span></div>
<br />
举例说明下这其中一个宏的实现:<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;sw16(x)&nbsp;"</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(&nbsp;</span><span style="color: rgb(0, 0, 0);">"<br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0x00ffU</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"<br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0xff00U</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;))</span></div>
<br />
这里实现的是一个交换两个字节顺序.其他几个宏类似.<br />
<br />
我们改写一下上面的程序<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
#include&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">assert.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
<br />
</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;sw16(x)&nbsp;"</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(&nbsp;</span><span style="color: rgb(0, 0, 0);">"<br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0x00ffU</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"<br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(((</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)(x)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 0, 0);">0xff00U</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&gt;&gt;</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">8</span><span style="color: rgb(0, 0, 0);">)&nbsp;))<br />
<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;因为x86下面是低位在前,需要交换一下变成网络字节顺序</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);">&nbsp;htons(x)&nbsp;sw16(x)</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;main(&nbsp;</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">&nbsp;test;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">&nbsp;fp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;htons(</span><span style="color: rgb(0, 0, 0);">0x3132</span><span style="color: rgb(0, 0, 0);">);&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">(31ASIIC码的&#8217;1&#8217;,32ASIIC码的&#8217;2&#8217;)</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;((fp&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;fopen&nbsp;(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">c:</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">test.txt</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">wb</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">))&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;NULL)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert(</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fwrite(</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">test,&nbsp;</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">),&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">,&nbsp;fp);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);<br />
}</span></div>
<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; 如果在高字节在前的机器上,由于与网络字节顺序一致,所以我们什么都不干就可以了,只需要把#define htons(x) sw16(x)宏替<br />
<br />
换为 #define htons(x) (x).<br />
&nbsp;&nbsp;&nbsp; 一开始我在理解这个问题时,总在想为什么其他数据不用交换字节顺序?比如说我们write一块buffer到文件,最后终于想明白了,<br />
<br />
因为都是unsigned char类型一个字节一个字节的写进去,这个顺序是固定的,不存在字节顺序的问题.<br />
<p><strong><font color="#0000ff">【用函数判断系统是Big Endian还是Little Endian】</font></strong><br />
</p>
<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);">&nbsp;IsBig_Endian()<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">如果字节序为big-endian，返回true;<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">反之为&nbsp;&nbsp;&nbsp;little-endian，返回false</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">{<br />
&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="color: rgb(0, 0, 255);">short</span><span style="color: rgb(0, 0, 0);">&nbsp;test&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0x1122</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">(&nbsp;(unsigned&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">test&nbsp;)&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0x11</span><span style="color: rgb(0, 0, 0);">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;TRUE;<br />
</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">&nbsp;FALSE;<br />
<br />
}</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">IsBig_Endian()<br />
</span></div>
<br />
<strong><font color="#0000ff">【打印程序对象的字节表示】</font></strong><font color="#0000ff"><br />
</font>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;可在不同平台与硬件架构的机器中测试运行这段代码,理解大端表示和小端表示的不同.<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;这段代码使用强制类型转换规避类型系统</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">#incluede&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;假设每个字节都是非负整数</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">typedef&nbsp;unsigned&nbsp;</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">byte_pointer;<br />
<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show_bytes(byte_pointer&nbsp;start,&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;len)<br />
{<br />
&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;len;&nbsp;i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)<br />
&nbsp;&nbsp;printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;%.2x</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;start[i]);<br />
&nbsp;printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show_int(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;x)<br />
{<br />
&nbsp;show_bytes((byte_pointer)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">x,&nbsp;</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">));<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show_float(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">&nbsp;x)<br />
{<br />
&nbsp;show_bytes((byte_pointer)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">x,&nbsp;</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">));<br />
}<br />
<br />
</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;在使用相同编码(如ASCII编码)的系统中,字符串字节表示得到的结果一般是相同的.所以文本数据比二进制数据具有更强的平台无关性</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show_string(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x)<br />
{<br />
&nbsp;show_bytes((byte_pointer)&nbsp;x,&nbsp;strlen(x));<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;show_pointer(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">x)<br />
{<br />
&nbsp;show_bytes((byte_pointer)&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">x,&nbsp;</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">));<br />
}<br />
<br />
</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">&nbsp;test_show_bytes(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;val)<br />
{<br />
&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;ival&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;val;<br />
&nbsp;</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">&nbsp;fval&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;(</span><span style="color: rgb(0, 0, 255);">float</span><span style="color: rgb(0, 0, 0);">)ival;<br />
&nbsp;</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pval&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">ival;<br />
&nbsp;<br />
&nbsp;show_int(ival);&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;各个机器因为大端表示和小端表示的不同,从而只是字节顺序不同</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;show_float(fval);&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;各个机器因为大端表示和小端表示的不同,从而只是字节顺序不同</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;show_pointer(pval);&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;指针值是与机器相关的(linux,sun使用4字节地址,&nbsp;而alpha使用八字节地址)</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">}</span></div>
<br />
---------------------------------------------<br />
对于如数值12345在int型和float型时的编码表示<br />
<img src ="http://www.blogjava.net/lukewange-hit1983/aggbug/240053.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lukewange-hit1983/" target="_blank">LukeW</a> 2008-11-12 11:58 <a href="http://www.blogjava.net/lukewange-hit1983/archive/2008/11/12/240053.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>