﻿<?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博客-yunshichen-随笔分类-C/C++ </title><link>http://www.cnitblog.com/yunshichen/category/7106.html</link><description>我相信人生是值得活的,尽管人在一生中必须遭受痛苦,卑劣,残酷,不幸和死亡的折磨,我依然深信如此.但我认为人生不一定要有意义,只是对一些人而言,他们可以使人生有意义.  ---J 赫胥黎</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 14:16:27 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 14:16:27 GMT</pubDate><ttl>60</ttl><item><title>Ubuntu下动态共享库(so)开发精悍教程</title><link>http://www.cnitblog.com/yunshichen/archive/2009/08/28/61065.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Fri, 28 Aug 2009 13:50:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2009/08/28/61065.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/61065.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2009/08/28/61065.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/61065.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/61065.html</trackback:ping><description><![CDATA[
		<br />在网上找到一篇很棒的文章: <a target="_blank" title="http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html" href="http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html">http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html</a><br /><br />翻译并根据实际情况进行了小小修改,仅关注Linux下动态共享库(Dynamic shared library .so)的开发.<br /><br /><h1><b><font color="#006600">1 简单的so实例</font></b></h1><h2><font color="#006600">源文件</font></h2>//test1.c<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test1(){<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br />//test2.c<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test2(){<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br />//mytest.c<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test1();<br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test2();<br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(){<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">result of test1:= %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,test1());<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">result of test2:= %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,test2());<br />}</span></div><br /><h2><font color="#006600">打包成so文件</font></h2>在代码的目录下运行如下命令: (如果你不是Ubuntu系统,请将命令的sudo都去掉)<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">gcc -Wall -fPIC -c *.c<br />gcc -shared -Wl</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">-soname</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">libctest.so</span><span style="color: rgb(0, 0, 0);">.1</span><span style="color: rgb(0, 0, 0);"> -o libctest.so</span><span style="color: rgb(0, 0, 0);">.1.0</span><span style="color: rgb(0, 0, 0);">   *.o<br />sudo mv libctest.so</span><span style="color: rgb(0, 0, 0);">.1.0</span><span style="color: rgb(0, 0, 0);"> /usr/lib<br />sudo ln -sf /usr/lib/libctest.so</span><span style="color: rgb(0, 0, 0);">.1.0</span><span style="color: rgb(0, 0, 0);"> /usr/lib/libctest.so<br />sudo ln -sf /usr/lib/libctest.so</span><span style="color: rgb(0, 0, 0);">.1.0</span><span style="color: rgb(0, 0, 0);"> /usr/lib/libctest.so</span><span style="color: rgb(0, 0, 0);">.1</span></div><br />参数详解:<br /><ul><li>-Wall: 包含warning信息</li><li>-fPIC: 编译动态库必须,输出不依赖位置的代码(原文 :Compiler directive to output position independent code)</li><li><tt>-shared</tt>: 编译动态库必需选项</li><li><tt>-W1</tt>: 向链接器(Linker)传递一些参数.在这里传递的参数有
        "<tt>-soname libctest.so.1</tt>"</li><li>-o: 动态库的名字. 在这个例子里最终生成动态库 libctest.so.1.0</li></ul>两个符号链接的含义:<br /><ul><li>第一个:允许应用代码用 -lctest 的语法进行编译.</li><li>第二个:允许应用程序在运行时调用动态库.</li></ul><br /><h1><b><font><b><font color="#006600">2 so路径设置</font></b></font></b></h1>为了使应用程序能够在运行时加载动态库,可以通过3种方式指定动态库的路径(以下例子均假定/opt/lib是动态库所在位置):<br /><br /><h2><font><font color="#006600">用ldconfig指定路径</font></font></h2>运行 <br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">sudo ldconfig -n /opt/lib</span></div><br />/opt/lib 是动态库所在路径.  这种方式简单快捷,便于程序员开发.缺点是重启后即失效.<br /><h2><font><font><font><font color="#006600">修改/etc/ld.so.conf文件</font></font></font></font></h2>打开/etc/ld.so.confg 文件,并将/opt/lib 添加进去. <br /><br />(<b><font color="#000000">注: 在Ubuntu系统中</font></b>, 所有so.conf文件都在/etc/ld.so.conf.d目录. 你可以仿照该目录下的.conf文件写一个libctest.conf并将/opt/lib填入)<br /><h2><font><font><font><font color="#006600">用环境变量LD_LIBRARY_PATH指定路径</font></font></font></font></h2>环境变量的名字一般是LD_LIBRARY_PATH, 但是不同的系统可能有不同名字. 例如<br /><br />Linux/Solaris: <tt>LD_LIBRARY_PATH</tt>, SGI: <tt>LD_LIBRARYN32_PATH</tt>, AIX: <tt>LIBPATH</tt>, Mac OS X: <tt>DYLD_LIBRARY_PATH</tt>, HP-UX: <tt>SHLIB_PATH</tt>) (<i><font color="#009900">注: 此说法未经验证</font></i>)<br /><br />
修改~/.bashrc , 增加以下脚本:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"><img src="http://www.cnitblog.com/images/dot.gif" /><br />if </span><span style="color: rgb(128, 0, 0); font-weight: bold;">[</span><span style="color: rgb(128, 0, 0);"> -d /opt/lib </span><span style="color: rgb(128, 0, 0); font-weight: bold;">]</span><span style="color: rgb(0, 128, 0);">;<br /></span><span style="color: rgb(0, 0, 0);">then<br />   LD_LIBRARY_PATH</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">/opt/lib:$LD_LIBRARY_PATH<br />fi<br /><br /><img src="http://www.cnitblog.com/images/dot.gif" /><br /><br />export LD_LIBRARY_PATH<br /></span></div><br />在第一章的简单例子中, /usr/lib 是Ubuntu默认的动态库目录,所以我们不须指定动态库目录也能运行应用程序.<br /><br /><h1><b><font><b><font><b><font><b><font color="#006600">3 简单的动态调用so例子</font></b></font></b></font></b></font></b></h1><br /><h2><font><font><font><font><font><font><font><font color="#006600">C调用例子</font></font></font></font></font></font></font></font></h2>保留第一章的test1.c和test2.c文件,并增加ctest.h头文件如下:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#ifndef CTEST_H<br /></span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> CTEST_H</span><span style="color: rgb(0, 0, 0);"><br /><br />#ifdef __cplusplus<br /></span><span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> {<br /></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test1();<br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> test2();<br /><br />#ifdef __cplusplus<br />}<br /></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br />      </span></div><br />我们继续使用第一章生成的libctest.so,仅需增加一个新的应用程序 prog.c:<br /><br />//prog.c<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">dlfcn.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ctest.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> argc, </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">argv) <br />{<br />   </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">lib_handle;<br />   </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">fn)();<br />   </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">error;<br /><br />   lib_handle </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlopen(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">libctest.so</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, RTLD_LAZY);<br />   </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">lib_handle) <br />   {<br />      fprintf(stderr, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, dlerror());<br />      </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />   }<br /><br />   fn </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlsym(lib_handle, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">test1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />   </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> ((error </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlerror()) </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> NULL)  <br />   {<br />      fprintf(stderr, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, error);<br />      </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">;<br />   }<br /><br />   </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> y</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">fn();<br />   printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">y=%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,y);<br /><br />   dlclose(lib_handle);<br />   <br />   </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}<br />       </span></div><br /><br />然后用如下命令运行(由于没有使用其他库,所以忽略-L等参数):<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">gcc -Wall prog.c -lctest -o prog</span><span style="color: rgb(0, 0, 0);"> -ldl<br />.</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">progdl</span></div><br /><h2><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font color="#006600">方法简介</font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></h2><span style="color: rgb(0, 0, 0);">dlopen(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">libctest.so</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, RTLD_LAZY): 加载动态库</span>,如果加载失败返回NULL. 第二个参数可以是:<br /><ul><li><span style="color: rgb(0, 0, 0);">RTLD_LAZY: lazy模式. 直到源码运行到改行才尝试加载.</span></li><li><span style="color: rgb(0, 0, 0);">RTLD_NOW: 马上加载.</span></li><li><span style="color: rgb(0, 0, 0);">RTLD_GLOBAL: 不解(原文:</span> Make symbol libraries visible.)</li></ul><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);"> dlsym(lib_handle, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">test1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">): 返回函数地址. 如果查找函数失败则返回NULL.</span><br /><br />和微软的动态加载dll技术对比如下:<br /><ul><li>::LoadLibrary() - dlopen()
        </li><li>::GetProcAddress() - dlsym()
        </li><li>::FreeLibrary() - dlclose()
        </li></ul><br /><h2><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font color="#006600">C++调用例子</font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></h2><br />增加一个prog2.cpp<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">dlfcn.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">ctest.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /><br /><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(){<br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">lib_handle;<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">MyClass* (*create)();<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">ReturnType (* func_name)();</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> func_handle)();  <br />    </span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> nameOfLibToLoad(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">libctest.so</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    lib_handle </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlopen(nameOfLibToLoad.c_str(), RTLD_LAZY);<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);">lib_handle) {<br />        cerr </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Cannot load library: </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> dlerror() </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl;<br />    }<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> reset errors</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    dlerror();<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> load the symbols (handle to function "test")<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">create = (MyClass* (*)())dlsym(handle, "create_object");<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">destroy = (void (*)(MyClass*))dlsym(handle, "destroy_object");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    func_handle </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)())dlsym(lib_handle, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">test1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> dlsym_error </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlerror();<br />    </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (dlsym_error) {<br />        cerr </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Cannot load symbol test1: </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> dlsym_error </span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);"> endl;<br />    }<br />    <br />    cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">result:= </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">func_handle()</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">endl;<br />    <br />    dlclose(lib_handle);<br />    <br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /><br /><br /></span></div><br />然后用如下命令运行:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">g++ -Wall prog2.cpp -lctest -o prog2</span><span style="color: rgb(0, 0, 0);"> -ldl</span><span style="color: rgb(0, 0, 0);"><br />.</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">prog2</span></div><br /><h2><font color="#006600">编译命令简介</font></h2>假设C文件是prog.c, C++调用文件是prog2.cpp,那么编译脚本分别是:<br /><br />C语言:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> gcc -Wall -I/path/to/include-files -L/path/to/libraries prog.c -lctest -o prog</span></div><br />C++语言:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> g++ -Wall -I/path/to/include-files -L/path/to/libraries prog2.cpp -lctest -ldl -o prog2</span></div><br />参数详解:<br /><ul><li>-I: 指定头文件目录. <br /></li><li>-L: 指定库目录.</li><li>-lctest: 调用动态库libctest.so.1.0. 如果在打包so时没有创建第一个符号链接,那么这个参数会导致编译不成功.</li><li>-ldl: C++编译必须<br /></li></ul><br /><h2><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font><font color="#006600">相关知识</font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font></font><br /></h2><br />命令<i><b>ldd appname</b></i> 可以查看应用程序所依赖的动态库,运行如下命令:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">ldd prog</span></div><br />
在我的机器输出:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    linux-gate.so</span><span style="color: rgb(0, 0, 0);">.1</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&gt;  (0xb80d4000)<br />    libctest.so</span><span style="color: rgb(0, 0, 0);">.1</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&gt; /usr/lib/libctest.so</span><span style="color: rgb(0, 0, 0);">.1</span><span style="color: rgb(0, 0, 0);"> (0xb80be000)<br />    libc.so</span><span style="color: rgb(0, 0, 0);">.6</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&gt; /lib/tls/i686/cmov/libc.so</span><span style="color: rgb(0, 0, 0);">.6</span><span style="color: rgb(0, 0, 0);"> (0xb7f5b000)<br />    /lib/ld-linux.so</span><span style="color: rgb(0, 0, 0);">.2</span><span style="color: rgb(0, 0, 0);"> (0xb80d5000)<br /></span></div><h1><b><font><b><font color="#006600">4 C++开发带class的so</font></b></font></b></h1>//myclass.h<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#ifndef __MYCLASS_H__<br /></span><span style="color: rgb(0, 0, 255);">#define</span><span style="color: rgb(0, 0, 0);"> __MYCLASS_H__</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> MyClass<br />{<br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);">:<br />  MyClass();<br /><br />  </span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"> use virtual otherwise linker will try to perform static linkage </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />  </span><span style="color: rgb(0, 0, 255);">virtual</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> DoSomething();<br /><br /></span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);">:<br />  </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> x;<br />};<br /><br /></span><span style="color: rgb(0, 0, 255);">#endif</span><span style="color: rgb(0, 0, 0);"><br /></span></div><br />//myclass.cpp<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">myclass.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /><br /></span><span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> create_object()<br />{<br />  </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> MyClass;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">extern</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">C</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> destroy_object( MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> )<br />{<br />  delete </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br />MyClass::MyClass()<br />{<br />  x </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">20</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> MyClass::DoSomething()<br />{<br />  cout</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">x</span><span style="color: rgb(0, 0, 0);">&lt;&lt;</span><span style="color: rgb(0, 0, 0);">endl;<br />}<br /></span></div><br />//class_user.cpp<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">dlfcn.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">iostream</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">myclass.h</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> std;<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> argc, </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">**</span><span style="color: rgb(0, 0, 0);">argv)<br />{<br />  </span><span style="color: rgb(0, 128, 0);">/*</span><span style="color: rgb(0, 128, 0);"> on Linux, use "./myclass.so" </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />  </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> handle </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> dlopen(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">./myclass.so</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, RTLD_LAZY);<br /><br />  MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">create)();<br />  </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">destroy)(MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">);<br /><br />  create </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)())dlsym(handle, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">create_object</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />  destroy </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)(MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">))dlsym(handle, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">destroy_object</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />  MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> myClass </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (MyClass</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)create();<br />  myClass</span><span style="color: rgb(0, 0, 0);">-&gt;</span><span style="color: rgb(0, 0, 0);">DoSomething();<br />  destroy( myClass );<br />}<br /></span></div><br /><br />编译和运行:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> g++ -fPIC -shared myclass.cpp -o myclass.so<br /> g++ class_user.cpp -ldl -o class_user<br /> ./class_user</span></div><br /><br /><br /><br /><br /><img src ="http://www.cnitblog.com/yunshichen/aggbug/61065.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2009-08-28 21:50 <a href="http://www.cnitblog.com/yunshichen/archive/2009/08/28/61065.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 附录B 资源引用</title><link>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43301.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Sun, 04 May 2008 09:27:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43301.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/43301.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43301.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/43301.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/43301.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 附录B 参考书和网络资源&nbsp;&nbsp;<a href='http://www.cnitblog.com/yunshichen/archive/2008/05/04/43301.html'>阅读全文</a><img src ="http://www.cnitblog.com/yunshichen/aggbug/43301.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-05-04 17:27 <a href="http://www.cnitblog.com/yunshichen/archive/2008/05/04/43301.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 第五章 标准库函数</title><link>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43300.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Sun, 04 May 2008 09:17:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43300.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/43300.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43300.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/43300.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/43300.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 标准库函数介绍和用法&nbsp;&nbsp;<a href='http://www.cnitblog.com/yunshichen/archive/2008/05/04/43300.html'>阅读全文</a><img src ="http://www.cnitblog.com/yunshichen/aggbug/43300.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-05-04 17:17 <a href="http://www.cnitblog.com/yunshichen/archive/2008/05/04/43300.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 附录A 格式速查</title><link>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43299.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Sun, 04 May 2008 09:10:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43299.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/43299.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/05/04/43299.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/43299.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/43299.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有用的查询&nbsp;&nbsp;<a href='http://www.cnitblog.com/yunshichen/archive/2008/05/04/43299.html'>阅读全文</a><img src ="http://www.cnitblog.com/yunshichen/aggbug/43299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-05-04 17:10 <a href="http://www.cnitblog.com/yunshichen/archive/2008/05/04/43299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 第四章 练习</title><link>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43144.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Thu, 01 May 2008 07:16:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43144.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/43144.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43144.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/43144.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/43144.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一些有趣的练习.管中窥豹,可以大致推断C标准库的实现.&nbsp;&nbsp;<a href='http://www.cnitblog.com/yunshichen/archive/2008/05/01/43144.html'>阅读全文</a><img src ="http://www.cnitblog.com/yunshichen/aggbug/43144.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-05-01 15:16 <a href="http://www.cnitblog.com/yunshichen/archive/2008/05/01/43144.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 第三章 拾遗补阙</title><link>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43143.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Thu, 01 May 2008 07:09:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43143.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/43143.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/05/01/43143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/43143.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/43143.html</trackback:ping><description><![CDATA[
		<h1>Chapter 3 拾遗补阙</h1>
		<h1>3.1 标准输入的缓冲区    </h1>    当你使用标准输入函数,如getchar,gets,scanf时,请注意缓冲区问题.简言之,当你使用如下函数时:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">getchar();</span></div>    <br />    编译器会将键盘输入的字符存储到系统的缓冲区,再从缓冲区返回一个字符给c变量.在这个语句,实际上你至少输入了两个字符(第二个字符是回车).这个回车符号保存在缓冲区里.当你再次使用getchar或者gets时,这些函数会检查缓冲区,发现缓冲区还有字符,于是就直接读取这个字符,而不是读入键盘输入.<br /><br />    也就是说,这些函数实际上并不是读入键盘输入的字符,而是先检查缓冲区.请观察以下这个错误的例子:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Input a char:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">getchar();<br /><br />    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">What char is it?</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    putchar(c);<br />    putchar(</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">\n</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 0);"><br />    c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">getchar();<br />    putchar(c);<br /><br />    system(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">pause</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);</span></div><br />    这个程序的本意是从键盘输入两次字符并打印.但你会发觉控制台只让你输入一次字符就自动结束.原因是第二个getchar发现缓冲区还有字符(上一个getchar留下的回车符号),所以它不等键盘输入就直接返回.<br />    <br />    所以,为了确保程序运行正确,每次运行getchar,gets,scanf..等函数时,先清空标准输入的缓冲区,语法如下:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    fflush(stdin);</span></div><br />    这个例子会加深你的了解:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">ctype.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdarg.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Input a char:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">getchar();</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Experiment to input a line instead of a char , and comment fflush(stdin) to watch the reslut.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">What char is it?</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    putchar(c);<br />    putchar(</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">\n</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">);<br /><br />    fflush(stdin);<br /><br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> s[</span><span style="color: rgb(0, 0, 0);">20</span><span style="color: rgb(0, 0, 0);">];<br />    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Input a line:</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    gets(s);<br /><br />    puts(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">What line is it?</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />    puts(s);<br /><br />    fflush(stdin);<br /><br />    system(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">pause</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}<br /></span></div><br /><br /><br /><hr size="2" width="100%" /><br /><img src ="http://www.cnitblog.com/yunshichen/aggbug/43143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-05-01 15:09 <a href="http://www.cnitblog.com/yunshichen/archive/2008/05/01/43143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 第二章 指针</title><link>http://www.cnitblog.com/yunshichen/archive/2008/04/25/42748.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Fri, 25 Apr 2008 10:13:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/04/25/42748.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/42748.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/04/25/42748.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/42748.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/42748.html</trackback:ping><description><![CDATA[
		<h1>Chapter 2 指针<br /></h1>
		<h2>2.1 变量与内存地址</h2>
		<br />    我们都很熟悉变量的声明赋值语句,例如:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;</span></div>    <br />    在这个简单的语句中,编译器实际上做了如下大量的工作:<br /><ol><li>创建变量名 a</li><li>为变量分配存储空间.假设这段空间的地址是0xFF6600</li><li>在地址空间存入值"5"</li></ol>    当然,以上描述是抽象性的,不涉及实际的技术细节.<br /><br />    当我们使用这个变量,例如打印a的值时,编译器会做如下工作:<br /><ol><li>查找变量a</li><li>查找变量a的地址空间</li><li>从地址空间取值</li></ol>    在许多"现代"的高级编程语言里,声明变量,取值,一切都显得很自然,因为编译器隐藏了变量关于地址的细节.而C将地址细节提供给程序员,鼓励程序员写出更快效率更高的程序.<br /><hr size="2" width="100%" /><br /><h2>2.2 指针(Pointer)的概念</h2>    为了精确的理解指针,请区分变量值和变量的精确含义.变量a的值是字面量(literal text)5 ,这个"5"不能再改变. 但是变量a的值可以改变为6,7,8...等等.有时候你可以把变量理解为一个小仓库,里面的东西可以搬来搬去.<br /><br />    指针正是这样一个小仓库.不同的是char类型变量存储字符串的值,int类型存储数值型值,而地址类型(指针)存储地址的值.例如如下我们声明一个指针pa,并用&amp;符号取出a地址并赋给pa:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> pa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">a;</span></div>    <br />    用一句简单的printf,你可以看到pa的值,即a的地址:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of pa is:%x</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,pa);</span></div>    <br />    当然,由于pa本身也是变量,根据2.1的描述,变量本身也有地址,我们可以试试打印pa的地址如下:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Address of pa is:%x</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">pa);</span></div>    <br />    *用于指针前表示取值,即"取指针所存储地址所存储的值".例如a的值是5,a的地址是0x66ff00,pa的值是0x66ff00,则*pa表示0x66ff00上所存储的值,也就是5.所以*pa==5;为了避免这种拗口的叫法,通常*pa也称为"取pa所指向变量的值."<br /><br />    为了帮助你更好的理解指针,请确保自己理解如下几个概念:<br /><ul><li>地址:变量所分配到的存储空间.例如char型的存储空间是1字节,int型是4字节(在现代32位操作系统).</li><li>变量的值:变量所被分配存储空间所存放的字面量.例如字符型的'a','b','c',数值型的1,2,3,地址型的0xFFCC00,0xFFCCFF 等.<br /></li><li>指针:地址的变量.指针的值不是普通的如1,2,3,'c','d','f' ... 等字面量,而是内存的地址.</li><li>&amp; :从变量中取出地址.</li><li>* :取pa所指向变量的值.</li></ul>    国内一些不太精确的教科书经常将"指针"和"指针变量"概念混用,让人瞠目不知所云.根据如上的精确定义,"指针"应指地址变量,"指针变量"应指地址变量的变量.所以"指针"并不等于"指针变量".请观察如下例子:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> pa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">a;<br /></span><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> ppa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">pa;</span></div>    <br />    上例中,a是变量,pa是指针,ppa可称为指针变量,或指针的指针.有趣的是,当你声明指针的指针时,观察如下例子:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">    int</span><span style="color: rgb(0, 0, 0);">***************************************************</span><span style="color: rgb(0, 0, 0);"> ppa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">pa;</span></div><br />    在我的gcc3.45中编译运行正确.<br /><br />    这里的讨论并不仅仅为了咬文嚼字.回想过去学习指针的经历,许多国内教材的翻译水平让我抓狂.如果你实在厌烦了玩弄文字把戏,你可以到官方网上进行学习: www.cplusplus.com<br /><br />    最后,请运行这个例子以加深巩固本章节的学习(为方便对比,我将地址值以10进制形式输出):<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br /><br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> pa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">a;<br /><br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of a is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,a);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Address of a is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">a);<br />    <br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of pa is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,pa);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of which pa pointed to is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">pa);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Address of pa itself is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">pa);<br />    <br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">***************************************************</span><span style="color: rgb(0, 0, 0);"> ppa</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">pa;<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of ppa is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,ppa);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Value of which ppa pointed to is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">ppa);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Address of ppa itself is : %d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">&amp;</span><span style="color: rgb(0, 0, 0);">ppa);<br />    <br />    <br />    <br />    <br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">system("pause");</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}</span></div><br />    <br /><hr size="2" width="100%" /><h2>2.3 指针和数组  </h2>    <br />    数组和指针的关系极其紧密.数组由一系列类型相同的元素组成,这些元素的地址是连续的.事实上,数组名本身就是一个指针,只不过该指针的值不能再更改(称为常量指针).<br /><br />    以下这个例子会让你加深理解:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br /><br />int main() {<br />    int arr[]= { 3, 7, 9, 11, 1, 6, 7, 5, 4, 2 };<br /><br />    printf("1.What's arr? %d\n", arr);<br />    printf("2.What's &amp;arr? %d\n", &amp;arr);<br />    printf("3.What's &amp;arr[0]? %d\n\n", &amp;arr[0]);<br /><br />    printf("4.What's arr[-2]? %d\n", arr[-2]);<br />    printf("5.What's arr[2]? %d\n\n", arr[2]);<br /><br />    int* pa=&amp;arr;<br />    pa+=4;<br />    printf("6.What's *pa? %d\n", *pa);<br />    printf("7.What's pa[2]? %d\n", pa[2]);<br />    printf("8.What's pa[-2]? %d\n", pa[-2]);<br /><br />    return 0;<br />}<br /></span><span style="color: rgb(0, 0, 0);"><br /></span></div><br />    有一个特性你必须知道,当数组作为函数的形参时,它实际上是一个指针.在紧接着数组声明后用sizeof函数,你可以得到数组的总地址空间,而在函数内,你用sizeof仅得到指针本身的大小(32位机器上是4字节). 例如:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br /><br />int strlen(char* a){<br />    printf("Size of a is:%d\n",sizeof(a));<br />    int c=0;<br />    while(*a++)c++;<br />    return c;<br />}<br /><br />int main() {<br />    char arr[]="Hello,world!";<br />    printf("Size of arr is:%d\n",sizeof(arr));<br />    <br /><br />    //This couldn't be compiled.<br />    //arr++;<br />    <br />    int l=strlen(&amp;arr);<br />    printf("Length of array is:%d\n",l);<br /><br />    return 0;<br />}<br /><br /></span><span style="color: rgb(0, 0, 0);"><br /><br /></span></div><br /><hr size="2" width="100%" /><h2>2.4 指针和字符串</h2><br />    声明字符串可以用数组或指针方式.但这两种方式存在差异.例如:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">    char</span><span style="color: rgb(0, 0, 0);"> a[</span><span style="color: rgb(0, 0, 0);">20</span><span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello,world</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 128, 0);">    //</span><span style="color: rgb(0, 128, 0);">a="hello";</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    a[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">] </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">s</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">; </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">OK.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">    char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> str</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Hello,world</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    str</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Another world!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    str++;//OK.    </span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 128, 0);">    //</span><span style="color: rgb(0, 128, 0);">*str='s';</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span><br /><span style="color: rgb(0, 128, 0);">    //</span><span style="color: rgb(0, 128, 0);">str[0]='s';</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span></div>    <br />    总结数组方式和指针方式声明字符串的区别如下:<br /><ul><li>数组方式有实际的空间,所以可以单独改变元素值.而指针方式不能.</li><li>虽然都是指针变量.但指针方式的指针可以运算,而数组方式不能.</li><li>指针方式中的指针可以指向另一个字符串,而数组方式的指针不能.所以要改变一个数组的值,只能逐个元素进行改变.</li></ul>    以下这个例子演示了如何使用系统函数strcpy<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">string.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">I'm a big enough buffer from string copied</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> b[</span><span style="color: rgb(0, 0, 0);">80</span><span style="color: rgb(0, 0, 0);">];<br />    <br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> s</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">This is a beautiful world.</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    <br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> t</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">NULL;<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">t = strcpy(a,s);//Couldn't be run!</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">t is : %s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,t);<br />    <br />    t </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">strcpy(b,s);<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">t is : %s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,t);    <br /><br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /><br /><br /> </span></div><br />    技术上,指针形式定义的字符串变量实际上指向常量的字符串,该常量不能改变.有关常量和指针的关系,我们在下一节继续讨论.<br /><br /><hr size="2" width="100%" /><br /><h2>2.5 指针和常量</h2>    <br />    常量是什么就不多加讨论了.见如下例子:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">;<br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">a is:%d\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,a);<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">a=6;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This will not be compiled.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">}<br /><br /></span></div><br />    常量(的)指针(pointer to constant )即指向常量的指针.也就是说,假设*p==5,进行*p=6的操作会失败.<br /><br />    相反,指针(的)常量(constant pointer )表示指针的值不能改变,而指针指向的对象的值可以改变.<br /><br />    数组名本身就是一个指针常量,所以数组名不能进行通常的指针运算.而用指针声明字符串时,该指针是指针常量,所以不能再改变各元素的值.<br /><br />    如果你觉得这个中文意义的区分有点拗口,请牢记代码方式:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">,b</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> c</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">a;<br />    <br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">*c=8;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    c</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">b;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">OK.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    <br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> d</span><span style="color: rgb(0, 0, 0);">=&amp;</span><span style="color: rgb(0, 0, 0);">a;<br />    </span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">d</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">10</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">d=&amp;a;    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    <br />}<br /><br /></span></div><br />    如果const在int*之前,则该变量是常量指针.const(常量)int*(指针)<br />    如果const在int*之后,则该变量是指针常量.int*(指针)const(常量) .<br /><br />    是不是很好记忆,呵呵.<br /><br />    常量指针有着实际的实用意义.假设某个函数的形参为指针,在我们操作这个指针时,很容易把指针指向的对象值也改变,如果将该指针指向的对象声明为常量(即声明常量指针为形参),以下代码说明一切:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> strlen(</span><span style="color: rgb(0, 0, 255);">const</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> str){<br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> c</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />    </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">str</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">){<br />        </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">*s='t';</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">This couldn't be compiled.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">        c</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">;<br />    }<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> c;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);"> s[]</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Don't change this string!</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />    <br />    </span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> l</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">strlen(s);<br />    <br />}<br /><br /></span></div><br /><hr size="2" width="100%" /><h2>2.6 函数指针(Pointer to function)</h2>    乍一看,C语言并没有"接口"的概念,习惯使用Java的程序员可能对此有点失望.其实,回忆一下"回调函数"的概念(callback function).无论我们学哪种语言,都会被教导我们要将代码写在哪里,才能被编译器编译进而运行.最著名的回调函数就是main函数,我们将代码写在main里,编译器就会运行我们的代码(如果没有错误的话).<br /><br />    所以,回调函数其实就是接口.在C语言,这通过函数指针来实现.<br /><br />    先看看函数指针的语法:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> someFunc1(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a);</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">一个普通的函数声明</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">someFunc2)(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a);</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">声明函数指针</span></div><br />    必须通过观察代码才能更好理解函数指针的实际作用<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdio.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />#include </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">stdlib.h</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />typedef </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">YOUR_NAME)();<br /><br /></span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fun1(){<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Diego</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />}<br /></span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> fun2(){<br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Chen</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> handleName(YOUR_NAME y){<br />    </span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> s</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">y();<br />    <br />    printf(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Welcome,%s\n</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,s);    <br />}<br /><br /></span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> main() {<br />    YOUR_NAME y1 </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> fun1;<br />    handleName(y1);<br />    handleName(fun2);<br />    <br />    </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />}<br /><br /><br /><br /> </span></div><br />    这段代码的知识点有:<br /><ul><li>如何声明函数指针</li><li>如何为函数指针变量赋值.</li><li>实际的应用</li></ul>    粗略地看,以上例子似乎平平无奇,其实不然.稍具Java Servlet编程经验的程序员都知道,处理web请求是一个相当简单的事情----实现Servlet的doGet或者doPost函数则可.也许我们羡慕Servlet面向程序员的简易友好的接口并且想用C语言实现,于是我们考虑如下伪码:<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">typedef </span><span style="color: rgb(0, 0, 255);">struct</span><span style="color: rgb(0, 0, 0);"> REQUEST_STRUCT<br />typedef </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">HANDLE_REQUEST_PROC)(REQUEST_STRUCT req)<br /><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> doGet(){<br />    REQUEST_STRUCT req;<br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Initializes req.<br />    <br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Gets function from implementation by programmer.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    HANDLE_REQUEST_PROC proc </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> <img src="http://www.cnitblog.com/images/dot.gif" />..</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Gets from somewhere.<br />    <br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Executes it.</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">    proc();<br />    <br />    </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">Continue other operations<img src="http://www.cnitblog.com/images/dot.gif" /> </span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br />}</span></div>    <br />    如果没有函数指针的帮助,这简直不可能.<br /><br />    简单的说,函数指针的重要作用在于允许代码在运行时才进行连接.对于一些框架设计工作来说,预定义的供给程序员实现的回调函数是必不可少的,只有函数指针才能达到这个目的.<br /><br />    函数指针的语法总结如下:<br /><ul><li>如何声明(对比普通函数的声明). <br /></li><li>如何赋值(仅需要函数名,不需要函数参数表)</li></ul><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> FUNCTIONS) (</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a,</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b);</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">声明函数指针</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> func1(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a,</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b);</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">符合该函数指针声明的函数</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> func2(</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> a,</span><span style="color: rgb(0, 0, 255);">int</span><span style="color: rgb(0, 0, 0);"> b);</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">符合该函数指针声明的函数</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);"><br />FUNCTIONS y </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> func1;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">赋值</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">y</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">func2;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">赋值<br /></span></div><br /><hr size="2" width="100%" /><h2>2.7 指针和动态内存分配</h2>    动态分配的内存地址空间是连续的,分配完的空间会返回起始地址的指针:<br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);"> pstr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">)malloc(</span><span style="color: rgb(0, 0, 0);">100</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 255);">sizeof</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 255);">char</span><span style="color: rgb(0, 0, 0);">));</span></div><br />    所以,在这个场合你还是会用到指针.关于动态内存的使用会有专题章节进行总结.<br /><hr size="2" width="100%" /><h2>2.8 指针用法总结</h2>    C语言里关于指针的应用场合总结如下:<br /><ul><li>遍历数组元素</li><li>引用字符串</li><li>提供面向程序员的接口,技术上以函数指针实现.</li><li>分配动态内存<br /></li></ul><br /><br /><img src ="http://www.cnitblog.com/yunshichen/aggbug/42748.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-04-25 18:13 <a href="http://www.cnitblog.com/yunshichen/archive/2008/04/25/42748.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言速记 第一章 快速入门</title><link>http://www.cnitblog.com/yunshichen/archive/2008/04/24/42692.html</link><dc:creator>Chenyunshi</dc:creator><author>Chenyunshi</author><pubDate>Thu, 24 Apr 2008 08:26:00 GMT</pubDate><guid>http://www.cnitblog.com/yunshichen/archive/2008/04/24/42692.html</guid><wfw:comment>http://www.cnitblog.com/yunshichen/comments/42692.html</wfw:comment><comments>http://www.cnitblog.com/yunshichen/archive/2008/04/24/42692.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yunshichen/comments/commentRss/42692.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yunshichen/services/trackbacks/42692.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Chapter 1 快速入门		1.1 尽快Hello world		    这个简单的例子有助于你快速进入C的世界:#include &lt;stdio.h&gt;#include &lt;stdlib.h&gt;#define PI 3.1415926float circle(float r);int main(int argc, char* argv) ...{    float r...&nbsp;&nbsp;<a href='http://www.cnitblog.com/yunshichen/archive/2008/04/24/42692.html'>阅读全文</a><img src ="http://www.cnitblog.com/yunshichen/aggbug/42692.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yunshichen/" target="_blank">Chenyunshi</a> 2008-04-24 16:26 <a href="http://www.cnitblog.com/yunshichen/archive/2008/04/24/42692.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>