﻿<?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>IT博客-linux-文章分类-c语言</title><link>http://www.cnitblog.com/seedshopezhong/category/8619.html</link><description>driver</description><language>zh-cn</language><lastBuildDate>Thu, 29 Sep 2011 03:45:11 GMT</lastBuildDate><pubDate>Thu, 29 Sep 2011 03:45:11 GMT</pubDate><ttl>60</ttl><item><title>嵌入式调试printf与分配rintf</title><link>http://www.cnitblog.com/seedshopezhong/articles/64816.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Wed, 24 Mar 2010 16:22:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64816.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64816.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64816.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64816.html</trackback:ping><description><![CDATA[<span  style="color: rgb(51, 51, 51); font-family: Tahoma, SimSun, Verdana, Arial; font-size: 12px; line-height: 18px; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">除了人工的分析之外，最简单最直接的调试方法要算printf了。不过，我们这里推荐使用的并不是初学C语言时使用的函数int printf(const char *format, ...)，而是稍微复杂一点的fprintf()函数，因为它更方便我们之后重定向错误输出信息到指定的设备。fprintf()函数的原型如下：</div><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "></p><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">int fprintf(FILE *stream, const char *format, ...)</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">可以看到，它与printf()函数相比多出来了第一个参数FILE *stream，其意义是将打印的内容输出到文件流指针stream指向的流。所谓流，通常是指程序输入或输出的一个连续的字节序列，设备(例如鼠标、键盘、磁盘、屏幕、调制解调器和打印机)的输入和输出都是用流来处理的，在C语言中，所有的流均以文件的形式出现——不一定是物理磁盘文件，还可以是对应于某个输入／输出源的逻辑文件。C语言提供了5种标准的流，你的程序在任何时候都可以使用它们，并且不必打开或关闭它们。以下列出了这5种标准的流。<br>------------------------------------------------<br>&nbsp;&nbsp;&nbsp; 名称&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描&nbsp;述&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;例&nbsp;子<br>------------------------------------------------<br>&nbsp;&nbsp;&nbsp; stdin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标准输入&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>&nbsp;&nbsp;</span>键盘<br>&nbsp;&nbsp;&nbsp; stdout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标准输出&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;屏幕<br>&nbsp;&nbsp;&nbsp; stderr&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标准错误&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<span>&nbsp;&nbsp;</span>屏幕<br>&nbsp;&nbsp;&nbsp; stdprn&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标准打印机&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; LPT1端口<br>&nbsp;&nbsp;&nbsp; stdaux&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 标准串行设备&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;COM1端口<br>------------------------------------------------<br>&nbsp;&nbsp;&nbsp; 其中，stdprn和stdaux并不总是预先定义好的，因为LPT1和COM1端口在某些操作系统中是没有意义的，而stdin，stdout 和stderr总是预先定义好的。此外，stdin并不一定来自键盘，stdout也并不一定显示在屏幕上，它们都可以重定向到磁盘文件或其它设备上。我们在头文件stdio.h中可以找到stdin，stdout 和stderr的定义如下：</div><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "></p><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">/* Standard streams.&nbsp;*/</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">extern struct _IO_FILE *stdin;<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Standard input stream.&nbsp;*/</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">extern struct _IO_FILE *stdout;<span>&nbsp;&nbsp;&nbsp;&nbsp; /* Standard output stream.&nbsp;*/</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">extern struct _IO_FILE *stderr;<span>&nbsp;&nbsp;&nbsp;&nbsp; /* Standard error output stream.&nbsp;*/</span></div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">在使用fprintf()函数时，通常我们可以将第一个参数设为stdout或者stderr，打印出错调试信息的时候则推荐使用stderr而不是stdout，这是一种惯例，同时也由于内核在处理stdout和stderr时的优先级不一样，后者的优先级要高一些，因此有时候如果程序异常退出时，stderr能得到输出，而stdout就不行。</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">printf(...) 实际上相当于fprintf(stdout, ...)，这也是为什么我们不推荐使用它的原因。在输出调试信息的时候，我们推荐使用fprintf(stderr, &#8230;)，或者使用某个指定的文件流fprintf(some_stream, &#8230;)。</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span style="font-size: 10.5pt; ">那么具体如何在必要的时候重定向</span><span style="font-size: 10.5pt; ">fprintf()</span><span style="font-size: 10.5pt; ">中的调试信息呢？来看看下面的一些方法：</span></div><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; "><span style="font-size: 10.5pt; ">当调试信息的量比较大，需要一些时间或者其他辅助工具来搜索过滤时，仅仅利用显示屏幕来输出调试信息是不够的，这时我们经常将这些信息输出到所谓的日志文件(log)中，之后再仔细的分析log文件来发现问题。</span></div><div style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: -21pt; "><span style="font-size: 10.5pt; "><span style="font-size: 12pt; ">&#216;<span style="font: normal normal normal 7pt/normal 'Times New Roman'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>&nbsp;<strong><span style="font-size: 12pt; ">利用</span></strong><strong><span style="font-size: 12pt; ">Shell</span></strong><strong><span style="font-size: 12pt; ">的</span></strong><strong><span style="font-size: 12pt; ">I/O</span></strong><strong><span style="font-size: 12pt; ">重定向</span></strong></span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">简单的写log方法可以通过shell的I/O重定向机制来实现，比如下面的代码：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;#include &lt;stdio.h&gt;</span></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 2</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;int main()</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;{</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "This is a standard output info!\n");</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr, "This is a standard error output info!\n");</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp;}</span></div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">在默认条件下，编译运行的结果是打印信息都输出在屏幕上：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ gcc fprint.c -o fprint</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ ./fprint</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard error output info!</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">这是因为默认情况下，shell所打开的stdout和stderr设备都是显示屏幕。不过我们可以通过shell的重定向功能来将打印信息写到文件中去。比如：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ ./fprint &gt;output.log</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard error output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ cat output.log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard output info!</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">这样，我们把stdout的输出写到了文件output.log中，不过stderr的输出还是在屏幕上。如何重定向stderr呢？这需要用到shell定义的文件描述符。在shell下stdin, stdout, 和stderr的文件描述符分别是0, 1和2，我们可以用下面的方法重定向：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ ./fprint &gt;output.log 2&gt;error.log</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ cat output.log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ cat error.log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard error output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ ./fprint &gt;output.log 2&gt;&amp;1</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ cat output.log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard error output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard output info!</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">其中./fprint &gt;output.log 2&gt;error.log分别将stdout和stderr的输出写入到文件output.log和error.log中，而./fprint &gt;output.log 2&gt;&amp;1则表示将stderr的输出追加到stdout的文件output.log中（结果是output.log中既有stdout输出也有stderr输出）。</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">一些常用的shell I/O语法如下：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">cmd &gt; file &nbsp;把 stdout 重定向到 file 文件中<br>cmd &gt;&gt; file &nbsp;把 stdout 重定向到 file 文件中(追加)<br>cmd 1&gt; fiel &nbsp;把 stdout 重定向到 file 文件中<br>cmd &gt; file 2&gt;&amp;1 &nbsp;把 stdout 和 stderr 一起重定向到 file 文件中<br>cmd 2&gt; file &nbsp;把 stderr 重定向到 file 文件中<br>cmd 2&gt;&gt; file &nbsp;把 stderr 重定向到 file 文件中(追加)<br>cmd &gt;&gt; file 2&gt;&amp;1 &nbsp;把 stderr 和 stderr 一起重定向到 file 文件中(追加)</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">在平时的简单调试中，我们可以灵活利用这些方法来快速得到log文件。</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">&nbsp;</div><div style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 21pt; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: -21pt; "><span style="font-size: 12pt; ">&#216;<span style="font: normal normal normal 7pt/normal 'Times New Roman'; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>&nbsp;<strong><span style="font-size: 12pt; ">用</span></strong><strong><span style="font-size: 12pt; ">freopen()</span></strong><strong><span style="font-size: 12pt; ">进行重定向</span></strong></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">有时候我们要求在程序中能够控制标准流的重定向，这时可以利用标准C库函数freopen()。freopen()的函数原型如下：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">FILE *freopen(const char *filename, const char *mode, FILE *stream)</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">下面的代码用来测试用函数freopen()重定向stderr：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;#include &lt;stdio.h&gt;</span></p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 2</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;int main()</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;{</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (freopen("err.log", "w", stderr)==NULL)</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr, "error redirecting stderr\n");</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stdout, "This is a standard output info!\n");</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fprintf(stderr, "This is a standard error output info!\n");</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp;&nbsp; 9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(stderr);</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span>&nbsp;&nbsp;&nbsp; 11&nbsp;}</span></div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">在第5行我们用freopen()函数将stderr重定向到了&#8221;err.log&#8221;文件，这样得到的结果如下：</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><table cellspacing="0" cellpadding="0" width="100%" border="0" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(179, 179, 179); width: 726px; "><tbody><tr><td style="border-right-color: rgb(212, 208, 200); border-right-width: initial; border-right-style: initial; padding-right: 0cm; border-top-color: rgb(212, 208, 200); border-top-width: initial; border-top-style: initial; padding-left: 0cm; padding-bottom: 0cm; border-left-color: rgb(212, 208, 200); border-left-width: initial; border-left-style: initial; padding-top: 0cm; border-bottom-color: rgb(212, 208, 200); border-bottom-width: initial; border-bottom-style: initial; background-color: transparent; "><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ gcc print_log.c -o print_log</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ ./print_log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard output info!</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">$ cat err.log</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; text-indent: 21pt; ">This is a standard error output info!</div></td></tr></tbody></table><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; ">&nbsp;</p><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; overflow-x: hidden; overflow-y: hidden; "><span style="font-size: 10.5pt; ">可见第</span><span style="font-size: 10.5pt; ">8</span><span style="font-size: 10.5pt; ">行打印到</span><span style="font-size: 10.5pt; ">stderr</span><span style="font-size: 10.5pt; ">的信息被重定向到了</span><span style="font-size: 10.5pt; ">err.log</span><span style="font-size: 10.5pt; ">文件中，而第</span><span style="font-size: 10.5pt; ">7</span><span style="font-size: 10.5pt; ">行</span><span style="font-size: 10.5pt; ">stdout</span><span style="font-size: 10.5pt; ">的打印信息则还是输出到了屏幕上。</span></div></div></div></div></div></div></div></div></span>
<img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-25 00:22 <a href="http://www.cnitblog.com/seedshopezhong/articles/64816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是字节对齐，字节为什么要对齐</title><link>http://www.cnitblog.com/seedshopezhong/articles/64815.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Wed, 24 Mar 2010 15:02:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64815.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64815.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64815.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64815.html</trackback:ping><description><![CDATA[





<div><div>注:转载于网络</div><div>现代计算机中内存空间都是按照byte划分的，从理论上讲似乎对任何类型的变量的访问可以从任何地址开始，但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问，这就需要各种类型数据按照一定的规则在空间上排列，而不是顺序的一个接一个的排放，这就是对齐。</div><div>&nbsp;&nbsp; &nbsp; 对齐的作用和原因：各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况，但是最常见的是如果不按照适合其平台要求对数据存放进行对齐，会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始，如果一个int型（假设为32位系统）如果存放在偶地址开始的地方，那么一个读周期就可以读出这32bit，而如果存放在奇地址开始的地方，就需要2个读周期，并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。</div><div><br></div><div>二.字节对齐对程序的影响:</div><div>先让我们看几个例子吧(32bit,x86环境,gcc编译器):</div><div>设结构体如下定义：</div><div>struct A</div><div>{</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div><br></div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4Byte</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |---------|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | &nbsp; &nbsp; a &nbsp; &nbsp; |</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |----|----|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | b -| c -|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |---------|</div><div><br></div><div><br></div><div>struct B</div><div>{</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div><br></div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |--------|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |b &nbsp; &nbsp; &nbsp; &nbsp;|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |--------|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | &nbsp; &nbsp; a &nbsp; &nbsp;|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |--------|</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; | c &nbsp; &nbsp; &nbsp; |</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; |--------|&nbsp;</div><div><br></div><div>现在已知32位机器上各种数据类型的长度如下:</div><div>char:1 &nbsp; &nbsp; (有符号无符号同) &nbsp; &nbsp;</div><div>short:2 &nbsp; &nbsp; (有符号无符号同) &nbsp; &nbsp;</div><div>int:4 &nbsp; &nbsp; &nbsp; &nbsp; (有符号无符号同) &nbsp; &nbsp;</div><div>long:4 &nbsp; &nbsp; (有符号无符号同) &nbsp; &nbsp;</div><div>float:4 &nbsp; &nbsp; double:8</div><div>那么上面两个结构大小如何呢?</div><div>结果是:</div><div>sizeof(strcut A)值为8</div><div>sizeof(struct B)的值却是12</div><div><br></div><div>结构体A中包含了4字节长度的int一个，1字节长度的char一个和2字节长度的short型数据一个,B也一样;按理说A,B大小应该都是7字节。之所以出现上面的结果是因为编译器要对数据成员在空间上进行对齐。上面是按照编译器的默认设置进行对齐的结果,那么我们是不是可以改变编译器的这种默认对齐设置呢,当然可以.例如:</div><div><br></div><div>#pragma pack (2) /*指定按2字节对齐*/</div><div>struct B</div><div>{</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div>#pragma pack () /*取消指定对齐，恢复缺省对齐*/</div><div>sizeof(struct B)值是8。</div><div><br></div><div><br></div><div>修改对齐值为1：</div><div>#pragma pack (1) /*指定按1字节对齐*/</div><div>struct B</div><div>{</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div>#pragma pack () /*取消指定对齐，恢复缺省对齐*/</div><div>sizeof(struct B)值为7。</div><div><br></div><div>后面我们再讲解#pragma pack()的作用.</div><div><br></div><div>三.编译器是按照什么样的原则进行对齐的?</div><div><br></div><div>先让我们看四个重要的基本概念：</div><div>1.数据类型自身的对齐值：对于char型数据，其自身对齐值为1，对于short型为2，对于int,float,double类型，其自身对齐值为4，单位字节。</div><div>2.结构体的自身对齐值：其成员中自身对齐值最大的那个值。</div><div>3.指定对齐值：#pragma pack (value)时的指定对齐值value。</div><div>4.数据成员和结构体的有效对齐值：数据成员(数据类型)和数据结构的自身对齐值和指定对齐值中小的那个值。(数据成员对齐了数据结构自然也就对齐了)</div><div><br></div><div>有了这些值，我们就可以很方便的来讨论具体数据结构的成员和其自身的对齐方式。有效对齐值N是最终用来决定数据存放地址方式的值，最重要。有效对齐N，就是表示&#8220;对齐在N上&#8221;，也就是说该数据的"存放起始地址%N=0".而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放，结构体本身也要根据自身的有效对齐值圆整(就是结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍，结合下面例子理解)。这样就不难理解上面的几个例子的值了。</div><div><br></div><div>例子分析：</div><div>分析例子B；</div><div>struct B</div><div>{</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div>假设B从地址空间0x0000开始排放。该例子中没有定义指定对齐值，在笔者环境下，该值默认为4。第一个成员变量b的自身对齐值是1，比指定或者默认指定对齐值4小，所以其有效对齐值为1，所以其存放地址0x0000符合0x0000%1=0.第二个成员变量a，其自身对齐值为4，所以有效对齐值也为4，所以只能存放在起始地址为0x0004到0x0007这四个连续的字节空间中，复核0x0004%4=0,且紧靠第一个变量。第三个变量c,自身对齐值为 2，所以有效对齐值也是2，可以存放在0x0008到0x0009这两个字节空间中，符合0x0008%2=0。所以从0x0000到0x0009存放的都是B内容。再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b）所以就是4，所以结构体的有效对齐值也是4。根据结构体圆整的要求， 0x0009到0x0000=10字节，（10＋2）％4＝0。所以0x0000A到0x000B也为结构体B所占用。故B从0x0000到0x000B 共有12个字节,sizeof(struct B)=12;其实如果就这一个就来说它已将满足字节对齐了, 因为它的起始地址是0,因此肯定是对齐的,之所以在后面补充2个字节,是因为编译器为了实现结构数组的存取效率,试想如果我们定义了一个结构B的数组,那么第一个结构起始地址是0没有问题,但是第二个结构呢?按照数组的定义,数组中所有元素都是紧挨着的,如果我们不把结构的大小补充为4的整数倍,那么下一个结构的起始地址将是0x0000A,这显然不能满足结构的地址对齐了,因此我们要把结构补充成有效对齐大小的整数倍.其实诸如:对于char型数据，其自身对齐值为1，对于short型为2，对于int,float,double类型，其自身对齐值为4，这些已有类型的自身对齐值也是基于数组考虑的,只是因为这些类型的长度已知了,所以他们的自身对齐值也就已知了.</div><div>同理,分析上面例子C：</div><div>#pragma pack (2) /*指定按2字节对齐*/</div><div>struct C</div><div>{</div><div>&nbsp;&nbsp; &nbsp; char b;</div><div>&nbsp;&nbsp; &nbsp; int &nbsp; &nbsp;a;</div><div>&nbsp;&nbsp; &nbsp; short c;</div><div>};</div><div>#pragma pack () /*取消指定对齐，恢复缺省对齐*/</div><div>第一个变量b的自身对齐值为1，指定对齐值为2，所以，其有效对齐值为1，假设C从0x0000开始，那么b存放在0x0000，符合0x0000%1= 0;第二个变量，自身对齐值为4，指定对齐值为2，所以有效对齐值为2，所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续字节中，符合0x0002%2=0。第三个变量c的自身对齐值为2，所以有效对齐值为2，顺序存放</div><div>在0x0006、0x0007中，符合 0x0006%2=0。所以从0x0000到0x00007共八字节存放的是C的变量。又C的自身对齐值为4，所以C的有效对齐值为2。又8%2=0,C 只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8.</div><div><br></div><div>四.如何修改编译器的默认对齐值?</div><div>1.在VC IDE中，可以这样修改：[Project]|[Settings],c/c 选项卡Category的Code Generation选项的Struct Member Alignment中修改，默认是8字节。</div><div>2.在编码时，可以这样动态修改：#pragma pack .注意:是pragma而不是progma.</div><div><br></div><div>---------------------------------------------------------</div><div>&#183; 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。</div><div>&#183; 使用伪指令#pragma pack ()，取消自定义字节对齐方式。</div><div><br></div><div>---------------------------------------------------------</div><div>&#183; __attribute((aligned (n)))，让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n，则按照最大成员的长度来对齐。</div><div>&#183; __attribute__ ((packed))，取消结构在编译过程中的优化对齐，按照实际占用字节数进行对齐。</div><div><br></div><div><br></div><div>五.针对字节对齐,我们在编程中如何考虑?</div><div>&nbsp;&nbsp; &nbsp; 如果在编程的时候要考虑节约空间的话,那么我们只需要假定结构的首地址是0,然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变量按照类型大小从小到大声明,尽量减少中间的填补空间.还有一种就是为了以空间换取时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做法是显式的插入reserved成员：</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;struct A{</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char a;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;char reserved[3];//使用空间换时间</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int b;</div><div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div><br></div><div>reserved成员对我们的程序没有什么意义,它只是起到填补空间以达到字节对齐的目的,当然即使不加这个成员通常编译器也会给我们自动填补对齐,我们自己加上它只是起到显式的提醒作用.</div><div><br></div><div><br></div><div>六.字节对齐可能带来的隐患:</div><div>&nbsp;&nbsp; &nbsp; 代码中关于对齐的隐患，很多是隐式的。比如在强制类型转换的时候。例如：</div><div>unsigned int i = 0x12345678;</div><div>unsigned char *p=NULL;</div><div>unsigned short *p1=NULL;</div><div><br></div><div>p=&amp;i;</div><div>*p=0x00;</div><div>p1=(unsigned short *)(p 1);</div><div>*p1=0x0000;</div><div>最后两句代码，从奇数边界去访问unsigned short型变量，显然不符合对齐的规定。在x86上，类似的操作只会影响效率，但是在MIPS或者sparc上，可能就是一个error,因为它们要求必须字节对齐.</div><div><br></div><div>七.如何查找与字节对齐方面的问题:</div><div>如果出现对齐或者赋值问题首先查看</div><div>1. 编译器的big little端设置</div><div>2. 看这种体系本身是否支持非对齐访问</div><div>3. 如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。</div><div><br></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 36pt "><span style="COLOR:red"><span style="FONT-SIZE: 18pt ">补充：汇编和ADS的对齐</span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 36pt "><span style="COLOR:red"><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">三.在ADS编译器中的实例.&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">&nbsp;#pragma	pack(push)
//保存对齐状态&nbsp;&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">//设定为4字节对齐&nbsp;&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">__align(4)
struct	test {&nbsp;&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><span class="Apple-tab-span" style="white-space:pre">	</span>char	m1;&nbsp;&nbsp;	</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><span class="Apple-tab-span" style="white-space:pre">	</span>double	m4;
&nbsp;	</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><span class="Apple-tab-span" style="white-space:pre">	</span>int	m3;&nbsp;&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">}; 　　&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">以上结构的大小为16，下面分析其存储情况，首先为m1分配空间，其偏移量为0，满足我们自己设定的对齐方式（4字节对</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">&nbsp;齐），m1占用1个字节。接着开始为m4分配空间，这时其偏移量为1，需要补足3个字节，这样使偏移量满足为n=4的倍数</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">&nbsp;（因为sizeof(double)大于n）,m4占用8个字节。接着为m3分配空间，这时其偏移量为12，满足为4的倍数，m3占用4个字</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">&nbsp;节。这时已经为所有成员变量分配了空间，共分配了16个字节，满足为n的倍数。如果把上面的	__align(4)	struct	test 改为</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">&nbsp;&nbsp;__align(16)	struct	test	，那么我们可以得到结构的大小为24。&nbsp;&nbsp;</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt "><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="FONT-SIZE: 18pt ">========= 编译器不同在存放结构体方式可能不同，因此对齐也会有不同</span></span></span></font></div><div><font face="arial, 宋体, serif" size="6"><span style="font-size: 24px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><br></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red">汇编对齐方式</span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><br></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">.align n 它的含义就是使得下面的代码按一定规则对齐，.align n 指令的对齐值有两种方案，n 或 2^n ，各种平台最初的汇</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">编器一般都不是gas，采取方案1或2的都很多，gas的目标是取代原来的汇编器，必然要保持和原来汇编器的兼容，因此在</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">gas中如何解释 .align指令会显得有些混乱，原因在于保持兼容。arm-linu是按照2^n的方案对齐的，需要说明的是这个对齐</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">和ld-script里的对齐不同，不是一会事。.align n
它的含义就是使得下面的代码按一定规则对齐，.align n 指令的对齐值有两</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">种方案，n 或 2^n ，各种平台最初的汇编器一般都不是gas，采取方案1或2的都很多，gas的目标是取代原来的汇编器，必</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">然要保持和原来汇编器的兼容，因此在gas中如何解释 .align指令会显得有些混乱，原因在于保持兼容。arm-linu是按照2^n</span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt "><br></span></span></span></span></span></font></div><div><font face="arial, 宋体, serif" size="3"><span style="font-size: 12px; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px;"><span style="FONT-SIZE: 18pt "><span style="COLOR:red"><span style="color: rgb(42, 42, 42); font-family: Tahoma, Helvetica, Arial, sans-serif; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: 14px; line-height: 25px; "><span style="FONT-SIZE: 18pt ">的方案对齐的，需要说明的是这个对齐和ld-script里的对齐不同，不是一会事。</span></span></span></span></span></font></div></div><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-24 23:02 <a href="http://www.cnitblog.com/seedshopezhong/articles/64815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>#与##语法</title><link>http://www.cnitblog.com/seedshopezhong/articles/64783.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Mon, 22 Mar 2010 14:22:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64783.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64783.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64783.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64783.html</trackback:ping><description><![CDATA[<span  style="font-family: verdana, sans-serif; font-size: 14px; line-height: 21px; ">宏定义里面有个##和字符串的关系<br>#include&nbsp;&lt;stdio.h&gt;&nbsp;<br>#define&nbsp;CAT(x,&nbsp;y)&nbsp;&nbsp;x##y&nbsp;&nbsp;&nbsp;&nbsp;//将x,y连接起来形成"xy"的形式&nbsp;<br>void&nbsp;main()&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;printf("%s",&nbsp;CAT("hello",&nbsp;"&nbsp;world"));&nbsp;<br>}&nbsp;<br>出现在宏定义中的＃＃是用来告诉编译器，将两个字符串系在一起。&nbsp;-&nbsp;<br><br>一个#代表将一个宏参数转变为一个string&nbsp;，例如&nbsp;<br>#include&lt;stdio.h&gt;&nbsp;<br>#define&nbsp;stringer(&nbsp;x&nbsp;)&nbsp;printf(&nbsp;#x&nbsp;"\n"&nbsp;)&nbsp;<br>void&nbsp;main()&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;stringer(&nbsp;haha&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;<br>}&nbsp;<br><br>这里的这个#将x转化为一个string&nbsp;，这个宏就是要将x传进来的东西打印到屏幕上&nbsp;，只有一个是将其变为字符串&nbsp;<br>#include&nbsp;&lt;stdio.h&gt;&nbsp;<br>#define&nbsp;TRACE(x)&nbsp;printf(#x"&nbsp;is:&nbsp;%d\n",&nbsp;x)&nbsp;<br>void&nbsp;main(void)&nbsp;<br>{&nbsp;<br>int&nbsp;i=3;&nbsp;<br>TRACE(i);&nbsp;<br>}</span><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-22 22:22 <a href="http://www.cnitblog.com/seedshopezhong/articles/64783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Volatile的用法</title><link>http://www.cnitblog.com/seedshopezhong/articles/64687.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Tue, 16 Mar 2010 15:25:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64687.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64687.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64687.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64687.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64687.html</trackback:ping><description><![CDATA[<span  style="font-family: georgia, Verdana, Helvetica, Arial; font-size: 12px; line-height: 18px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "><p class="MsoNormal" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; "><span style="font-family: 宋体; ">由于访问寄存器的速度要快过</span><font face="宋体"><span lang="EN-US">RAM</span><span style="font-family: 宋体; ">，所以编译器一般都会作减少存取外部</span><span lang="EN-US">RAM</span><span style="font-family: 宋体; ">的优化。比如：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>static int i=0;&nbsp;<br>int main(void)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; while (1)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dosomething();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>}&nbsp;<br>/* Interrupt service routine. */&nbsp;<br>void ISR_2(void)&nbsp;<br>{&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i=1;&nbsp;<br>}&nbsp;<br></span><span style="font-family: 宋体; ">程序的本意是希望</span><span lang="EN-US">ISR_2</span><span style="font-family: 宋体; ">中断产生时，在</span><span lang="EN-US">main</span><span style="font-family: 宋体; ">当中调用</span><span lang="EN-US">dosomething</span><span style="font-family: 宋体; ">函数，但是，由于编译器判断在</span><span lang="EN-US">main</span><span style="font-family: 宋体; ">函数里面没有修改过</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">，因此可能只执行一次对从</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">到某寄存器的读操作，然后每次</span><span lang="EN-US">if</span><span style="font-family: 宋体; ">判断都只使用这个寄存器里面的</span><span lang="EN-US">&#8220;i</span><span style="font-family: 宋体; ">副本</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">，导致</span><span lang="EN-US">dosomething</span><span style="font-family: 宋体; ">永远也不会被调用。</span></font></p><p class="MsoNormal" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; "><span style="font-family: 宋体; ">如果将将变量加上</span><font face="宋体"><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">修饰，则编译器保证对此变量的读写操作都不会被优化（肯定执行）。此例中</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">也应该如此说明。</span>&nbsp;</font><span lang="EN-US"><br></span><span style="font-family: 宋体; ">一般说来，</span><font face="宋体"><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">用在如下的几个地方：</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">1</font></span><span style="font-family: 宋体; ">、中断服务程序中修改的供其它程序检测的变量需要加</span><font face="宋体"><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">；</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">2</font></span><span style="font-family: 宋体; ">、多任务环境下各任务间共享的标志应该加</span><font face="宋体"><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">；</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">3</font></span><span style="font-family: 宋体; ">、存储器映射的硬件寄存器通常也要加</span><font face="宋体"><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">说明，因为每次对它的读写都可能有不同意义；</span>&nbsp;</font><span lang="EN-US"><br></span><span style="font-family: 宋体; ">另外，以上这几种情况经常还要同时考虑数据的完整性（相互关联的几个标志读了一半被打断了重写），在</span><font face="宋体"><span lang="EN-US">1</span><span style="font-family: 宋体; ">中可以通过关中断来实现，</span><span lang="EN-US">2</span><span style="font-family: 宋体; ">中可以禁止任务调度，</span><span lang="EN-US">3</span><span style="font-family: 宋体; ">中则只能依靠硬件的良好设计了。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>1.&nbsp;</span><span style="font-family: 宋体; ">因为</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">抑制了优化，因而应尽量减少对它的引用操作，最好只对它进行简单的读写赋值，如：</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">volatile char *pcWr_g;&nbsp;<br>...&nbsp;<br>while (...)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; *pcWr_g++=UDR;&nbsp;<br>...&nbsp;<br><br></font></span><span style="font-family: 宋体; ">考虑改写成：</span><font face="宋体"><span lang="EN-US">&nbsp;<br><br>char *pcTemp;&nbsp;<br>...&nbsp;<br>pcTemp=pcWr_g;&nbsp;<br>while (...)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; *pcTemp++=UDR;&nbsp;<br>pcWr_g=pcTemp;&nbsp;<br>...&nbsp;<br></span><span style="font-family: 宋体; ">（其实即便</span><span lang="EN-US">pcWr_g</span><span style="font-family: 宋体; ">是普通的全局变量，一般而言也是改写后的效率高些，可以在循环中只针对寄存器操作）</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">2.&nbsp;</font></span><span style="font-family: 宋体; ">优化还会清除死代码、执行代码合并等，因而某些</span><font face="宋体"><span lang="EN-US">C</span><span style="font-family: 宋体; ">语句可能找不到直接对应的汇编代码，这应该只会给调试设置断点有影响，不影响运行结果。</span>&nbsp;</font><span lang="EN-US"><br><font face="宋体">3.&nbsp;</font></span><span style="font-family: 宋体; ">类似</span><font face="宋体"><span lang="EN-US">&nbsp;<br>for (i=0; i&lt;10000; i++)&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; j=0;&nbsp;<br></span><span style="font-family: 宋体; ">之类的延时，如果不把</span><span lang="EN-US">j</span><span style="font-family: 宋体; ">或者</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">说明成</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">，编译器都会当成无用代码把优化掉</span>&nbsp;</font><span lang="EN-US"><br><br></span></p><p class="MsoNormal" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; "><span style="font-family: 宋体; ">文章二：</span><font face="宋体"><span lang="EN-US">&nbsp;<br>volatile</span><span style="font-family: 宋体; ">的本意是一般有两种说法</span><span lang="EN-US">--1.&#8220;</span><span style="font-family: 宋体; ">暂态的</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">；</span><span lang="EN-US">2.&#8220;</span><span style="font-family: 宋体; ">易变的</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">这两种说法都有可行。但是究竟</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">是什么意思，现举例说明（以</span><span lang="EN-US">Keil-c</span><span style="font-family: 宋体; ">与</span><span lang="EN-US">a51</span><span style="font-family: 宋体; ">为例</span>&nbsp;<span style="font-family: 宋体; ">例子来自</span><span lang="EN-US">Keil FQA</span><span style="font-family: 宋体; ">）</span><span lang="EN-US">,</span><span style="font-family: 宋体; ">看完例子后你应该明白</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">的意思了，如果还不明白，那只好</span>&nbsp;<span style="font-family: 宋体; ">再看一遍了。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">例</span></font><font face="宋体"><span lang="EN-US">1.&nbsp;<br><br>void main (void)&nbsp;<br>{&nbsp;<br>volatile int i;&nbsp;<br>int j;&nbsp;<br><br>i = 1;&nbsp;&nbsp; //1&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">不被优化</span></font><font face="宋体"><span lang="EN-US">&nbsp;i=1&nbsp;<br>i = 2;&nbsp;&nbsp; //2&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">不被优化</span></font><font face="宋体"><span lang="EN-US">&nbsp;i=1&nbsp;<br>i = 3;&nbsp;&nbsp; //3&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">不被优化</span></font><font face="宋体"><span lang="EN-US">&nbsp;i=1&nbsp;<br><br>j = 1;&nbsp;&nbsp; //4&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">被优化</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>j = 2;&nbsp;&nbsp; //5&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">被优化</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>j = 3;&nbsp;&nbsp; //6&nbsp;&nbsp; j = 3&nbsp;<br>}&nbsp;<br>---------------------------------------------------------------------&nbsp;<br></span><span style="font-family: 宋体; ">例</span></font><font face="宋体"><span lang="EN-US">2.&nbsp;<br><br></span><span style="font-family: 宋体; ">函数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>void func (void)&nbsp;<br>{&nbsp;<br>unsigned char xdata xdata_junk;&nbsp;<br>unsigned char xdata *p = &amp;xdata_junk;&nbsp;<br>unsigned char t1, t2;&nbsp;<br><br>t1 = *p;&nbsp;<br>t2 = *p;&nbsp;<br>}&nbsp;<br><br></span><span style="font-family: 宋体; ">编译的汇编为：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>0000 7E00&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R6,#HIGH xdata_junk&nbsp;<br>0002 7F00&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R7,#LOW xdata_junk&nbsp;<br>;---- Variable &#8217;p&#8217; assigned to Register &#8217;R6/R7&#8217; ----&nbsp;<br><br>0004 8F82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DPL,R7&nbsp;<br>0006 8E83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DPH,R6&nbsp;<br><br>;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;</span><span style="font-family: 宋体; ">注意</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>0008 E0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOVX&nbsp;&nbsp;&nbsp;&nbsp; A,@DPTR&nbsp;<br>0009 F500&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t1,A&nbsp;<br><br>000B F500&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t2,A&nbsp;<br>;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;<br>000D 22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br></span><span style="font-family: 宋体; ">将函数变为：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>void func (void)&nbsp;<br>{&nbsp;<br>volatile unsigned char xdata xdata_junk;&nbsp;<br>volatile unsigned char xdata *p = &amp;xdata_junk;&nbsp;<br>unsigned char t1, t2;&nbsp;<br><br>t1 = *p;&nbsp;<br>t2 = *p;&nbsp;<br>}&nbsp;<br><br></span><span style="font-family: 宋体; ">编译的汇编为：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>0000 7E00&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R6,#HIGH xdata_junk&nbsp;<br>0002 7F00&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R7,#LOW xdata_junk&nbsp;<br>;---- Variable &#8217;p&#8217; assigned to Register &#8217;R6/R7&#8217; ----&nbsp;<br><br>0004 8F82&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DPL,R7&nbsp;<br>0006 8E83&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DPH,R6&nbsp;<br><br>;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;<br>0008 E0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOVX&nbsp;&nbsp;&nbsp;&nbsp; A,@DPTR&nbsp;<br>0009 F500&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t1,A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;a</span><span style="font-family: 宋体; ">处</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>000B E0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOVX&nbsp;&nbsp;&nbsp;&nbsp; A,@DPTR&nbsp;<br>000C F500&nbsp;&nbsp;&nbsp;&nbsp; R&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t2,A&nbsp;<br>;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!&nbsp;<br><br>000E 22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><br></span><span style="font-family: 宋体; ">比较结果可以看出来，未用</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字时，只从</span><span lang="EN-US">*p</span><span style="font-family: 宋体; ">所指的地址读一次</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">如在</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">处</span><span lang="EN-US">*p</span><span style="font-family: 宋体; ">的内容有变化，则</span><span lang="EN-US">t2</span><span style="font-family: 宋体; ">得到的则不是真正</span><span lang="EN-US">*p</span><span style="font-family: 宋体; ">的内容。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>---------------------------------------------------------------------&nbsp;<br></span><span style="font-family: 宋体; ">例</span></font><font face="宋体"><span lang="EN-US">3&nbsp;<br><br><br>volatile unsigned char bdata var;&nbsp;&nbsp; // use volatile keyword here&nbsp;<br>sbit var_0 = var^0;&nbsp;<br>sbit var_1 = var^1;&nbsp;<br>unsigned char xdata values[10];&nbsp;<br><br>void main (void)&nbsp;&nbsp; {&nbsp;<br>&nbsp;&nbsp; unsigned char i;&nbsp;<br><br>&nbsp;&nbsp; for (i = 0; i &lt; sizeof (values); i++)&nbsp;&nbsp; {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; var = values<u>;</u>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; if (var_0)&nbsp;&nbsp; {&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var_1 = 1; //a</span><span style="font-family: 宋体; ">处</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values = var;&nbsp;&nbsp; // without the volatile keyword, the compiler&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // assumes that &#8217;var&#8217; is unmodified and does not&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // reload the variable content.&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br>&nbsp;&nbsp; }&nbsp;<br>}&nbsp;<br><br><br></span><span style="font-family: 宋体; ">在此例中，如在</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">处到下一句运行前，</span><span lang="EN-US">var</span><span style="font-family: 宋体; ">如有变化则不会，如</span><span lang="EN-US">var=0xff;&nbsp;</span><span style="font-family: 宋体; ">则在</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>values = var;</span><span style="font-family: 宋体; ">得到的还是</span></font><font face="宋体"><span lang="EN-US">values = 1;&nbsp;<br><br>---------------------------------------------------------------------&nbsp;<br></span><span style="font-family: 宋体; ">应用举例：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">例</span></font><font face="宋体"><span lang="EN-US">1.&nbsp;<br>#define DBYTE ((unsigned char volatile data&nbsp;&nbsp; *) 0)&nbsp;<br><br></span><span style="font-family: 宋体; ">说明：此处不用</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字，可能得不到真正的内容。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>---------------------------------------------------------------------&nbsp;<br><br></span><span style="font-family: 宋体; ">例</span></font><font face="宋体"><span lang="EN-US">2.&nbsp;<br><br><br>#define TEST_VOLATILE_C&nbsp;&nbsp;&nbsp;<br><br>//***************************************************************&nbsp;<br>// verwendete Include Dateien&nbsp;<br>//***************************************************************&nbsp;<br>#if __C51__ &lt; 600&nbsp;<br>&nbsp;&nbsp; #error: !! Keil&nbsp;</span><span style="font-family: 宋体; ">版本不正确</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>#endif&nbsp;<br><br>//***************************************************************&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">函数</span></font><font face="宋体"><span lang="EN-US">&nbsp;void v_IntOccured(void)&nbsp;<br>//***************************************************************&nbsp;<br>extern void v_IntOccured(void);&nbsp;<br><br>//***************************************************************&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">变量定义</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//***************************************************************&nbsp;<br>char xdata cValue1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体; ">全局</span></font><font face="宋体"><span lang="EN-US">xdata&nbsp;<br>char volatile xdata cValue2; //</span><span style="font-family: 宋体; ">全局</span></font><font face="宋体"><span lang="EN-US">xdata&nbsp;<br><br>//***************************************************************&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">函数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;v_ExtInt0()&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">版本：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">参数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">用途：</span></font><font face="宋体"><span lang="EN-US">cValue1++,cValue2++&nbsp;<br>//***************************************************************&nbsp;<br>void v_ExtInt0(void) interrupt 0 {&nbsp;<br>&nbsp;&nbsp; cValue1++;&nbsp;<br>&nbsp;&nbsp; cValue2++;&nbsp;&nbsp;&nbsp;<br>}&nbsp;&nbsp;&nbsp;<br><br>//***************************************************************&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">函数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;main()&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">版本：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">参数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">用途：测试</span></font><font face="宋体"><span lang="EN-US">volatile&nbsp;<br>//***************************************************************&nbsp;<br><br>void main() {&nbsp;<br>char cErg;&nbsp;<br><br>//1.&nbsp;</span><span style="font-family: 宋体; ">使</span></font><font face="宋体"><span lang="EN-US">cErg=cValue1;&nbsp;<br>cErg = cValue1;&nbsp;<br><br>//2.&nbsp;</span><span style="font-family: 宋体; ">在此处仿真时手动产生中断</span><span lang="EN-US">INT0,</span><span style="font-family: 宋体; ">使</span></font><font face="宋体"><span lang="EN-US">cValue1++; cValue2++&nbsp;<br>if (cValue1 != cErg)&nbsp;<br>&nbsp;&nbsp; v_IntOccured();&nbsp;<br><br>//3.&nbsp;</span><span style="font-family: 宋体; ">使</span></font><font face="宋体"><span lang="EN-US">cErg=cValue2;&nbsp;<br>cErg = cValue2;&nbsp;<br><br>//4.&nbsp;</span><span style="font-family: 宋体; ">在此处仿真时手动产生中断</span><span lang="EN-US">INT0,</span><span style="font-family: 宋体; ">使</span></font><font face="宋体"><span lang="EN-US">cValue1++; cValue2++&nbsp;<br>if (cValue2 != cErg)&nbsp;<br>&nbsp;&nbsp; v_IntOccured();&nbsp;<br>&nbsp;&nbsp;&nbsp;<br>//5.&nbsp;</span><span style="font-family: 宋体; ">完成</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&nbsp;&nbsp; while (1);&nbsp;<br>}&nbsp;<br><br>//***************************************************************&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">函数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;v_IntOccured()&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">版本：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">参数：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//&nbsp;</span><span style="font-family: 宋体; ">用途：</span>&nbsp;<span style="font-family: 宋体; ">死循环</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>//***************************************************************&nbsp;<br>void v_IntOccured() {&nbsp;<br>&nbsp;&nbsp; while(1);&nbsp;<br>}&nbsp;<br><br></span><span style="font-family: 宋体; ">仿真可以看出，在没有用</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">时，即</span><span lang="EN-US">2</span><span style="font-family: 宋体; ">处，程序不能进入</span></font><font face="宋体"><span lang="EN-US">v_IntOccured();&nbsp;<br></span><span style="font-family: 宋体; ">但在</span><span lang="EN-US">4</span><span style="font-family: 宋体; ">处可以进入</span></font><font face="宋体"><span lang="EN-US">v_IntOccured();&nbsp;<br><br>***********************************************************************************************&nbsp;<br><br><br></span><span style="font-family: 宋体; ">关于</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字的说明以及测试</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>volatile</span><span style="font-family: 宋体; ">关键字是一种类型修饰符，用它声明的类型变量表示可以被某些编译器未知的因素更改，比如</span>&nbsp;<span style="font-family: 宋体; ">操作系统、硬件或者其它线程等。遇到这个关键字声明的变量，编译器对访问该变量的代码就不再进行优化，从而可以提供对特殊地址的稳定访问。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">使用该关键字的例子如下：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>int volatile nVint;&nbsp;<br></span><span style="font-family: 宋体; ">当要求使用</span><span lang="EN-US">volatile&nbsp;</span><span style="font-family: 宋体; ">声明的变量的值的时候，系统总是重新从它所在的内存读取数据，即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">例如：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>volatile int i=10;&nbsp;<br>int a = i;&nbsp;<br></span><span style="font-family: 宋体; ">。。。</span><span lang="EN-US">//</span><span style="font-family: 宋体; ">其他代码，并未明确告诉编译器，对</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">进行过操作</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>int b = i;&nbsp;<br>volatile&nbsp;</span><span style="font-family: 宋体; ">指出</span><span lang="EN-US">&nbsp;i</span><span style="font-family: 宋体; ">是随时可能发生变化的，每次使用它的时候必须从</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">的地址中读取，因而编译器生成的汇编代码会重新从</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">的地址读取数据放在</span><span lang="EN-US">b</span><span style="font-family: 宋体; ">中。而优化做法是，由于编译器发现两次从</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">读数据的代码之间的代码没有对</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">进行过操作，它会自动把上次读的数据放在</span><span lang="EN-US">b</span><span style="font-family: 宋体; ">中。而不是重新从</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">里面读。这样以来，如果</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">是一个寄存器变量或者表示一个端口数据就容易出错，所以说</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">可以保证对特殊地址的稳定访问</span>&nbsp;<span style="font-family: 宋体; ">。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">注意，在</span><span lang="EN-US">vc6</span><span style="font-family: 宋体; ">中，一般调试模式没有进行代码优化，所以这个关键字的作用看不出来。下面通过插入汇编代码，测试有无</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字，对程序最终代码的影响：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">首先用</span><span lang="EN-US">classwizard</span><span style="font-family: 宋体; ">建一个</span><span lang="EN-US">win32 console</span><span style="font-family: 宋体; ">工程，插入一个</span><span lang="EN-US">voltest.cpp</span><span style="font-family: 宋体; ">文件，输入下面的代码：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>＃i nclude&nbsp;<br>void main()&nbsp;<br>{&nbsp;<br>int i=10;&nbsp;<br>int a = i;&nbsp;<br>printf("i= %d\n",a);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //</span><span style="font-family: 宋体; ">下面汇编语句的作用就是改变内存中</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">的值，但是又不让编译器知道</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>__asm {&nbsp;<br>&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4], 20h&nbsp;<br>}&nbsp;<br>int b = i;&nbsp;<br>printf("i= %d\n",b);&nbsp;<br>}&nbsp;<br></span><span style="font-family: 宋体; ">然后，在调试版本模式运行程序，输出结果如下：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 32&nbsp;<br></span><span style="font-family: 宋体; ">然后，在</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">版本模式运行程序，输出结果如下：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 10&nbsp;<br></span><span style="font-family: 宋体; ">输出的结果明显表明，</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">模式下，编译器对代码进行了优化，第二次没有输出正确的</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">值。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">下面，我们把</span><span lang="EN-US">&nbsp;i</span><span style="font-family: 宋体; ">的声明加上</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字，看看有什么变化：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>＃i nclude&nbsp;<br>void main()&nbsp;<br>{&nbsp;<br>volatile int i=10;&nbsp;<br>int a = i;&nbsp;<br>printf("i= %d\n",a);&nbsp;<br>__asm {&nbsp;<br>&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4], 20h&nbsp;<br>}&nbsp;<br>int b = i;&nbsp;<br>printf("i= %d\n",b);&nbsp;<br>}&nbsp;<br></span><span style="font-family: 宋体; ">分别在调试版本和</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">版本运行程序，输出都是：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 32&nbsp;<br></span><span style="font-family: 宋体; ">这说明这个关键字发挥了它的作用！</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>************************************************************************************&nbsp;<br><br></span><span style="font-family: 宋体; ">发贴心情</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">上午在</span><span lang="EN-US">CSDN</span><span style="font-family: 宋体; ">的</span><span lang="EN-US">C</span><span style="font-family: 宋体; ">＋＋版逛时，发现有人在问</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字的用义和用法。于是乎便写了这篇</span><span lang="EN-US">BLOG</span><span style="font-family: 宋体; ">。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">如果你懂一点点的编译器的知识我想你都会知道编译器在编译你的代码的时候，用进行自动优化的，用以产生优化指令。同上操作系统和一些线程同样也会对你所定义的一些变量做出一些你所不知道的更改。这样的更改我们称为，隐式修改，因为你不知道，编译器在什么情况下，在那里做出了优化，甚至你都不知道，或是不能肯定编译器到底有没有对你的代码做出优化。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">直接点把你看看下面的例子</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>＃i nclude&nbsp;<br>void main()&nbsp;<br>{&nbsp;<br>int i=10;&nbsp;<br>int a = i;&nbsp;<br>printf("i= %d\n",a);&nbsp;<br>__asm {&nbsp;<br>mov dword ptr [ebp-4], 50h&nbsp;<br>}&nbsp;<br>//</span><span style="font-family: 宋体; ">下面汇编语句的作用就是改变内存中</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">的值，但是又不让编译器知道</span><span lang="EN-US">,</span><span style="font-family: 宋体; ">来隐式的修改了变量。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>int b = i;&nbsp;<br>printf("i= %d\n",b);&nbsp;<br>}&nbsp;<br><br></span><span style="font-family: 宋体; ">然后，在调试版本</span><span lang="EN-US">(debug)</span><span style="font-family: 宋体; ">模式运行程序，输出结果如下：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 80&nbsp;<br></span><span style="font-family: 宋体; ">然后，在</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">版本模式运行程序，输出结果如下：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 10&nbsp;<br><br></span><span style="font-family: 宋体; ">呵呵结果看到了吗？输出的结果明显表明，</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">模式下，编译器对代码进行了优化，第二次没有输出正确的</span><span lang="EN-US">i</span><span style="font-family: 宋体; ">值。所以得出一个结论在</span><span lang="EN-US">VC</span><span style="font-family: 宋体; ">中</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">模式编译代码时编译器会自动对你的代码来做起优化的。而调试版本</span><span lang="EN-US">(debug)</span><span style="font-family: 宋体; ">模式下便不会。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">废话说了好多啊呵呵　下面继续说说</span></font><font face="宋体"><span lang="EN-US">&nbsp;volatile&nbsp;<br></span><span style="font-family: 宋体; ">下面，我们把</span><span lang="EN-US">&nbsp;i</span><span style="font-family: 宋体; ">的声明加上</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字，看看有什么效果：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>＃i nclude&nbsp;<br>void main()&nbsp;<br>{&nbsp;<br>volatile int i=10;&nbsp;<br>int a = i;&nbsp;<br>printf("i= %d\n",a);&nbsp;<br>__asm {&nbsp;<br>&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4], 50h&nbsp;<br>}&nbsp;<br>int b = i;&nbsp;<br>printf("i= %d\n",b);&nbsp;<br>}&nbsp;<br></span><span style="font-family: 宋体; ">这下你再在调试版本和</span><span lang="EN-US">release</span><span style="font-family: 宋体; ">版本运行程序，看看输出结果是不是都是：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>i = 10&nbsp;<br>i = 32&nbsp;<br></span><span style="font-family: 宋体; ">估计大家看到这里便会明白了，</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">　这个关键字最最主要的意思是做什么的了。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">在</span><span lang="EN-US">MSDN</span><span style="font-family: 宋体; ">中</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">是一个限定符，也称为</span><span lang="EN-US">keyword</span><span style="font-family: 宋体; ">或描述符，</span><span lang="EN-US">"volatile&nbsp;</span><span style="font-family: 宋体; ">关键字指示字段可由操作系统、硬件或并发执行的线程在程序中进行修改。</span></font><font face="宋体"><span lang="EN-US">"&nbsp;<br></span><span style="font-family: 宋体; ">当要求使用</span><span lang="EN-US">volatile&nbsp;</span><span style="font-family: 宋体; ">声明的变量的值的时候，系统总是重新从它所在的内存读取数据，即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">一般说来，</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">用在如下的几个地方：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>1</span><span style="font-family: 宋体; ">、中断服务程序中修改的供其它程序检测的变量需要加</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">；</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>2</span><span style="font-family: 宋体; ">、多任务环境下各任务间共享的标志应该加</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">；</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>3</span><span style="font-family: 宋体; ">、存储器映射的硬件寄存器通常也要加</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">说明，因为每次对它的读写都可能由不同意义；</span></font><font face="宋体"><span lang="EN-US">&nbsp;&nbsp;&nbsp;<br><br></span><span style="font-family: 宋体; ">声明方式为　　</span></font><font face="宋体"><span lang="EN-US">volatile declaration&nbsp;<br><br></span><span style="font-family: 宋体; ">备注</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">系统总是在</span><span lang="EN-US">&nbsp;volatile&nbsp;</span><span style="font-family: 宋体; ">对象被请求的那一刻读取其当前值，即使上一条指令从同一对象请求值。而且，该对象的值在赋值时立即写入。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>volatile&nbsp;</span><span style="font-family: 宋体; ">修饰符通常用于由多个线程访问而不使用</span><span lang="EN-US">&nbsp;lock&nbsp;</span><span style="font-family: 宋体; ">语句来序列化访问的字段。使用</span><span lang="EN-US">&nbsp;volatile&nbsp;</span><span style="font-family: 宋体; ">修饰符能够确保一个线程检索由另一线程写入的最新值。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">备注部分由</span><span lang="EN-US">MSDN</span><span style="font-family: 宋体; ">原文所说。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">本文参考：关于</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">关键字的说明以及测试（作者：</span><span lang="EN-US">iwaswzq</span><span style="font-family: 宋体; ">）　有关</span><span lang="EN-US">volatile (</span><span style="font-family: 宋体; ">函数前加</span><span lang="EN-US">volatile)&nbsp;</span><span style="font-family: 宋体; ">和</span><span lang="EN-US">inline</span><span style="font-family: 宋体; ">的用法（作者：</span><span lang="EN-US">kobefly</span><span style="font-family: 宋体; ">）</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>15:47 2005-11-14</span><span style="font-family: 宋体; ">　　</span><span lang="EN-US">50</span><span style="font-family: 宋体; ">米于公司</span><span lang="EN-US">&nbsp;&nbsp;&nbsp;</span><span style="font-family: 宋体; ">下午无聊时所写。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>****************************************************************************************&nbsp;<br><br></span><span style="font-family: 宋体; ">关键字</span><span lang="EN-US">Const</span><span style="font-family: 宋体; ">与</span><span lang="EN-US">Volatile</span><span style="font-family: 宋体; ">的使用</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">关键字</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">有什么含意？</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">我只要一听到被面试者说：</span><span lang="EN-US">&#8220;const</span><span style="font-family: 宋体; ">意味着常数</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">，我就知道我正在和一个业余者打交道。去年</span><span lang="EN-US">Dan Saks</span><span style="font-family: 宋体; ">已经在他的文章里完全概括了</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">的所有用法，因此</span><span lang="EN-US">ESP(</span><span style="font-family: 宋体; ">译者：</span><span lang="EN-US">Embedded Systems Programming)</span><span style="font-family: 宋体; ">的每一位读者应该非常熟悉</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">能做什么和不能做什么</span><span lang="EN-US">.</span><span style="font-family: 宋体; ">如果你从没有读到那篇文章，只要能说出</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">意味着</span><span lang="EN-US">&#8220;</span><span style="font-family: 宋体; ">只读</span><span lang="EN-US">&#8221;</span><span style="font-family: 宋体; ">就可以了。尽管这个答案不是完全的答案，但我接受它作为一个正确的答案。（如果你想知道更详细的答案，仔细读一下</span><span lang="EN-US">Saks</span><span style="font-family: 宋体; ">的文章吧。）</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">如果应试者能正确回答这个问题，我将问他一个附加的问题：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">下面的声明都是什么意思？</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br>const int a;&nbsp;<br>int const a;&nbsp;<br>const int *a;&nbsp;<br>int * const a;&nbsp;<br>int const * a const;&nbsp;<br><br>/******/&nbsp;<br></span><span style="font-family: 宋体; ">前两个的作用是一样，</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">是一个常整型数。第三个意味着</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">是一个指向常整型数的指针（也就是，整型数是不可修改的，但指针可以）。第四个意思</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">是一个指向整型数的常指针（也就是说，指针指向的整型数是可以修改的，但指针是不可修改的）。最后一个意味着</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">是一个指向常整型数的常指针（也就是说，指针指向的整型数是不可修改的，同时指针也是不可修改的）。如果应试者能正确回答这些问题，那么他就给我留下了一个好印象。顺带提一句，也许你可能会问，即使不用关键字</span><span lang="EN-US">&nbsp;const</span><span style="font-family: 宋体; ">，也还是能很容易写出功能正确的程序，那么我为什么还要如此看重关键字</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">呢？我也如下的几下理由：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">关键字</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">的作用是为给读你代码的人传达非常有用的信息，实际上，声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾，你就会很快学会感谢这点多余的信息。（当然，懂得用</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">的程序员很少会留下的垃圾让别人来清理的。）</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">通过给优化器一些附加的信息，使用关键字</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">也许能产生更紧凑的代码。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">合理地使用关键字</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">可以使编译器很自然地保护那些不希望被改变的参数，防止其被无意的代码修改。简而言之，这样可以减少</span><span lang="EN-US">bug</span><span style="font-family: 宋体; ">的出现。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br><br>Volatile&nbsp;<br><br>8.&nbsp;</span><span style="font-family: 宋体; ">关键字</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">有什么含意</span><span lang="EN-US">?</span><span style="font-family: 宋体; ">并给出三个不同的例子。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">一个定义为</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">的变量是说这变量可能会被意想不到地改变，这样，编译器就不会去假设这个变量的值了。精确地说就是，优化器在用到这个变量时必须每次都小心地重新读取这个变量的值，而不是使用保存在寄存器里的备份。下面是</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">变量的几个例子：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">并行设备的硬件寄存器（如：状态寄存器）</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">一个中断服务子程序中会访问到的非自动变量</span></font><font face="宋体"><span lang="EN-US">(Non-automatic variables)&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">多线程应用中被几个任务共享的变量</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br></span><span style="font-family: 宋体; ">回答不出这个问题的人是不会被雇佣的。我认为这是区分</span><span lang="EN-US">C</span><span style="font-family: 宋体; ">程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、</span><span lang="EN-US">RTOS</span><span style="font-family: 宋体; ">等等打交道，所有这些都要求用到</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">变量。不懂得</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">的内容将会带来灾难。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br></span><span style="font-family: 宋体; ">假设被面试者正确地回答了这是问题（嗯，怀疑是否会是这样），我将稍微深究一下，看一下这家伙是不是直正懂得</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">完全的重要性。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">一个参数既可以是</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">还可以是</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">吗？解释为什么。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">一个指针可以是</span><span lang="EN-US">volatile&nbsp;</span><span style="font-family: 宋体; ">吗？解释为什么。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">下面的函数有什么错误：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>int square(volatile int *ptr)&nbsp;<br>{&nbsp;<br>return *ptr * *ptr;&nbsp;<br>}&nbsp;<br><br></span><span style="font-family: 宋体; ">下面是答案：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">是的。一个例子是只读的状态寄存器。它是</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">因为它可能被意想不到地改变。它是</span><span lang="EN-US">const</span><span style="font-family: 宋体; ">因为程序不应该试图去修改它。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个</span><span lang="EN-US">buffer</span><span style="font-family: 宋体; ">的指针时。</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br>&#8226;;&nbsp;</span><span style="font-family: 宋体; ">这段代码有点变态。这段代码的目的是用来返指针</span><span lang="EN-US">*ptr</span><span style="font-family: 宋体; ">指向值的平方，但是，由于</span><span lang="EN-US">*ptr</span><span style="font-family: 宋体; ">指向一个</span><span lang="EN-US">volatile</span><span style="font-family: 宋体; ">型参数，编译器将产生类似下面的代码：</span></font><font face="宋体"><span lang="EN-US">&nbsp;<br><br><br>int square(volatile int *ptr)&nbsp;<br>{&nbsp;<br>int a,b;&nbsp;<br>a = *ptr;&nbsp;<br>b = *ptr;&nbsp;<br>return a * b;&nbsp;<br>}&nbsp;<br><br><br></span><span style="font-family: 宋体; ">由于</span><span lang="EN-US">*ptr</span><span style="font-family: 宋体; ">的值可能被意想不到地该变，因此</span><span lang="EN-US">a</span><span style="font-family: 宋体; ">和</span><span lang="EN-US">b</span><span style="font-family: 宋体; ">可能是不同的。结果，这段代码可能返不是你所期望的平方值！正确的代码如下：</span></font><span lang="EN-US"><font face="宋体">&nbsp;<br><br>long square(volatile int *ptr)&nbsp;<br>{&nbsp;<br>int a;&nbsp;<br>a = *ptr;&nbsp;<br>return a * a;&nbsp;<br>}</font></span></p><p class="MsoNormal" style="margin-top: 0cm; margin-right: 0cm; margin-bottom: 0pt; margin-left: 0cm; "><font  face="宋体">转载于<span  style="font-family: georgia, Verdana, Helvetica, Arial; "><a href="http://blog.21ic.com/user1/6113/archives/2009/64856.html">http://blog.21ic.com/user1/6113/archives/2009/64856.html</a></span></font></p></span>
<img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-16 23:25 <a href="http://www.cnitblog.com/seedshopezhong/articles/64687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux c字符测试篇</title><link>http://www.cnitblog.com/seedshopezhong/articles/64686.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Tue, 16 Mar 2010 14:34:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64686.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64686.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64686.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64686.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64686.html</trackback:ping><description><![CDATA[<span style="border-collapse: collapse; font-family: song, Verdana; font-size: 12px; ">isalnum（测试字符是否为英文或数字）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isalpha，isdigit，islower，isupper<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isalnum (int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为英文字母或阿拉伯数字，在标准c中相当于使用<br style="font: normal normal normal 12px/normal song, Verdana; ">&#8220;isalpha(c) || isdigit(c)&#8221;做测试。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为字母或数字，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 找出str 字符串中为英文字母或数字的字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt; ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]=&#8221;123c@#FDsP[e?&#8221;;<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for (i=0;str[i]!=0;i++ )<br style="font: normal normal normal 12px/normal song, Verdana; ">if ( isalnum(str[i])) printf(&#8220;%c is an alphanumeric<br style="font: normal normal normal 12px/normal song, Verdana; ">character\n&#8221;,str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 1 is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">2 is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">3 is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">c is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">F is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">D is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">s is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">P is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">e is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">isalpha （测试字符是否为英文字母）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isalnum，islower，isupper<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isalpha (int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为英文字母，在标准c中相当于使用&#8220;isupper(c)<br style="font: normal normal normal 12px/normal song, Verdana; ">||islower(c)&#8221;做测试。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为英文字母，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，1/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 找出str 字符串中为英文字母的字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]=&#8221;123c@#FDsP[e?&#8221;;<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for (i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isalpha(str[i])) printf(&#8220;%c is an alphanumeric<br style="font: normal normal normal 12px/normal song, Verdana; ">character\n&#8221;,str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 c is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">F is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">D is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">s is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">P is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">e is an apphabetic character<br style="font: normal normal normal 12px/normal song, Verdana; ">isascii（测试字符是否为ASCII 码字符）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 iscntrl<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isascii(int c);<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为ASCII码字符，也就是判断c的范围是否在0到127之<br style="font: normal normal normal 12px/normal song, Verdana; ">间。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为ASCII码字符，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 判断int i是否具有对映的ASCII码字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=125;i&lt;130;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isascii(i))<br style="font: normal normal normal 12px/normal song, Verdana; ">printf("%d is an ascii character:%c\n",i,i);<br style="font: normal normal normal 12px/normal song, Verdana; ">else<br style="font: normal normal normal 12px/normal song, Verdana; ">printf("%d is not an ascii character\n",i);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 125 is an ascii character:}<br style="font: normal normal normal 12px/normal song, Verdana; ">126 is an ascii character:~<br style="font: normal normal normal 12px/normal song, Verdana; ">127 is an ascii character:<br style="font: normal normal normal 12px/normal song, Verdana; ">128 is not an ascii character<br style="font: normal normal normal 12px/normal song, Verdana; ">129 is not an ascii character<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，2/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">iscntrl（测试字符是否为ASCII 码的控制字符）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isascii<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int iscntrl(int c)；<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为ASCII控制码，也就是判断c的范围是否在0到30之<br style="font: normal normal normal 12px/normal song, Verdana; ">间。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为ASCII控制码，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">isdigit（测试字符是否为阿拉伯数字）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isxdigit<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isdigit(int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为阿拉伯数字0到9。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为阿拉伯数字，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 找出str字符串中为阿拉伯数字的字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="<a href="mailto:123@#FDsP[e" style="text-decoration: underline; color: rgb(0, 68, 182); ">123@#FDsP[e</a>?";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isdigit(str[i])) printf("%c is an digit character\n",str<br style="font: normal normal normal 12px/normal song, Verdana; ">[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 1 is an digit character<br style="font: normal normal normal 12px/normal song, Verdana; ">2 is an digit character<br style="font: normal normal normal 12px/normal song, Verdana; ">3 is an digit character<br style="font: normal normal normal 12px/normal song, Verdana; ">isgraphis（测试字符是否为可打印字符）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isprint<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，3/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isgraph (int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为可打印字符，若c所对映的ASCII码可打印，且非空<br style="font: normal normal normal 12px/normal song, Verdana; ">格字符则返回TRUE。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为可打印字符，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 判断str字符串中哪些为可打印字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="a5 @;";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isgraph(str[i])) printf("str[%d] is printable<br style="font: normal normal normal 12px/normal song, Verdana; ">character:%d\n",i,str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 str[0] is printable character:a<br style="font: normal normal normal 12px/normal song, Verdana; ">str[1] is printable character:5<br style="font: normal normal normal 12px/normal song, Verdana; ">str[3] is printable character:@<br style="font: normal normal normal 12px/normal song, Verdana; ">str[4] is printable character:;<br style="font: normal normal normal 12px/normal song, Verdana; ">islower（测试字符是否为小写字母）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isalpha，isupper<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int islower(int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为小写英文字母。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为小写英文字母，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="<a href="mailto:123@#FDsP[e" style="text-decoration: underline; color: rgb(0, 68, 182); ">123@#FDsP[e</a>?";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(islower(str[i])) printf("%c is a lower-case<br style="font: normal normal normal 12px/normal song, Verdana; ">character\n",str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 c is a lower-case character<br style="font: normal normal normal 12px/normal song, Verdana; ">s is a lower-case character<br style="font: normal normal normal 12px/normal song, Verdana; ">e is a lower-case character<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，4/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">isprint（测试字符是（否为可打印字符）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isgraph<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isprint(int c);<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为可打印字符，若c所对映的ASCII码可打印，其中包<br style="font: normal normal normal 12px/normal song, Verdana; ">含空格字符，则返回TRUE。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为可打印字符，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /* 判断str字符串中哪些为可打印字符包含空格字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="a5 @;";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isprint(str[i])) printf("str[%d] is printable<br style="font: normal normal normal 12px/normal song, Verdana; ">character:%d\n",i,str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 str[0] is printable character:a<br style="font: normal normal normal 12px/normal song, Verdana; ">str[1] is printable character:5<br style="font: normal normal normal 12px/normal song, Verdana; ">str[2] is printable character:<br style="font: normal normal normal 12px/normal song, Verdana; ">str[3] is printable character:@<br style="font: normal normal normal 12px/normal song, Verdana; ">str[4] is printable character:;<br style="font: normal normal normal 12px/normal song, Verdana; ">isspace（测试字符是否为空格字符）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isgraph<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isspace(int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为空格字符，也就是判断是否为空格('')、定位字符<br style="font: normal normal normal 12px/normal song, Verdana; ">('\t')、CR('\r')、换行('\n')、垂直定位字符('\v')或翻页<br style="font: normal normal normal 12px/normal song, Verdana; ">('\f')的情况。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为空格字符，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /*将字符串str[]中内含的空格字符找出，并显示空格字符的ASCII<br style="font: normal normal normal 12px/normal song, Verdana; ">码*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，5/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str="123c @# FD\tsP[e?\n";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isspace(str[i]))<br style="font: normal normal normal 12px/normal song, Verdana; ">printf("str[%d] is a white-space character:%d\n",i,str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 str[4] is a white-space character:32<br style="font: normal normal normal 12px/normal song, Verdana; ">str[7] is a white-space character:32<br style="font: normal normal normal 12px/normal song, Verdana; ">str[10] is a white-space character:9 /* \t */<br style="font: normal normal normal 12px/normal song, Verdana; ">str[16] is a white-space character:10 /* \t */<br style="font: normal normal normal 12px/normal song, Verdana; ">ispunct（测试字符是否为标点符号或特殊符号）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isspace，isdigit，isalpha<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #inlude&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int ispunct(int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为标点符号或特殊符号。返回TRUE也就是代表参数c<br style="font: normal normal normal 12px/normal song, Verdana; ">为非空格、非数字和非英文字母。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 v若参数c为标点符号或特殊符号，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /*列出字符串str中的标点符号或特殊符号*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="123c@ #FDsP[e?";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(ispunct(str[i])) printf("%c\n",str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 v<br style="font: normal normal normal 12px/normal song, Verdana; ">@#[?<br style="font: normal normal normal 12px/normal song, Verdana; ">isupper（测试字符是否为大写英文字母）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isalpha，islower<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isupper(int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为大写英文字母。<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，6/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为大写英文字母，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /*找出字符串str中为大写英文字母的字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="<a href="mailto:123c@#FDsP[e" style="text-decoration: underline; color: rgb(0, 68, 182); ">123c@#FDsP[e</a>?";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isupper(str[i])) printf("%c is an uppercase<br style="font: normal normal normal 12px/normal song, Verdana; ">character\n",str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 F is an uppercase character<br style="font: normal normal normal 12px/normal song, Verdana; ">D is an uppercase character<br style="font: normal normal normal 12px/normal song, Verdana; ">P is an uppercase character<br style="font: normal normal normal 12px/normal song, Verdana; ">isxdigit（测试字符是否为16进制数字）<br style="font: normal normal normal 12px/normal song, Verdana; ">相关函数 isalnum，isdigit<br style="font: normal normal normal 12px/normal song, Verdana; ">表头文件 #include&lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">定义函数 int isxdigit (int c)<br style="font: normal normal normal 12px/normal song, Verdana; ">函数说明 检查参数c是否为16进制数字，只要c为下列其中一个情况则返回<br style="font: normal normal normal 12px/normal song, Verdana; ">TRUE。16进制数字:0123456789ABCDEF。<br style="font: normal normal normal 12px/normal song, Verdana; ">返回值 若参数c为16进制数字，则返回TRUE，否则返回NULL(0)。<br style="font: normal normal normal 12px/normal song, Verdana; ">附加说明 此为宏定义，非真正函数。<br style="font: normal normal normal 12px/normal song, Verdana; ">范例 /*找出字符串str中为十六进制数字的字符*/<br style="font: normal normal normal 12px/normal song, Verdana; ">#include &lt;ctype.h&gt;<br style="font: normal normal normal 12px/normal song, Verdana; ">main()<br style="font: normal normal normal 12px/normal song, Verdana; ">{<br style="font: normal normal normal 12px/normal song, Verdana; ">char str[]="<a href="mailto:123c@#FDsP[e" style="text-decoration: underline; color: rgb(0, 68, 182); ">123c@#FDsP[e</a>?";<br style="font: normal normal normal 12px/normal song, Verdana; ">int i;<br style="font: normal normal normal 12px/normal song, Verdana; ">for(i=0;str[i]!=0;i++)<br style="font: normal normal normal 12px/normal song, Verdana; ">if(isxdigit(str[i])) printf("%c is a hexadecimal<br style="font: normal normal normal 12px/normal song, Verdana; ">digits\n",str[i]);<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">执行 1 is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">2 is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">3 is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">c is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">F is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">D is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">Untitled Document 页码，7/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9<br style="font: normal normal normal 12px/normal song, Verdana; ">e is a hexadecimal digits<br style="font: normal normal normal 12px/normal song, Verdana; ">页Untitled Document 码，8/8<br style="font: normal normal normal 12px/normal song, Verdana; "><a href="file:///D:/linux_c/function/01.html" style="text-decoration: underline; color: rgb(0, 68, 182); ">file://D:\linux_c\function\01.html</a>&nbsp;2004-1-9</span>

<div><span style="border-collapse: collapse; font-family: song, Verdana; font-size: 12px; "><br></span></div><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64686.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-16 22:34 <a href="http://www.cnitblog.com/seedshopezhong/articles/64686.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux内存及字符串操作</title><link>http://www.cnitblog.com/seedshopezhong/articles/64685.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Tue, 16 Mar 2010 14:30:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64685.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64685.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64685.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64685.html</trackback:ping><description><![CDATA[
<span style="color: rgb(161, 161, 161); font-family: Arial, Helvetica, sans-serif; font-size: 14px; line-height: 22px; "><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">bcmp（比较内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcmp，strcasecmp，strcmp，strcoll，strncmp，strncasecmp<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int bcmp ( const void *s1,const void * s2,int n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; bcmp()用来比较s1和s2所指的内存区间前n个字节，若参数n为0，则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1 和s2 所指的内存内容都完全相同则返回0 值，否则返回非零值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 建议使用memcmp()取代。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; 参考memcmp()。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">bcopy（拷贝内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; memccpy，memcpy，memmove，strcpy，ctrncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void bcopy ( const void *src,void *dest ,int n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; bcopy()与memcpy()一样都是用来拷贝src所指的内存内容前n个字节到dest所指的地址，不过参数src与dest在传给函数时是相反的位置。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp;&nbsp;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 建议使用memcpy()取代<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char dest[30]=&#8221;string(a)&#8221;;<br style="line-height: 22px; ">char src[30]=&#8221;string\0string&#8221;;<br style="line-height: 22px; ">int i;<br style="line-height: 22px; ">bcopy(src,dest,30);/* src指针放在前*/<br style="line-height: 22px; ">printf(bcopy(): &#8220;)<br style="line-height: 22px; ">for(i=0;i&lt;30;i++)<br style="line-height: 22px; ">printf(&#8220;%c&#8221;,dest[i]);<br style="line-height: 22px; ">memcpy(dest src,30); /*dest指针放在钱*/<br style="line-height: 22px; ">printf(&#8216;\nmemcpy() : &#8220;);<br style="line-height: 22px; ">for(i=0;i&lt;30;i++)<br style="line-height: 22px; ">printf(&#8220;%c&#8221;,dest[i]);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; bcopy() : string string<br style="line-height: 22px; ">memcpy() :string sring<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">bzero（将一段内存内容全清为零）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; memset，swab<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void bzero(void *s,int n)；<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; bzero()会将参数s所指的内存区域前n个字节，全部设为零值。相当于调用memset((void*)s,0,size_tn);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp;&nbsp;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 建议使用memset取代<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; 参考memset()。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">index（查找字符串中第一个出现的指定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; rindex，srechr，strrchr<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * index( const char *s, int c);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; index()用来找出参数s字符串中第一个出现的参数c地址，然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字符则返回该字符所在地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s =&#8221;0123456789012345678901234567890&#8221;;<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p =index(s,&#8217;5&#8217;);<br style="line-height: 22px; ">printf(%s\n&#8221;,p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 5.68E+25<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memccpy（拷贝内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memcpy，memmove，strcpy，strncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void * memccpy(void *dest, const void * src, int c,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是，memccpy()会在复制时检查参数c是否出现，若是则返回dest中值为c的下一个字节地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回指向dest中值为c的下一个字节指针。返回值为0表示在src所指内存前n个字节中没有值为c的字节。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[]="string[a]";<br style="line-height: 22px; ">char b[]="string(b)";<br style="line-height: 22px; ">memccpy(a,b,'B',sizeof(b));<br style="line-height: 22px; ">printf("memccpy():%s\n",a);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; memccpy():string(b)<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memchr（在某一内存范围中查找一特定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，rindex，strchr，strpbrk，strrchr，strsep，strspn，strstr<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void * memchr(const void *s,int c,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memchr()从头开始搜寻s所指的内存内容前n个字节，直到发现第一个值为c的字节，则返回指向该字节的指针。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字节则返回该字节的指针，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s="0123456789012345678901234567890";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p=memchr(s,'5',10);<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 5.68E+25<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memcmp（比较内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcmp，strcasecmp，strcmp，strcoll，strncmp，strncasecmp<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int memcmp (const void *s1,const void *s2,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memcmp()用来比较s1和s2所指的内存区间前n个字符。字符串大小的比较是以ASCII码表上的顺序来决定，次顺序亦为字符的值。memcmp()首先将s1第一个字符值减去s2第一个字符的值，若差为0则再继续比较下个字符，若差值不为0则将差值返回。例如，字符串"Ac"和"ba"比较则会返回字符'A'(65)和'b'(98)的差值(－33)。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1和s2所指的内存内容都完全相同则返回0值。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0的值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *a ="aBcDeF";<br style="line-height: 22px; ">char *b="AbCdEf";<br style="line-height: 22px; ">char *c="aacdef";<br style="line-height: 22px; ">char *d="aBcDeF";<br style="line-height: 22px; ">printf("memcmp(a,b):%d\n",memcmp((void*)a,(void*) b,6));<br style="line-height: 22px; ">printf("memcmp(a,c):%d\n",memcmp((void*)a,(void*) c,6));<br style="line-height: 22px; ">printf("memcmp(a,d):%d\n",memcmp((void*)a,(void*) d,6));<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; memcmp(a,b):1 /*字符串a&gt;字符串b，返回1*/<br style="line-height: 22px; ">memcmp(a,c):-1 /* 字符串a&lt;字符串c,返回－1*/<br style="line-height: 22px; ">memcmp(a,d):0 /*字符串a＝字符串d，返回0*/<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memcpy（拷贝内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memccpy，memcpy，memmove，strcpy，strncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void * memcpy (void * dest ,const void *src, size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是，memcpy()会完整的复制n个字节，不会因为遇到字符串结束'\0'而结束。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回指向dest的指针。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 指针src和dest所指的内存区域不可重叠。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[30]="string (a)";<br style="line-height: 22px; ">char b[30]="string\0string";<br style="line-height: 22px; ">int i;<br style="line-height: 22px; ">strcpy(a,b);<br style="line-height: 22px; ">printf("strcpy():");<br style="line-height: 22px; ">for(i=0;i&lt;30;i++)<br style="line-height: 22px; ">printf("%c",a[i]);<br style="line-height: 22px; ">memcpy(a,b,30);<br style="line-height: 22px; ">printf("\nmemcpy() :");<br style="line-height: 22px; ">for(i=0;i&lt;30;i++)<br style="line-height: 22px; ">printf("%c",a[i]);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; strcpy() : string a )<br style="line-height: 22px; ">memcpy() : string string<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memmove（拷贝内存内容）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memccpy，memcpy，strcpy，strncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void * memmove(void *dest,const void *src,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memmove()与memcpy()一样都是用来拷贝src所指的内存内容前n个字节到dest所指的地址上。不同的是，当src和dest所指的内存区域重叠时，memmove()仍然可以正确的处理，不过执行效率上会比使用memcpy()略慢些。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回指向dest的指针。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 指针src和dest所指的内存区域可以重叠。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; 参考memcpy()。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">memset（将一段内存空间填入某值）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bzero，swab<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; void * memset (void *s ,int c, size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; memset()会将参数s所指的内存区域前n个字节以参数c填入，然后返回指向s的指针。在编写程序时，若需要将某一数组作初始化，memset()会相当方便。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回指向s的指针。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 参数c虽声明为int， 但必须是unsigned char ，所以范围在0到255之间。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char s[30];<br style="line-height: 22px; ">memset (s,'A',sizeof(s));<br style="line-height: 22px; ">s[30]='\0';<br style="line-height: 22px; ">printf("%s\n",s);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">rindex（查找字符串中最后一个出现的指定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，strchr，strrchr<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * rindex( const char *s,int c);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; rindex()用来找出参数s字符串中最后一个出现的参数c地址，然后将该字符出现的地址返回。字符串结束字符(NULL)也视为字符串一部分。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字符则返回该字符所在的地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">mian()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s ="0123456789012345678901234567890";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p=rindex(s,'5');<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 567890<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcasecmp（忽略大小写比较字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcmp，memcmp，strcmp，strcoll，strncmp<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int strcasecmp (const char *s1, const char *s2);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcasecmp()用来比较参数s1和s2字符串，比较时会自动忽略大小写的差异。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1和s2字符串相同则返回0。s1长度大于s2长度则返回大于0 的值，s1 长度若小于s2 长度则返回小于0的值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *a="aBcDeF";<br style="line-height: 22px; ">char *b="AbCdEf";<br style="line-height: 22px; ">if(!strcasecmp(a,b))<br style="line-height: 22px; ">printf("%s=%s\n",a,b);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; aBcDeF=AbCdEf<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcat（连接两字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memccpy，memcpy，strcpy，strncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char *strcat (char *dest,const char *src);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcat()会将参数src字符串拷贝到参数dest所指的字符串尾。第一个参数dest要有足够的空间来容纳要拷贝的字符串。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回参数dest的字符串起始地址<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h.&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[30]="string(1)";<br style="line-height: 22px; ">char b[]="string(2)";<br style="line-height: 22px; ">printf("before strcat() : %s\n",a);<br style="line-height: 22px; ">printf("after strcat() : %s\n",strcat(a,b));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; before strcat () : string(1)<br style="line-height: 22px; ">after strcat () : string(1)string(2)<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strchr（查找字符串中第一个出现的指定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，rinex，strbrk，strsep，strspn，strstr，strtok<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strchr (const char *s,int c);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strchr()用来找出参数s字符串中第一个出现的参数c地址，然后将该字符出现的地址返回。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字符则返回该字符所在地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s=0123456789012345678901234567890&#8221;;<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p=strchr(s,'5');<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 5.68E+25<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcmp（比较字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcmp，memcmp，strcasecmp，strncasecmp，strcoll<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int strcmp(const char *s1,const char *s2);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcmp()用来比较参数s1和s2字符串。字符串大小的比较是以ASCII 码表上的顺序来决定，此顺序亦为字符的值。strcmp()首先将s1第一个字符值减去s2第一个字符值，若差值为0则再继续比较下个字符，若差值不为0则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(－33)。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *a="aBcDeF";<br style="line-height: 22px; ">char *b="AbCdEf";<br style="line-height: 22px; ">char *c="aacdef";<br style="line-height: 22px; ">char *d="aBcDeF";<br style="line-height: 22px; ">printf("strcmp(a,b) : %d\n",strcmp(a,b));<br style="line-height: 22px; ">printf("strcmp(a,c) : %d\n",strcmp(a,c));<br style="line-height: 22px; ">printf("strcmp(a,d) : %d\n",strcmp(a,d));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; strcmp(a,b) : 32<br style="line-height: 22px; ">strcmp(a,c) :-31<br style="line-height: 22px; ">strcmp(a,d) : 0<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcoll（采用目前区域的字符排列次序来比较字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; strcmp，bcmp，memcmp，strcasecmp，strncasecmp<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int strcoll( const char *s1, const char *s2);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcoll()会依环境变量LC_COLLATE所指定的文字排列次序来比较s1和s2 字符串。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1和s2字符串相同则返回0。s1若大于s2则返回大于0的值。s1若小于s2则返回小于0 的值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 若LC_COLLATE为"POSIX"或"C"，则strcoll()与strcmp()作用完全相同。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; 参考strcmp()。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcpy（拷贝字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memcpy，memccpy，memmove<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char *strcpy(char *dest,const char *src);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcpy()会将参数src字符串拷贝至参数dest所指的地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回参数dest的字符串起始地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">附加说明&nbsp; 如果参数dest所指的内存空间不够大，可能会造成缓冲溢出(buffer Overflow)的错误情况，在编写程序时请特别留意，或者用strncpy()来取代。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[30]="string(1)";<br style="line-height: 22px; ">char b[]="string(2)";<br style="line-height: 22px; ">printf("before strcpy() :%s\n",a);<br style="line-height: 22px; ">printf("after strcpy() :%s\n",strcpy(a,b));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; before strcpy() :string(1)<br style="line-height: 22px; ">after strcpy() :string(2)<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strcspn（返回字符串中连续不含指定字符串内容的字符数）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; strspn<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #inclued&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; size_t strcspn ( const char *s,const char * reject);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strcspn()从参数s字符串的开头计算连续的字符，而这些字符都完全不在参数reject 所指的字符串中。简单地说，若strcspn()返回的数值为n，则代表字符串s开头连续有n个字符都不含字符串reject内的字符。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回字符串s开头连续不含字符串reject内的字符数目。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *str="Linux was first developed for 386/486-based pcs.";<br style="line-height: 22px; ">printf("%d\n",strcspn(str," "));<br style="line-height: 22px; ">printf("%d\n",strcspn(str,"/-"));<br style="line-height: 22px; ">printf("%d\n",strcspn(str,"1234567890"));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 5 /*只计算到&#8220; &#8221;的出现，所以返回&#8220;Linux&#8221;的长度*/<br style="line-height: 22px; ">33 /*计算到出现&#8220;/&#8221;或&#8220;－&#8221;，所以返回到&#8220;6&#8221;的长度*/<br style="line-height: 22px; ">30 /* 计算到出现数字字符为止，所以返回&#8220;3&#8221;出现前的长度*/<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strdup（复制字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; calloc，malloc，realloc，free<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strdup( const char *s);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strdup()会先用maolloc()配置与参数s字符串相同的空间大小，然后将参数s字符串的内容复制到该内存地址，然后把该地址返回。该地址最后可以利用free()来释放。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回一字符串指针，该指针指向复制后的新字符串地址。若返回NULL表示内存不足。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[]="strdup";<br style="line-height: 22px; ">char *b;<br style="line-height: 22px; ">b=strdup(a);<br style="line-height: 22px; ">printf("b[ ]=\"%s\"\n",b);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; b[ ]="strdup"<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strlen（返回字符串长度）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp;&nbsp;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; size_t strlen (const char *s);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strlen()用来计算指定的字符串s的长度，不包括结束字符"\0"。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回字符串s的字符数。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; /*取得字符串str的长度*/<br style="line-height: 22px; ">#include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *str = "12345678";<br style="line-height: 22px; ">printf("str length = %d\n", strlen(str));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; str length = 8<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strncasecmp（忽略大小写比较字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcmp，memcmp，strcmp，strcoll，strncmp<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; int strncasecmp(const char *s1,const char *s2,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strncasecmp()用来比较参数s1和s2字符串前n个字符，比较时会自动忽略大小写的差异。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 若参数s1和s2 字符串相同则返回0。s1 若大于s2则返回大于0的值，s1若小于s2则返回小于0 的值。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *a="aBcDeF";<br style="line-height: 22px; ">char *b="AbCdEf";<br style="line-height: 22px; ">if(!strncasecmp(a,b))<br style="line-height: 22px; ">printf("%s =%s\n",a,b);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; aBcDef=AbCdEf<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strncat（连接两字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memccpy，memecpy，strcpy，strncpy<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #inclue &lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strncat(char *dest,const char *src,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strncat()会将参数src字符串拷贝n个字符到参数dest所指的字符串尾。第一个参数dest要有足够的空间来容纳要拷贝的字符串。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回参数dest的字符串起始地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[30]="string(1)";<br style="line-height: 22px; ">char b[]="string(2)";<br style="line-height: 22px; ">printf("before strnact() :%s\n", a);<br style="line-height: 22px; ">printf("after strncat() :%s\n", strncat(a,b,6));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; before strnact() : string(1)<br style="line-height: 22px; ">after strncat() : string(1) string<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strncpy（拷贝字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; bcopy，memccpy，memcpy，memmove<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strncpy(char *dest,const char *src,size_t n);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strncpy()会将参数src字符串拷贝前n个字符至参数dest所指的地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回参数dest的字符串起始地址。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #inclue &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char a[30]="string(1)";<br style="line-height: 22px; ">char b[]="string(2)";<br style="line-height: 22px; ">printf("before strncpy() : %s\n",a);<br style="line-height: 22px; ">printf("after strncpy() : %s\n",strncpy(a,b,6));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; before strncpy() : string(1)<br style="line-height: 22px; ">after strncpy() : string(1)<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strpbrk（查找字符串中第一个出现的指定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，rindex，strpbrk，strsep，strspn，strstr，strtok<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include &lt;include.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char *strpbrk(const char *s,const char *accept);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strpbrk()用来找出参数s 字符串中最先出现存在参数accept 字符串中的任意字符。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字符则返回该字符所在地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include &lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s="0123456789012345678901234567890";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p=strpbrk(s,"a1 839"); /*1会最先在s字符串中找到*/<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">p=strprk(s,"4398");/*3 会最先在s 字符串中找到*/<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 1.23E+29<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strrchr（查找字符串中最后出现的指定字符）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，rindex，strpbrk，strsep，strspn，strstr，strtok<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strrchr(const char *s, int c);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strrchr()用来找出参数s字符串中最后一个出现的参数c地址，然后将该字符出现的地址返回。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 如果找到指定的字符则返回该字符所在地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *s="0123456789012345678901234567890";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p=strrchr(s,'5');<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 567890<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strspn（返回字符串中连续不含指定字符串内容的字符数）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; strcspn，strchr，strpbrk，strsep，strstr<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; size_t strspn (const char *s,const char * accept);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strspn()从参数s 字符串的开头计算连续的字符，而这些字符都完全是accept 所指字符串中的字符。简单的说，若strspn()返回的数值为n，则代表字符串s 开头连续有n 个字符都是属于字符串accept内的字符。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回字符串s开头连续包含字符串accept内的字符数目。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char *str="Linux was first developed for 386/486-based PCs.";<br style="line-height: 22px; ">char *t1="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";<br style="line-height: 22px; ">printf("%d\n",strspn(str,t1));<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 5 /*计算大小写字母。不包含&#8220; &#8221;，所以返回Linux的长度。*/<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strstr（在一字符串中查找指定的字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，rindex，strchr，strpbrk，strsep，strspn，strtok<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char *strstr(const char *haystack,const char *needle);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strstr()会从字符串haystack 中搜寻字符串needle，并将第一次出现的地址返回。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回指定字符串第一次出现的地址，否则返回0。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char * s="012345678901234567890123456789";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">p= strstr(s,"901");<br style="line-height: 22px; ">printf("%s\n",p);<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; 9.01E+21<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">　</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;</p><p style="line-height: 22px; margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">&nbsp;<br style="line-height: 22px; ">strtok（分割字符串）&nbsp;&nbsp;<br style="line-height: 22px; ">相关函数&nbsp; index，memchr，rindex，strpbrk，strsep，strspn，strstr<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">表头文件&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">定义函数&nbsp; char * strtok(char *s,const char *delim);<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">函数说明&nbsp; strtok()用来将字符串分割成一个个片段。参数s指向欲分割的字符串，参数delim则为分割字符串，当strtok()在参数s的字符串中发现到参数delim的分割字符时则会将该字符改为\0 字符。在第一次调用时，strtok()必需给予参数s字符串，往后的调用则将参数s设置成NULL。每次调用成功则返回下一个分割后的字符串指针。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">返回值&nbsp; 返回下一个分割后的字符串指针，如果已无从分割则返回NULL。<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">范例&nbsp; #include&lt;string.h&gt;<br style="line-height: 22px; ">main()<br style="line-height: 22px; ">{<br style="line-height: 22px; ">char s[]="ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";<br style="line-height: 22px; ">char *delim="-: ";<br style="line-height: 22px; ">char *p;<br style="line-height: 22px; ">printf("%s ";strtok(s,delim));<br style="line-height: 22px; ">while((p=strtok(NULL,delim)))printf("%s ",p);<br style="line-height: 22px; ">printf("\n");<br style="line-height: 22px; ">}<br style="line-height: 22px; ">&nbsp;<br style="line-height: 22px; ">执行&nbsp; ab cd ef;gh i jkl;mnop;qrs tu vwx y;z /*－与:字符已经被\0 字符取代*/</p></span><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-16 22:30 <a href="http://www.cnitblog.com/seedshopezhong/articles/64685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串处理</title><link>http://www.cnitblog.com/seedshopezhong/articles/64684.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Tue, 16 Mar 2010 14:21:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64684.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64684.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64684.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64684.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64684.html</trackback:ping><description><![CDATA[<span  style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 18px; "><strong>atof（将字符串转换成浮点型数）</strong><br>相关函数atoi，atol，strtod，strtol，strtoul<br>表头文件#include &lt;stdlib.h&gt;<br>定义函数double atof(const char *nptr);<br>函数说明atof()会扫描参数nptr字符串，跳过前面的空格字符，直到遇上数<br>字或正负符号才开始做转换，而再遇到非数字或字符串结束时<br>('\0')才结束转换，并将结果返回。参数nptr字符串可包含正负<br>号、小数点或E(e)来表示指数部分，如123.456或123e-2。<br>返回值返回转换后的浮点型数。<br>附加说明atof()与使用strtod(nptr,(char**)NULL)结果相同。<br>范例/* 将字符串a 与字符串b转换成数字后相加*/<br>#include&lt;stdlib.h&gt;<br>main()<br>{<br>char *a=&#8221;-100.23&#8221;;<br>char *b=&#8221;200e-2&#8221;;<br>float c;<br>c=atof(a)+atof(b);<br>printf(&#8220;c=%.2f\n&#8221;,c);<br>}<br>执行c=-98.23<br><strong>atoi（将字符串转换成整型数）</strong><br>相关函数atof，atol，atrtod，strtol，strtoul<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数int atoi(const char *nptr);<br>函数说明atoi()会扫描参数nptr字符串，跳过前面的空格字符，直到遇上数<br>字或正负符号才开始做转换，而再遇到非数字或字符串结束时<br>('\0')才结束转换，并将结果返回。<br>返回值返回转换后的整型数。<br>附加说明atoi()与使用strtol(nptr，(char**)NULL，10)；结果相同。<br>范例/* 将字符串a 与字符串b转换成数字后相加*/<br>#include&lt;stdlib.h&gt;<br>mian()<br>{<br>char a[]=&#8221;-100&#8221;;<br>char b[]=&#8221;456&#8221;;<br>int c;<br>c=atoi(a)+atoi(b);<br>printf(c=%d\n&#8221;,c);<br>}<br>执行c=356<br><strong>atol（将字符串转换成长整型数）</strong><br>相关函数atof，atoi，strtod，strtol，strtoul<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数long atol(const char *nptr);<br>函数说明atol()会扫描参数nptr字符串，跳过前面的空格字符，直到遇上数<br>字或正负符号才开始做转换，而再遇到非数字或字符串结束时<br>('\0')才结束转换，并将结果返回。<br>返回值返回转换后的长整型数。<br>附加说明atol()与使用strtol(nptr,(char**)NULL,10)；结果相同。<br>范例/*将字符串a与字符串b转换成数字后相加*/<br>#include&lt;stdlib.h&gt;<br>main()<br>{<br>char a[]=&#8221;1000000000&#8221;;<br>char b[]=&#8221; 234567890&#8221;;<br>long c;<br>c=atol(a)+atol(b);<br>printf(&#8220;c=%d\n&#8221;,c);<br>}<br>执行c=1234567890<br><strong>gcvt（将浮点型数转换为字符串，取四舍五入）</strong><br>相关函数ecvt，fcvt，sprintf<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数char *gcvt(double number，size_t ndigits，char *buf);<br>函数说明gcvt()用来将参数number转换成ASCII码字符串，参数ndigits表示<br>显示的位数。gcvt()与ecvt()和fcvt()不同的地方在于，gcvt()所<br>转换后的字符串包含小数点或正负符号。若转换成功，转换后的字<br>符串会放在参数buf指针所指的空间。<br>返回值返回一字符串指针，此地址即为buf指针。<br>附加说明<br>范例#include&lt;stdlib.h&gt;<br>main()<br>{<br>double a=123.45;<br>double b=-1234.56;<br>char *ptr;<br>int decpt,sign;<br>gcvt(a,5,ptr);<br>printf(&#8220;a value=%s\n&#8221;,ptr);<br>ptr=gcvt(b,6,ptr);<br>printf(&#8220;b value=%s\n&#8221;,ptr);<br>}<br>执行a value=123.45<br>b value=-1234.56<br><strong>strtod（将字符串转换成浮点数）</strong><br>相关函数atoi，atol，strtod，strtol，strtoul<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数double strtod(const char *nptr,char **endptr);<br>函数说明strtod()会扫描参数nptr字符串，跳过前面的空格字符，直到遇上<br>数字或正负符号才开始做转换，到出现非数字或字符串结束时<br>('\0')才结束转换，并将结果返回。若endptr不为NULL，则会将遇<br>到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字<br>符串可包含正负号、小数点或E(e)来表示指数部分。如123.456或<br>123e-2。<br>返回值返回转换后的浮点型数。<br>附加说明参考atof()。<br>范例/*将字符串a，b，c 分别采用10，2，16 进制转换成数字*/<br>#include&lt;stdlib.h&gt;<br>mian()<br>{<br>char a[]=&#8221;1000000000&#8221;;<br>char b[]=&#8221;1000000000&#8221;;<br>char c[]=&#8221;ffff&#8221;;<br>printf(&#8220;a=%d\n&#8221;,strtod(a,NULL,10));<br>printf(&#8220;b=%d\n&#8221;,strtod(b,NULL,2));<br>printf(&#8220;c=%d\n&#8221;,strtod(c,NULL,16));<br>}<br>执行a=1000000000<br>b=512<br>c=65535<br><strong>strtol（将字符串转换成长整型数）</strong><br>相关函数atof，atoi，atol，strtod，strtoul<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数long int strtol(const char *nptr,char **endptr,int base);<br>函数说明strtol()会将参数nptr字符串根据参数base来转换成长整型数。参<br>数base范围从2至36，或0。参数base代表采用的进制方式，如base<br>值为10则采用10进制，若base值为16则采用16进制等。当base值为0<br>时则是采用10进制做转换，但遇到如'0x'前置字符则会使用16进制<br>做转换。一开始strtol()会扫描参数nptr字符串，跳过前面的空格<br>字符，直到遇上数字或正负符号才开始做转换，再遇到非数字或字<br>符串结束时('\0')结束转换，并将结果返回。若参数endptr不为<br>NULL，则会将遇到不合条件而终止的nptr中的字符指针由endptr返<br>回。<br>返回值返回转换后的长整型数，否则返回ERANGE并将错误代码存入errno<br>中。<br>附加说明ERANGE指定的转换字符串超出合法范围。<br>范例/* 将字符串a，b，c 分别采用10，2，16进制转换成数字*/<br>#include&lt;stdlib.h&gt;<br>main()<br>{<br>char a[]=&#8221;1000000000&#8221;;<br>char b[]=&#8221;1000000000&#8221;;<br>char c[]=&#8221;ffff&#8221;;<br>printf(&#8220;a=%d\n&#8221;,strtol(a,NULL,10));<br>printf(&#8220;b=%d\n&#8221;,strtol(b,NULL,2));<br>printf(&#8220;c=%d\n&#8221;,strtol(c,NULL,16));<br>}<br>执行a=1000000000<br>b=512<br>c=65535<br><strong>strtoul（将字符串转换成无符号长整型数）</strong><br>相关函数atof，atoi，atol，strtod，strtol<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数unsigned long int strtoul(const char *nptr,char<br>**endptr,int base);<br>函数说明strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整<br>型数。参数base范围从2至36，或0。参数base代表采用的进制方<br>式，如base值为10则采用10进制，若base值为16则采用16进制数<br>等。当base值为0时则是采用10进制做转换，但遇到如'0x'前置字符<br>则会使用16进制做转换。一开始strtoul()会扫描参数nptr字符串，<br>跳过前面的空格字符串，直到遇上数字或正负符号才开始做转换，<br>再遇到非数字或字符串结束时('\0')结束转换，并将结果返回。若<br>参数endptr不为NULL，则会将遇到不合条件而终止的nptr中的字符<br>指针由endptr返回。<br>返回值返回转换后的长整型数，否则返回ERANGE并将错误代码存入errno<br>中。<br>附加说明ERANGE指定的转换字符串超出合法范围。<br>范例参考strtol()<br><strong>toascii（将整型数转换成合法的ASCII 码字符）</strong><br>相关函数isascii，toupper，tolower<br>表头文件#include&lt;ctype.h&gt;<br>定义函数int toascii(int c)<br>函数说明toascii()会将参数c转换成7位的unsigned char值，第八位则会被<br>清除，此字符即会被转成ASCII码字符。<br>返回值将转换成功的ASCII码字符值返回。<br>范例#include&lt;stdlib.h&gt;<br>main()<br>{<br>int a=217;<br>char b;<br>printf(&#8220;before toascii () : a value =%d(%c)\n&#8221;,a,a);<br>b=toascii(a);<br>printf(&#8220;after toascii() : a value =%d(%c)\n&#8221;,b,b);<br>}<br>执行before toascii() : a value =217()<br>after toascii() : a value =89(Y)<br><strong>tolower（将大写字母转换成小写字母）</strong><br>相关函数isalpha，toupper<br>表头文件#include&lt;stdlib.h&gt;<br>定义函数int tolower(int c);<br>函数说明若参数c为大写字母则将该对应的小写字母返回。<br>返回值返回转换后的小写字母，若不须转换则将参数c值返回。<br>附加说明<br>范例/* 将s字符串内的大写字母转换成小写字母*/<br>#include&lt;ctype.h&gt;<br>main()<br>{<br>char s[]=&#8221;aBcDeFgH12345;!#$&#8221;;<br>int i;<br>printf(&#8220;before tolower() : %s\n&#8221;,s);<br>for(i=0;I&lt;sizeof(s);i++)<br>s[i]=tolower(s[i]);<br>printf(&#8220;after tolower() : %s\n&#8221;,s);<br>}<br>执行before tolower() : aBcDeFgH12345;!#$<br>after tolower() : abcdefgh12345;!#$<br><strong>toupper（将小写字母转换成大写字母）<br></strong>相关函数isalpha，tolower<br>表头文件#include&lt;ctype.h&gt;<br>定义函数int toupper(int c);<br>函数说明若参数c为小写字母则将该对映的大写字母返回。<br>返回值返回转换后的大写字母，若不须转换则将参数c值返回。<br>附加说明<br>范例/* 将s字符串内的小写字母转换成大写字母*/<br>#include&lt;ctype.h&gt;<br>main()<br>{<br>char s[]=&#8221;aBcDeFgH12345;!#$&#8221;;<br>int i;<br>printf(&#8220;before toupper() : %s\n&#8221;,s);<br>for(i=0;I&lt;sizeof(s);i++)<br>s[i]=toupper(s[i]);<br>printf(&#8220;after toupper() : %s\n&#8221;,s);<br>}<br>执行before toupper() : aBcDeFgH12345;!#$<br>after toupper() : ABCDEFGH12345;!#$</span>
<img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64684.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-16 22:21 <a href="http://www.cnitblog.com/seedshopezhong/articles/64684.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c语言中static 用法总结</title><link>http://www.cnitblog.com/seedshopezhong/articles/64660.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Mon, 15 Mar 2010 15:50:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64660.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64660.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64660.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64660.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64660.html</trackback:ping><description><![CDATA[
<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 13px; line-height: 20px; -webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; "><strong style="line-height: normal; ">一、c程序</strong><strong style="line-height: normal; ">存储</strong><strong style="line-height: normal; ">空间布局</strong><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; C程序一直由下列部分组成：</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 1）正文段——CPU执行的机器指令部分；一个程序只有一个副本；只读，防止程序由于意外事故而修改自身指令；</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 2）初始化数据段（数据段）——在程序中所有赋了初值的全局变量，存放在这里。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 3）非初始化数据段（bss段）——在程序中没有初始化的全局变量；内核将此段初始化为0.</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 4）栈——增长方向：自顶向下增长；自动变量以及每次函数调用时所需要保存的信息（返回地址；环境信息）。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 5）堆——动态存储部分。<br style="line-height: normal; "><br style="line-height: normal; "><font color="#ff0000" style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp; 栈&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp; \|/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp; /|\&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp;&nbsp; 堆&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">| 未初始化&nbsp;&nbsp; |<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp;&nbsp; 初始化&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; (.data)<br style="line-height: normal; ">|-----------|<br style="line-height: normal; ">|&nbsp;&nbsp; 正文段&nbsp;&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; (.text)<br style="line-height: normal; ">|-----------|</font><br style="line-height: normal; "><br style="line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;<strong style="line-height: normal; ">二、 面向过程程序设计中的static</strong></p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 1. 全局静态变量</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 在全局变量之前加上关键字static，全局变量就被定义成为一个全局静态变量。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 1）内存中的位置：静态存储区（静态存储区在整个程序运行期间都存在）</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 2）初始化：未经初始化的全局静态变量会被程序自动初始化为0（自动对象的值是任意的，除非他被显示初始化）</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 3）作用域：全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 看下面关于作用域的程序：<br style="line-height: normal; "><table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2" style="table-layout: auto; line-height: normal; "><tbody style="line-height: normal; "><tr style="line-height: normal; "><td style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; "><p style="line-height: normal; ">//teststatic1.c<br style="line-height: normal; ">void display();<br style="line-height: normal; ">extern int n;<br style="line-height: normal; ">int main()<br style="line-height: normal; ">{<br style="line-height: normal; ">&nbsp;&nbsp; n = 20;<br style="line-height: normal; ">&nbsp;&nbsp; printf("%d\n",n);<br style="line-height: normal; ">&nbsp;&nbsp; display();<br style="line-height: normal; ">&nbsp;&nbsp; return 0;<br style="line-height: normal; ">}</p><p style="line-height: normal; ">//teststatic2.c<br style="line-height: normal; ">static int n;&nbsp;&nbsp;&nbsp; //定义全局静态变量，自动初始化为0，仅在本文件中可见<br style="line-height: normal; ">void display()<br style="line-height: normal; ">{<br style="line-height: normal; ">&nbsp;&nbsp; n++;<br style="line-height: normal; ">&nbsp;&nbsp; printf("%d\n",n);<br style="line-height: normal; ">}</p></td></tr></tbody></table></p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 文件分别编译通过，但link的时候teststatic1.c中的变量n找不到定义，产生错误。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 定义全局静态变量的好处：</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; &lt;1&gt;不会被其他文件所访问，修改</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; &lt;2&gt;其他文件中可以使用相同名字的变量，不会发生冲突。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 2. 局部静态变量</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 在局部变量之前加上关键字static，局部变量就被定义成为一个局部静态变量。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 1）内存中的位置：静态存储区</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 2）初始化：未经初始化的全局静态变量会被程序自动初始化为0（自动对象的值是任意的，除非他被显示初始化）</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 3）作用域：作用域仍为局部作用域，当定义它的函数或者语句块结束的时候，作用域随之结束。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 注：当static用来修饰局部变量的时候，它就改变了局部变量的存储位置，从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后，并没有被销毁，而是仍然驻留在内存当中，直到程序结束，只不过我们不能再对他进行访问。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 当static用来修饰全局变量的时候，它就改变了全局变量的作用域（在声明他的文件之外是不可见的），但是没有改变它的存放位置，还是在静态存储区中。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 3. 静态函数</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 在函数的返回类型前加上关键字static，函数就被定义成为静态函数。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 函数的定义和声明默认情况下是extern的，但静态函数只是在声明他的文件当中可见，不能被其他文件所用。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 例如：<br style="line-height: normal; "><table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2" style="table-layout: auto; line-height: normal; "><tbody style="line-height: normal; "><tr style="line-height: normal; "><td style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; "><p style="line-height: normal; ">//teststatic1.c<br style="line-height: normal; ">void display();<br style="line-height: normal; ">static void staticdis();<br style="line-height: normal; ">int main()<br style="line-height: normal; ">{<br style="line-height: normal; ">&nbsp;&nbsp; display();<br style="line-height: normal; ">&nbsp;&nbsp; staticdis();<br style="line-height: normal; ">&nbsp;&nbsp; renturn 0;<br style="line-height: normal; ">}</p><p style="line-height: normal; ">//teststatic2.c<br style="line-height: normal; ">void display()<br style="line-height: normal; ">{<br style="line-height: normal; ">&nbsp;&nbsp; staticdis();<br style="line-height: normal; ">&nbsp;&nbsp; printf("display() has been called \n");<br style="line-height: normal; ">}</p><p style="line-height: normal; ">static void staticdis()<br style="line-height: normal; ">{<br style="line-height: normal; ">&nbsp;&nbsp; printf("staticDis() has been called\n");<br style="line-height: normal; ">}</p></td></tr></tbody></table></p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 文件分别编译通过，但是连接的时候找不到函数staticdis（）的定义，产生错误。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 定义静态函数的好处：</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; &lt;1&gt; 其他文件中可以定义相同名字的函数，不会发生冲突</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; &lt;2&gt; 静态函数不能被其他文件所用。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 存储说明符auto，register，extern，static，对应两种存储期：自动存储期和静态存储期。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立，它在该程序块活动时存在，退出该程序块时撤销。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期（static storage duration），或静态范围（static extent）。虽然他的值在函数调用之间保持有效，但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 由于static变量的以上特性，可实现一些特定功能。</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 1. 统计次数功能</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 声明函数的一个局部变量，并设为static类型，作为一个计数器，这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法，因为这个变量是和函数息息相关的，而函数可能在多个不同的地方被调用，所以从调用者的角度来统计比较困难。代码如下：<br style="line-height: normal; "><table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2" style="table-layout: auto; line-height: normal; "><tbody style="line-height: normal; "><tr style="line-height: normal; "><td style="font-family: Arial; word-wrap: break-word; word-break: break-all; visibility: visible !important; zoom: 1 !important; filter: none; font-size: 12px; line-height: normal; ">void count();<br style="line-height: normal; ">int main()<br style="line-height: normal; ">{<br style="line-height: normal; ">int i;<br style="line-height: normal; ">for (i = 1; i &lt;= 3; i++)<br style="line-height: normal; ">&nbsp;&nbsp; count();<br style="line-height: normal; ">&nbsp;&nbsp; return 0;<br style="line-height: normal; ">}<br style="line-height: normal; ">void count()<br style="line-height: normal; ">{<br style="line-height: normal; ">static num = 0;<br style="line-height: normal; ">num++;<br style="line-height: normal; ">printf(" I have been called %d",num,"times\n");<br style="line-height: normal; ">}</td></tr></tbody></table></p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; 输出结果为：</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; I have been called 1 times.</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; I have been called 2 times.</p><p style="line-height: normal; ">&nbsp;&nbsp;&nbsp; I have been called 3 times.</p><p style="line-height: normal; ">转载来自:<span style="line-height: 20px; "><a href="http://hi.baidu.com/embedtec/blog/item/fe1f3cdccac337abcd116694.html">http://hi.baidu.com/embedtec/blog/item/fe1f3cdccac337abcd116694.html</a></span></p></span><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64660.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-15 23:50 <a href="http://www.cnitblog.com/seedshopezhong/articles/64660.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>extern用法详解</title><link>http://www.cnitblog.com/seedshopezhong/articles/64659.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Mon, 15 Mar 2010 15:43:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64659.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64659.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64659.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64659.html</trackback:ping><description><![CDATA[<span  style="border-collapse: collapse; font-family: song, Verdana; font-size: 12px; "><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; "><strong>1 基本解释<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; "></strong>　　extern可以置于变量或者<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>前，以标示变量或者<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的定义在别的文件中，提示编译器遇到此变量和<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>时在其他模块中寻找其定义。<br style="font: normal normal normal 12px/normal song, Verdana; "><br></span></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; ">　　另外，extern也可用来进行链接指定。</span></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; "><strong>2 问题：extern 变量</strong><br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　在一个源文件里定义了一个数组：char a[6];<br style="font: normal normal normal 12px/normal song, Verdana; ">　　在另外一个文件里用下列语句进行了声明：extern char *a；<br style="font: normal normal normal 12px/normal song, Verdana; ">　　请问，这样可以吗？</span></p><span style="font-size: 12px; "><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　答案与分析：<br style="font: normal normal normal 12px/normal song, Verdana; ">　　1)、不可以，程序运行时会告诉你非法访问。原因在于，指向类型T的<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%D6%B8%D5%EB&amp;Submit=+%CB%D1%CB%F7+" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">指针</font></a>并不等价于类型T的数组。extern char *a声明的是一个<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%D6%B8%D5%EB&amp;Submit=+%CB%D1%CB%F7+" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">指针</font></a>变量而不是字符数组，因此与实际的定义不同，从而造成运行时非法访问。应该将声明改为extern char a[ ]。<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　2)、例子分析如下，如果a[] = "abcd",则外部变量a=0x61626364 (abcd的ASCII码值)，*a显然没有意义<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　显然a指向的空间（0x61626364）没有意义，易出现非法内存访问。<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　3)、这提示我们，在使用extern时候要严格对应声明时的格式，在实际编程中，这样的错误屡见不鲜。<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　4)、extern用在变量声明中常常有这样一个作用，你在*.c文件中声明了一个全局的变量，这个全局的变量如果要被引用，就放在*.h中并用extern来声明。<br style="font: normal normal normal 12px/normal song, Verdana; "></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; "><strong>3 问题：extern&nbsp;<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>1</strong><br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　常常见extern放在<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的前面成为<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>声明的一部分，那么，<a href="http://www.bc-cn.net/Article/kfyy/cyy/Index.html" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">C语言</font></a>的关键字extern在<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的声明中起什么作用？<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　答案与分析：<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　如果<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的声明中带有关键字extern，仅仅是暗示这个<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>可能在别的源文件里定义，没有其它作用。即下述两个<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>声明没有明显的区别：<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">extern int f(); 和int f();<br style="font: normal normal normal 12px/normal song, Verdana; ">　　当然，这样的用处还是有的，就是在程序中取代include &#8220;*.h&#8221;来声明<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>，在一些复杂的项目中，我比较习惯在所有的<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>声明前添加extern修饰。</span><br style="font: normal normal normal 12px/normal song, Verdana; "></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; "><strong>4 问题：extern&nbsp;<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>2</strong><br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　当<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>提供方单方面修改<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>原型时，如果使用方不知情继续沿用原来的extern申明，这样编译时编译器不会报错。但是在运行过程中，因为少了或者多了输入参数，往往会照成系统错误，这种情况应该如何解决？<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　答案与分析：<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　目前业界针对这种情况的处理没有一个很完美的方案，通常的做法是提供方在自己的xxx_pub.h中提供对外部<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BD%D3%BF%DA" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">接口</font></a>的声明，然后调用方include该头文件，从而省去extern这一步。以避免这种错误。<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　宝剑有双锋，对extern的应用，不同的场合应该选择不同的做法。</span></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><span style="font-size: 12px; "><strong>5 问题：extern &#8220;C&#8221;</strong><br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　在<a href="http://www.bc-cn.net/Article/kfyy/cjj/Index.html" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">C++</font></a>环境下使用C<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的时候，常常会出现编译器无法找到obj模块中的C<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>定义，从而导致链接失败的情况，应该如何解决这种情况呢？<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　答案与分析：<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　<a href="http://www.bc-cn.net/Article/kfyy/cjj/Index.html" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">C++</font></a>语言在编译的时候为了解决<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的多态问题，会将<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>名和参数联合起来生成一个中间的<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>名称，而<a href="http://www.bc-cn.net/Article/kfyy/cyy/Index.html" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">C语言</font></a>则不会，因此会造成链接时找不到对应<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>的情况，此时C<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>就需要用extern &#8220;C&#8221;进行链接指定，这告诉编译器，请保持我的名称，不要给我生成用于链接的中间<a href="http://www.bc-cn.net/Article/Search.asp?Field=Title&amp;ClassID=&amp;keyword=%BA%AF%CA%FD" target="_blank" style="color: rgb(0, 68, 182); text-decoration: underline; "><font color="#000000">函数</font></a>名。<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">　　下面是一个标准的写法：<br style="font: normal normal normal 12px/normal song, Verdana; "><br style="font: normal normal normal 12px/normal song, Verdana; ">//在.h文件的头上<br style="font: normal normal normal 12px/normal song, Verdana; ">#ifdef __cplusplus<br style="font: normal normal normal 12px/normal song, Verdana; ">#if __cplusplus<br style="font: normal normal normal 12px/normal song, Verdana; ">extern "C"{<br style="font: normal normal normal 12px/normal song, Verdana; ">　#endif<br style="font: normal normal normal 12px/normal song, Verdana; ">　#endif /* __cplusplus */&nbsp;<br style="font: normal normal normal 12px/normal song, Verdana; ">　&#8230;<br style="font: normal normal normal 12px/normal song, Verdana; ">　&#8230;<br style="font: normal normal normal 12px/normal song, Verdana; ">　//.h文件结束的地方<br style="font: normal normal normal 12px/normal song, Verdana; ">　#ifdef __cplusplus<br style="font: normal normal normal 12px/normal song, Verdana; ">　#if __cplusplus<br style="font: normal normal normal 12px/normal song, Verdana; ">}<br style="font: normal normal normal 12px/normal song, Verdana; ">#endif<br style="font: normal normal normal 12px/normal song, Verdana; ">#endif /* __cplusplus */</span>&nbsp;</p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><br></p><p style="padding-right: 0px; padding-left: 0px; padding-bottom: 6px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 6px; font: normal normal normal 12px/normal song, Verdana; "><font color="#000099"><strong>原文地址</strong></font>&nbsp;<a href="http://blog.chinaunix.net/u1/40028/showart_461654.html" target="_blank" style="text-decoration: underline; color: rgb(0, 68, 182); ">http://blog.chinaunix.net/u1/40028/showart_461654.html</a></p></span></span>
<img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-15 23:43 <a href="http://www.cnitblog.com/seedshopezhong/articles/64659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>typedef的用法</title><link>http://www.cnitblog.com/seedshopezhong/articles/64658.html</link><dc:creator>seedshopezhong</dc:creator><author>seedshopezhong</author><pubDate>Mon, 15 Mar 2010 15:40:00 GMT</pubDate><guid>http://www.cnitblog.com/seedshopezhong/articles/64658.html</guid><wfw:comment>http://www.cnitblog.com/seedshopezhong/comments/64658.html</wfw:comment><comments>http://www.cnitblog.com/seedshopezhong/articles/64658.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/seedshopezhong/comments/commentRss/64658.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/seedshopezhong/services/trackbacks/64658.html</trackback:ping><description><![CDATA[<span style="border-collapse: collapse; font-family: song,Verdana; font-size: 12px;">注：typedf的使用方法！转载自百度百科！<br style="font: 12px song,Verdana;"><br style="font: 12px song,Verdana;">C语言中typedef用法<br style="font: 12px song,Verdana;">1. 基本解释<br style="font: 12px song,Verdana;">　　typedef为C语言的关键字，作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型（int,char等）和自定义的数据类型（struct等）。<br style="font: 12px song,Verdana;">　　在编程中使用typedef目的一般有两个，一个是给变量一个易记且意义明确的新名字，另一个是简化一些比较复杂的类型声明。<br style="font: 12px song,Verdana;">　　至于typedef有什么微妙之处，请你接着看下面对几个问题的具体阐述。<br style="font: 12px song,Verdana;">2. typedef &amp; 结构的问题<br style="font: 12px song,Verdana;">　　当用下面的代码定义一个结构时，编译器报了一个错误，为什么呢？莫非C语言不允许在结构中包含指向它自己的指针吗？请你先猜想一下，然后看下文说明：<br style="font: 12px song,Verdana;">typedef struct tagNode<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　char *pItem;<br style="font: 12px song,Verdana;">　pNode pNext;<br style="font: 12px song,Verdana;">} *pNode;<br><br style="font: 12px song,Verdana;">答案与分析：<br style="font: 12px song,Verdana;">1、typedef的最简单使用<br style="font: 12px song,Verdana;">typedef long byte_4;<br style="font: 12px song,Verdana;">给已知数据类型long起个新名字，叫byte_4。<br><br style="font: 12px song,Verdana;">2、 typedef与结构结合使用<br style="font: 12px song,Verdana;">typedef struct tagMyStruct<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　int iNum;<br style="font: 12px song,Verdana;">　long lLength;<br style="font: 12px song,Verdana;">} MyStruct;<br style="font: 12px song,Verdana;">这语句实际上完成两个操作：<br style="font: 12px song,Verdana;">1) 定义一个新的结构类型<br style="font: 12px song,Verdana;">struct tagMyStruct<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　int iNum;<br style="font: 12px song,Verdana;">　long lLength;<br style="font: 12px song,Verdana;">};<br style="font: 12px song,Verdana;">分析：tagMyStruct称为&#8220;tag&#8221;，即&#8220;标签&#8221;，实际上是一个临时名字，struct 关键字和tagMyStruct一起，构成了这个结构类型，不论是否有typedef，这个结构都存在。<br style="font: 12px song,Verdana;">我们可以用struct tagMyStruct varName来定义变量，但要注意，使用tagMyStruct varName来定义变量是不对的，因为struct 和tagMyStruct合在一起才能表示一个结构类型。<br style="font: 12px song,Verdana;">2) typedef为这个新的结构起了一个名字，叫MyStruct。<br style="font: 12px song,Verdana;">typedef struct tagMyStruct MyStruct;<br style="font: 12px song,Verdana;">因此，MyStruct实际上相当于struct tagMyStruct，我们可以使用MyStruct varName来定义变量。<br style="font: 12px song,Verdana;">答案与分析<br style="font: 12px song,Verdana;">C语言当然允许在结构中包含指向它自己的指针，我们可以在建立链表等数据结构的实现上看到无数这样的例子，上述代码的根本问题在于typedef的应用。<br style="font: 12px song,Verdana;">根据我们上面的阐述可以知道：新结构建立的过程中遇到了pNext域的声明，类型是pNode，要知道pNode表示的是类型的新名字，那么在类型本身还没有建立完成的时候，这个类型的新名字也还不存在，也就是说这个时候编译器根本不认识pNode。<br style="font: 12px song,Verdana;">解决这个问题的方法有多种：<br style="font: 12px song,Verdana;">1)、<br style="font: 12px song,Verdana;">typedef struct tagNode<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　char *pItem;<br style="font: 12px song,Verdana;">　struct tagNode *pNext;<br style="font: 12px song,Verdana;">} *pNode;<br style="font: 12px song,Verdana;">2)、<br style="font: 12px song,Verdana;">typedef struct tagNode *pNode;<br style="font: 12px song,Verdana;">struct tagNode<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　char *pItem;<br style="font: 12px song,Verdana;">　pNode pNext;<br style="font: 12px song,Verdana;">};<br style="font: 12px song,Verdana;">注意：在这个例子中，你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。<br style="font: 12px song,Verdana;">3)、规范做法：<br style="font: 12px song,Verdana;">struct tagNode<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　char *pItem;<br style="font: 12px song,Verdana;">　struct tagNode *pNext;<br style="font: 12px song,Verdana;">};<br style="font: 12px song,Verdana;">typedef struct tagNode *pNode;<br style="font: 12px song,Verdana;">3. typedef &amp; #define的问题<br style="font: 12px song,Verdana;">有下面两种定义pStr数据类型的方法，两者有什么不同？哪一种更好一点？<br style="font: 12px song,Verdana;">typedef char *pStr;<br style="font: 12px song,Verdana;">#define pStr char *;<br style="font: 12px song,Verdana;">　　答案与分析：<br style="font: 12px song,Verdana;">　　通常讲，typedef要比#define要好，特别是在有指针的场合。请看例子：<br style="font: 12px song,Verdana;">typedef char *pStr1;<br style="font: 12px song,Verdana;">#define pStr2 char *;<br style="font: 12px song,Verdana;">pStr1 s1, s2;<br style="font: 12px song,Verdana;">pStr2 s3, s4;<br style="font: 12px song,Verdana;">在上述的变量定义中，s1、s2、s3都被定义为char *，而s4则定义成了char，不是我们所预期的指针变量，根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。<br style="font: 12px song,Verdana;">#define用法例子：<br style="font: 12px song,Verdana;">#define f(x) x*x<br style="font: 12px song,Verdana;">main( )<br style="font: 12px song,Verdana;">{<br style="font: 12px song,Verdana;">　int a=6，b=2，c；<br style="font: 12px song,Verdana;">　c=f(a) / f(b)；<br style="font: 12px song,Verdana;">　printf("%d \\n"，c)；<br style="font: 12px song,Verdana;">}<br style="font: 12px song,Verdana;">以下程序的输出结果是: 36。<br style="font: 12px song,Verdana;">因为如此原因，在许多C语言编程规范中提到使用#define定义时，如果定义中包含表达式，必须使用括号，则上述定义应该如下定义才对：<br style="font: 12px song,Verdana;">#define f(x) (x*x)<br style="font: 12px song,Verdana;">当然，如果你使用typedef就没有这样的问题。<br style="font: 12px song,Verdana;">4. typedef &amp; #define的另一例<br style="font: 12px song,Verdana;">下面的代码中编译器会报一个错误，你知道是哪个语句错了吗？<br style="font: 12px song,Verdana;">typedef char * pStr;<br style="font: 12px song,Verdana;">char string[4] = "abc";<br style="font: 12px song,Verdana;">const char *p1 = string;<br style="font: 12px song,Verdana;">const pStr p2 = string;<br style="font: 12px song,Verdana;">p1++;<br style="font: 12px song,Verdana;">p2++;<br style="font: 12px song,Verdana;">答案与分析：<br style="font: 12px song,Verdana;">是p2++出错了。这个问题再一次提醒我们：typedef和#define不同，它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别，都是对变量进行只读限制，只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此，const pStr p2的含义是：限定数据类型为char *的变量p2为只读，因此p2++错误。<br style="font: 12px song,Verdana;">#define与typedef引申谈<br style="font: 12px song,Verdana;">1) #define宏定义有一个特别的长处：可以使用 #ifdef ,#ifndef等来进行逻辑判断，还可以使用#undef来取消定义。<br style="font: 12px song,Verdana;">2) typedef也有一个特别的长处：它符合范围规则，使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内（取决于此变量定义的位置），而宏定义则没有这种特性。<br style="font: 12px song,Verdana;">5. typedef &amp; 复杂的变量声明<br style="font: 12px song,Verdana;">在编程实践中，尤其是看别人代码的时候，常常会遇到比较复杂的变量声明,使用typedef作简化自有其价值，比如：<br style="font: 12px song,Verdana;">下面是三个变量的声明，我想使用typdef分别给它们定义一个别名，请问该如何做？<br style="font: 12px song,Verdana;">1：int *(*a[5])(int, char*);<br style="font: 12px song,Verdana;">2：void (*b[10]) (void (*)());<br style="font: 12px song,Verdana;">3. doube(*)() (*pa)[9];<br style="font: 12px song,Verdana;">答案与分析：<br style="font: 12px song,Verdana;">对复杂变量建立一个类型别名的方法很简单，你只要在传统的变量声明表达式里用类型名替代变量名，然后把关键字typedef加在该语句的开头就行了。<br style="font: 12px song,Verdana;">1：int *(*a[5])(int, char*);<br style="font: 12px song,Verdana;">//pFun是我们建的一个类型别名<br style="font: 12px song,Verdana;">typedef int *(*pFun)(int, char*);<br style="font: 12px song,Verdana;">//使用定义的新类型来声明对象，等价于int* (*a[5])(int, char*);<br style="font: 12px song,Verdana;">pFun a[5];<br style="font: 12px song,Verdana;">2：void (*b[10]) (void (*)());<br style="font: 12px song,Verdana;">//首先为上面表达式蓝色部分声明一个新类型<br style="font: 12px song,Verdana;">typedef void (*pFunParam)();<br style="font: 12px song,Verdana;">//整体声明一个新类型<br style="font: 12px song,Verdana;">typedef void (*pFun)(pFunParam);<br style="font: 12px song,Verdana;">//使用定义的新类型来声明对象，等价于void (*b[10]) (void (*)());<br style="font: 12px song,Verdana;">pFun b[10];<br style="font: 12px song,Verdana;">3. doube(*)() (*pa)[9];<br style="font: 12px song,Verdana;">//首先为上面表达式蓝色部分声明一个新类型<br style="font: 12px song,Verdana;">typedef double(*pFun)();<br style="font: 12px song,Verdana;">//整体声明一个新类型<br style="font: 12px song,Verdana;">typedef pFun (*pFunParam)[9];<br style="font: 12px song,Verdana;">//使用定义的新类型来声明对象，等价于doube(*)() (*pa)[9];<br style="font: 12px song,Verdana;">pFunParam pa;</span><img src ="http://www.cnitblog.com/seedshopezhong/aggbug/64658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/seedshopezhong/" target="_blank">seedshopezhong</a> 2010-03-15 23:40 <a href="http://www.cnitblog.com/seedshopezhong/articles/64658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>