﻿<?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>C++博客-Prayer-随笔分类-C/C++</title><link>http://www.cppblog.com/prayer/category/7958.html</link><description>在一般中寻求卓越</description><language>zh-cn</language><lastBuildDate>Thu, 04 Apr 2019 06:23:30 GMT</lastBuildDate><pubDate>Thu, 04 Apr 2019 06:23:30 GMT</pubDate><ttl>60</ttl><item><title>linux下提示/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found 解决办法</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216333.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 02:15:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216333.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216333.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216333.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216333.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216333.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">在rhel6.6上安装qt后，运行qtcreator提示 &#8220;核心载入失败: /opt/Qt5.3.2/Tools/QtCreator/lib/qtcreator/plugins/libCore.so:&nbsp;无法加载库/opt/Qt5.3.2/Tools/QtCreator/lib/qtcreator/plugins/libCore.so：(/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found&nbsp;<em id="__mceDel" style="margin: 0px; padding: 0px; line-height: 1.5;">(required by /opt/Qt5.3.2/Tools/QtCreator/lib/qtcreator/plugins/libCore.so))</em></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;"><em id="__mceDel" style="margin: 0px; padding: 0px; line-height: 1.5;"><em id="__mceDel" style="margin: 0px; padding: 0px;"></em></em>在网上查找资料后，解决方法如下<em id="__mceDel" style="margin: 0px; padding: 0px; line-height: 1.5;">。</em></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">1.查看gcc版本中包含哪些库。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">strings /usr/lib64/libstdc++.so.6 | grep GLIBC</p><table border="0" align="left" style="margin: 0px; padding: 0px; border-collapse: collapse; border-spacing: 0px; border-style: solid; border-color: silver; word-break: break-word; color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff; height: 22px; width: 222px;"><tbody style="margin: 0px; padding: 0px;"><tr style="margin: 0px; padding: 0px;"><td style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">GLIBCXX_3.4<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.1<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.2<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.3<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.4<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.5<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.6<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.7<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.8<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.9<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.10<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.11<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.12<br style="margin: 0px; padding: 0px;" />GLIBCXX_3.4.13<br style="margin: 0px; padding: 0px;" />GLIBC_2.2.5<br style="margin: 0px; padding: 0px;" />GLIBC_2.3<br style="margin: 0px; padding: 0px;" />GLIBC_2.4<br style="margin: 0px; padding: 0px;" />GLIBC_2.3.2<br style="margin: 0px; padding: 0px;" />GLIBCXX_FORCE_NEW<br style="margin: 0px; padding: 0px;" />GLIBCXX_DEBUG_MESSAGE_LENGTH</p></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">　　可以看出不包含GLIBCXX_3.4.14</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">2.从网上下载高版本的libstdc++.so.6.0.13以上的版本，比如libstdc++.so.6.0.17。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">3.把libstdc++.so.6.0.17拷贝到/usr/lib64目录下。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">　　cp&nbsp;libstdc++.so.6.0.17 /usr/lib64/</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">4.删除libstdc++.so.6符号连接。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">　　rm&nbsp;libstdc++.so.6</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">5.新建里符号连接。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">　　ln -s libstdc++.so.6.0.17 libstdc++.so.6</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">6.再次查看就没有问题了。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 15px; line-height: 27px; background-color: #ffffff;">libstdc++.so.6.0.17下载地址</p><img src ="http://www.cppblog.com/prayer/aggbug/216333.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 10:15 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216333.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>lib lib32 lib64等lib文件夹的说明</title><link>http://www.cppblog.com/prayer/archive/2019/04/04/216332.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 04 Apr 2019 02:14:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/04/216332.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216332.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/04/216332.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216332.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216332.html</trackback:ping><description><![CDATA[<ul style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: rgba(0, 0, 0, 0.74902); background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 32px; padding: 0px; list-style-type: disc; word-wrap: break-word;">/lib&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />最基本的共享库和内核模块。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />目的 -&gt; 存放用于启动系统和执行root文件系统的命令的如/bin /sbin的二进制文件的共享库，或者存放32位，或者64位(file命令查看)。</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 32px; padding: 0px; list-style-type: disc; word-wrap: break-word;">/lib、 /usr/lib、/usr/local/lib&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />目的 -&gt; 就是为了区分32位和64位而设置的目录。这种情况下/lib有可能是其符号链接。</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 32px; padding: 0px; list-style-type: disc; word-wrap: break-word;"><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">/usr/lib、/usr/local/lib&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />程序和安装包的库路径。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />说明 -&gt; 不依赖特定架构的库应该放到/usr/share中而不是这里。应用程序可以自己创建一个单独的子目录并把自己的库放在其中。</p></li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 32px; padding: 0px; list-style-type: disc; word-wrap: break-word;"><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">总结&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />一般情况下：&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />系统自己会匹配应用程序与其应该调用的位数的库。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />如果是用于/bin /sbin的库，放置到/lib*之中。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />如果是用于用户程序或安装包的，放置到/usr/lib*或/usr/local/lib*之中。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />如果某个库只是特别的用了某个专用程序，而这个程序但并不打算直接被用户或者root调用，应放置到/usr/libexec中。</p></li></ul><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word; background-color: #ffffff;"><a href="http://unix.stackexchange.com/questions/74646/difference-between-lib-lib32-lib64-libx32-and-libexec" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; background-color: transparent; word-wrap: break-word;">http://unix.stackexchange.com/questions/74646/difference-between-lib-lib32-lib64-libx32-and-libexec</a></p><img src ="http://www.cppblog.com/prayer/aggbug/216332.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-04 10:14 <a href="http://www.cppblog.com/prayer/archive/2019/04/04/216332.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux程序分析工具介绍—ldd,nm</title><link>http://www.cppblog.com/prayer/archive/2019/04/03/216328.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 03 Apr 2019 07:56:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/04/03/216328.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216328.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/04/03/216328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216328.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216328.html</trackback:ping><description><![CDATA[<section style="background-color: #ffffff; width: 1616px; margin: auto; overflow: hidden; font-family: 宋体, arial; font-size: 12px; line-height: normal;"><div style="width: 1486.71875px; margin: 0px auto auto; line-height: 32px; font-size: 18px; text-align: justify; overflow: hidden;"><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">本文要介绍的ldd和nm是linux下，两个用来分析程序很实用的工具。ldd是用来分析程序运行时需要依赖的动态库的工具；nm是用来查看指定程序中的符号表相关内容的工具。下面通过例子，分别来介绍一下这两个工具：</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">1. ldd, 先看下面的例子, 用ldd查看cs程序所依赖的动态库：</p><ol style="font-size: 0.95em;"><li style="font-size: 0.95em;">$&nbsp;ldd&nbsp;cs&nbsp;&nbsp;</li><li style="font-size: 0.95em;">linux-gate.so.1&nbsp;=&gt;&nbsp;&nbsp;(0xffffe000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libz.so.1&nbsp;=&gt;&nbsp;/lib/libz.so.1&nbsp;(0xb7f8c000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libpthread.so.0&nbsp;=&gt;&nbsp;/lib/libpthread.so.0&nbsp;(0xb7f75000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libcrypto.so.0.9.8&nbsp;=&gt;&nbsp;/usr/lib/libcrypto.so.0.9.8&nbsp;(0xb7e4d000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libpcre.so.0&nbsp;=&gt;&nbsp;/usr/lib/libpcre.so.0&nbsp;(0xb7e21000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libstdc++.so.6&nbsp;=&gt;&nbsp;/usr/local/gcc4.5.1/lib/libstdc++.so.6&nbsp;(0xb7d40000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libm.so.6&nbsp;=&gt;&nbsp;/lib/libm.so.6&nbsp;(0xb7d18000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libgcc_s.so.1&nbsp;=&gt;&nbsp;/usr/local/gcc4.5.1/lib/libgcc_s.so.1&nbsp;(0xb7cfd000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libc.so.6&nbsp;=&gt;&nbsp;/lib/libc.so.6&nbsp;(0xb7bbc000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">/lib/ld-linux.so.2&nbsp;(0xb7fab000)&nbsp;&nbsp;</li><li style="font-size: 0.95em;">libdl.so.2&nbsp;=&gt;&nbsp;/lib/libdl.so.2&nbsp;(0xb7bb7000)&nbsp;&nbsp;</li></ol><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">在上面的例子中，ldd的结果可以分为三列来看：</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">&#8226;第一列：程序需要依赖什么库<br style="font-size: 0.95em;" />&#8226;第二列: 系统提供的与程序需要的库所对应的库<br style="font-size: 0.95em;" />&#8226;第三列：库加载的开始地址<br style="font-size: 0.95em;" />通过上面的信息，我们可以得到以下几个信息：</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">&#8226;（1） 通过对比第一列和第二列，我们可以分析程序需要依赖的库和系统实际提供的，是否相匹配<br style="font-size: 0.95em;" />&#8226;（2） 通过观察第三列，我们可以知道在当前的库中的符号在对应的进程的地址空间中的开始位置<br style="font-size: 0.95em;" />2. nm, 通过下面的例子，我们来介绍nm工具：</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">先看一下这个简单的程序：</p><ol style="font-size: 0.95em;"><li style="font-size: 0.95em;">#include&nbsp;"iostream"&nbsp;&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;</li><li style="font-size: 0.95em;"><strong style="font-size: 0.95em;">using</strong>&nbsp;<strong style="font-size: 0.95em;">namespace</strong>&nbsp;std;&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;</li><li style="font-size: 0.95em;"><strong style="font-size: 0.95em;">class</strong>&nbsp;Test&nbsp;&nbsp;</li><li style="font-size: 0.95em;">{&nbsp;&nbsp;</li><li style="font-size: 0.95em;"><strong style="font-size: 0.95em;">public</strong>:&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;<strong style="font-size: 0.95em;">void</strong>&nbsp;Hello()&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&nbsp;&lt;&nbsp;"Hello&nbsp;world!"&nbsp;&lt;&lt;&nbsp;endl;&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="font-size: 0.95em;">};&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;</li><li style="font-size: 0.95em;"><strong style="font-size: 0.95em;">int</strong>&nbsp;main()&nbsp;&nbsp;</li><li style="font-size: 0.95em;">{&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;Test&nbsp;test;&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;test.Hello();&nbsp;&nbsp;</li><li style="font-size: 0.95em;">}&nbsp;&nbsp;</li></ol><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">接下来，我们编译该程序，然后看nm的结果：</p><ol style="font-size: 0.95em;"><li style="font-size: 0.95em;">$&nbsp;g++&nbsp;test.cc&nbsp;-o&nbsp;test&nbsp;&nbsp;</li><li style="font-size: 0.95em;">c$&nbsp;nm&nbsp;test&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f10&nbsp;d&nbsp;_DYNAMIC&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049ff4&nbsp;d&nbsp;_GLOBAL_OFFSET_TABLE_&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080486f0&nbsp;t&nbsp;_GLOBAL__I_main&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080487fc&nbsp;R&nbsp;_IO_stdin_used&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;_Jv_RegisterClasses&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080486b0&nbsp;t&nbsp;_Z41__static_initialization_and_destruction_0ii&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804870c&nbsp;W&nbsp;_ZN4Test5HelloEv&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;_ZNSolsEPFRSoS_E@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;_ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;_ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a040&nbsp;B&nbsp;_ZSt4cout@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a0d4&nbsp;b&nbsp;_ZStL8__ioinit&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f00&nbsp;d&nbsp;__CTOR_END__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049ef8&nbsp;d&nbsp;__CTOR_LIST__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f08&nbsp;D&nbsp;__DTOR_END__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f04&nbsp;d&nbsp;__DTOR_LIST__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080488c8&nbsp;r&nbsp;__FRAME_END__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f0c&nbsp;d&nbsp;__JCR_END__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049f0c&nbsp;d&nbsp;__JCR_LIST__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a02c&nbsp;A&nbsp;__bss_start&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;__cxa_atexit@@GLIBC_2.1.3&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a024&nbsp;D&nbsp;__data_start&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080487b0&nbsp;t&nbsp;__do_global_ctors_aux&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048610&nbsp;t&nbsp;__do_global_dtors_aux&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a028&nbsp;D&nbsp;__dso_handle&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;w&nbsp;__gmon_start__&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;__gxx_personality_v0@@CXXABI_1.3&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080487aa&nbsp;T&nbsp;__i686.get_pc_thunk.bx&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049ef8&nbsp;d&nbsp;__init_array_end&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08049ef8&nbsp;d&nbsp;__init_array_start&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048740&nbsp;T&nbsp;__libc_csu_fini&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048750&nbsp;T&nbsp;__libc_csu_init&nbsp;&nbsp;</li><li style="font-size: 0.95em;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;U&nbsp;__libc_start_main@@GLIBC_2.0&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a02c&nbsp;A&nbsp;_edata&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a0d8&nbsp;A&nbsp;_end&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080487dc&nbsp;T&nbsp;_fini&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080487f8&nbsp;R&nbsp;_fp_hw&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048508&nbsp;T&nbsp;_init&nbsp;&nbsp;</li><li style="font-size: 0.95em;">080485e0&nbsp;T&nbsp;_start&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a0cc&nbsp;b&nbsp;completed.7065&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a024&nbsp;W&nbsp;data_start&nbsp;&nbsp;</li><li style="font-size: 0.95em;">0804a0d0&nbsp;b&nbsp;dtor_idx.7067&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048670&nbsp;t&nbsp;frame_dummy&nbsp;&nbsp;</li><li style="font-size: 0.95em;">08048694&nbsp;T&nbsp;main&nbsp;&nbsp;</li></ol><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">上面便是test这个程序中所有的符号，首先需要介绍一下上面的内容的格式：</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">&#8226;第一列：当前符号的地址<br style="font-size: 0.95em;" />&#8226;第二列：当前符号的类型<br style="font-size: 0.95em;" />&#8226;第三列：当前符号的名称<br style="font-size: 0.95em;" />在上面的结果中，像_ZN4Test5HelloEv这样的符号，很多读者朋友可能会被它搞晕，这里介绍个小技巧，在nm的时候，加上-C选项，就可以把这些难以识别的符号，转换成便于我们阅读的符号TestHello()。这个主要是c++中的mangle机制所导致的，加上-C就是指定列出的符号是demangle了的。说了这么多，到底nm对我们程序有啥具体的帮助呢，我觉得主要有以下几个方面：<br style="font-size: 0.95em;" />（1）判断指定程序中有没有定义指定的符号 (比较常用的方式：nm -C proc | grep symbol)<br style="font-size: 0.95em;" />（2）解决程序编译时undefined reference的错误，以及mutiple definition的错误</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;">（3）查看某个符号的地址，以及在进程空间的大概位置（bss, data, text区，具体可以通过第二列的类型来判断）</p><p style="font-size: 0.95em; margin: 0px; line-height: 1.6em; padding: 0px; text-indent: 2em;"></p><blockquote style="background-color: #f3f7f0; padding-right: 5px; padding-left: 5px; margin-right: 0px; margin-left: 0px; font-size: 0.95em;"><p style="font-size: 14px; margin: 0px; line-height: 1.6; padding: 0px; text-indent: 2em;">本文要介绍的ldd和nm是linux下，两个用来分析程序很实用的工具。ldd是用来分析程序运行时需要依赖的动态库的工具；nm是用来查看指定程序中的符号表相关内容的工具。下面通过例子，分别来介绍一</p></blockquote></div></section><div style="width: 1519.03125px; margin: auto; overflow: hidden; font-family: 宋体, arial; font-size: 12px; line-height: normal; text-align: center; background-color: #ffffff;"><div style="width: 1427.875px; float: none; margin: 10px auto 0px;"><h1>相关推荐</h1></div></div><img src ="http://www.cppblog.com/prayer/aggbug/216328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-04-03 15:56 <a href="http://www.cppblog.com/prayer/archive/2019/04/03/216328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各unix平台动态连接库的编译与使用</title><link>http://www.cppblog.com/prayer/archive/2019/03/01/216276.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Fri, 01 Mar 2019 09:58:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/03/01/216276.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216276.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/03/01/216276.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216276.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216276.html</trackback:ping><description><![CDATA[<div>http://blog.itpub.net/283313/viewspace-2139257/<br /><br /><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">unix平台下，动态连接库的使用有两种方式，link方式和dlopen方式。需要设置LD_LIBRARY_PATH作为查找路径（低版本AIX使用LIBPATH）。link方式是程序启动时加载所有编译时连接的动态库，直到程序结束也不会关闭。dlopen方式是在运行中按照参数指定的方式加载动态库，并可以使用dlclose函数关闭，直到下次再使用dlopen重新加载。因此，link方式无法做到不重启应用程序而更新动态库版本，dlopen方式可以。</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">各平台动态连接库的编译参数如下。文件wel.c，编译成libwel.so（HPUX为libwel.sl）。</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"></p><div id="codeText" style="margin: 0px 0px 1.1em; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: Consolas, monospace; border: 1px solid #dddddd; width: 872.1875px; overflow: auto; word-break: break-all; background-color: #ffffff; font-size: 12px; line-height: normal; color: #444444;"><ol start="1" style="margin: 0px 1px 0px 0px; padding: 0px 0px 0px 40px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; list-style: disc; color: #5c5c5c; line-height: 1.3;"><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #000000;">#include&nbsp;<span style="color: #0000cc;">&lt;</span>stdio<span style="color: #0000cc;">.</span>h<span style="color: #0000cc;">&gt;</span><br /></span></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">void welcome<span style="color: #0000cc;">(</span>void<span style="color: #0000cc;">)</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">{</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;puts<span style="color: #0000cc;">(</span><span style="color: #ff00ff;">"welcome,baby!"</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">}</span></li></ol></div><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br />&nbsp;linux:<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;gcc -fPIC -shared -o libwel.so wel.c -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-fPIC&nbsp;&nbsp;用相对地址定位<br />&nbsp;&nbsp;&nbsp;&nbsp;-shared&nbsp;&nbsp;生成动态连接库</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;sco unix open server:<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;cc -K PIC -G -o libwel.so wel.c -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-K PIC&nbsp;&nbsp;用相对地址定位<br />&nbsp;&nbsp;&nbsp;&nbsp;-G&nbsp;&nbsp;生成动态连接库，包含了-b elf选项</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;AIX:<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;xlc -G -bnoentry -o libwel.so wel.c -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-G&nbsp;&nbsp;指定生成动态连接库<br />&nbsp;&nbsp;&nbsp;&nbsp;-bnoentry&nbsp;动态库无需模块入口（低版本AIX需要此参数）</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;HP UX:<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;cc +z -c wel.c<br />&nbsp;&nbsp;&nbsp;ld -b -o libwel.sl wel.o -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;+z&nbsp;&nbsp;用相对地址定位<br />&nbsp;&nbsp;&nbsp;&nbsp;-b&nbsp;&nbsp;生成动态连接库</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;SUN OS: 很类似SCO，man帮助不全面<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;cc -G -o libwel.so wel.c -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-G&nbsp;&nbsp;生成动态连接库</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">link方式使用动态连接库的编译参数如下。文件welcome.c，编译成welcome可执行程序。</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"></p><div id="codeText" style="margin: 0px 0px 1.1em; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: Consolas, monospace; border: 1px solid #dddddd; width: 872.1875px; overflow: auto; word-break: break-all; background-color: #ffffff; font-size: 12px; line-height: normal; color: #444444;"><ol start="1" style="margin: 0px 1px 0px 0px; padding: 0px 0px 0px 40px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; list-style: disc; color: #5c5c5c; line-height: 1.3;"><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #000000;">extern void welcome<span style="color: #0000cc;">(</span>void<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></span></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #ff0000;">int</span>&nbsp;main<span style="color: #0000cc;">(</span>void<span style="color: #0000cc;">)</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">{</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;welcome<span style="color: #0000cc;">(</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0<span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">}</span></li></ol></div><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;linux:<br />&nbsp;&nbsp;&nbsp;gcc -rdynamic -o welcome welcome.c -L. -lwel<br />&nbsp;&nbsp;&nbsp;&nbsp;-rdynamic&nbsp;&nbsp;导出所有符号供动态使用</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;sco unix open server:<br />&nbsp;&nbsp;&nbsp;cc -b elf -o welcome welcome.c -L. -lwel<br />&nbsp;&nbsp;&nbsp;&nbsp;-b elf&nbsp;&nbsp;必须使用ELF的可执行文件格式</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;AIX:<br />&nbsp;&nbsp;&nbsp;xlc -bdynamic -brtl -o welcome welcome.c -L. -lwel<br />&nbsp;&nbsp;&nbsp;&nbsp;-bdynamic&nbsp;使用动态连接方式，系统默认为此方式<br />&nbsp;&nbsp;&nbsp;&nbsp;-brtl&nbsp;&nbsp;-l参数使用.so为库</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;HP UX:<br />&nbsp;&nbsp;&nbsp;cc -dynamic -o welcome welcome.c -L. -lwel<br />&nbsp;&nbsp;&nbsp;&nbsp;-dynamic&nbsp;使用动态连接方式，系统默认为此方式</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;SUN OS:<br />&nbsp;&nbsp;编译libwel.so:<br />&nbsp;&nbsp;&nbsp;cc -B dynamic -o welcome welcome.c -L. -lwel<br />&nbsp;&nbsp;&nbsp;&nbsp;-B dynamic&nbsp;使用动态连接方式</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">dlopen方式，其实就是把打开动态库和查找符号的动作放在程序中执行。因此编译可执行文件与普通的相同，只要连接libdl.so库即可。文件welcome.c，编译成welcome可执行程序。</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"></p><div id="codeText" style="margin: 0px 0px 1.1em; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: Consolas, monospace; border: 1px solid #dddddd; width: 872.1875px; overflow: auto; word-break: break-all; background-color: #ffffff; font-size: 12px; line-height: normal; color: #444444;"><ol start="1" style="margin: 0px 1px 0px 0px; padding: 0px 0px 0px 40px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; list-style: disc; color: #5c5c5c; line-height: 1.3;"><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #000000;">#include&nbsp;<span style="color: #0000cc;">&lt;</span>dlfcn<span style="color: #0000cc;">.</span>h<span style="color: #0000cc;">&gt;</span><br /></span></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #ff0000;">int</span>&nbsp;main<span style="color: #0000cc;">(</span>void<span style="color: #0000cc;">)</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">{</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;<span style="color: #0000cc;">*</span>handle<span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;<span style="color: #0000cc;">(</span><span style="color: #0000cc;">*</span>welcome<span style="color: #0000cc;">)</span><span style="color: #0000cc;">(</span>void<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;handle<span style="color: #0000cc;">=</span>dlopen<span style="color: #0000cc;">(</span><span style="color: #ff00ff;">"libwel.so"</span><span style="color: #0000cc;">,</span>RTLD_LAZY<span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;welcome<span style="color: #0000cc;">=</span>dlsym<span style="color: #0000cc;">(</span>handle<span style="color: #0000cc;">,</span><span style="color: #ff00ff;">"welcome"</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000cc;">(</span><span style="color: #0000cc;">*</span>welcome<span style="color: #0000cc;">)</span><span style="color: #0000cc;">(</span><span style="color: #0000cc;">)</span><span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;return 0<span style="color: #0000cc;">;</span><br /></li><li style="margin: 0px; padding: 0px 0px 0px 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><span style="color: #0000cc;">}</span></li></ol></div><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br />&nbsp;linux:<br />&nbsp;&nbsp;&nbsp;gcc -rdynamic -o welcome welcome.c -ldl<br />&nbsp;&nbsp;&nbsp;&nbsp;-rdynamic&nbsp;导出所有符号供动态使用<br />&nbsp;&nbsp;&nbsp;&nbsp;-ldl&nbsp;&nbsp;用系统libdl.so库dlopen(),dlsym(),dlerror(),dlclose()</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;sco unix open server:<br />&nbsp;&nbsp;&nbsp;cc -b elf -o welcome welcome.c -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-b elf&nbsp;&nbsp;以elf格式，动态连接库必须</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;AIX:<br />&nbsp;&nbsp;&nbsp;xlc -bexpall -o welcome welcome.c -ldl -lc<br />&nbsp;&nbsp;&nbsp;&nbsp;-bexpall&nbsp;使主程序的符号可以被动态库使用</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;HP UX:<br />&nbsp;&nbsp;&nbsp;cc -o welcome welcome.c -ldl -lc</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">&nbsp;SUN OS:<br />&nbsp;&nbsp;&nbsp;cc -o welcome welcome.c -ldl -lc</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">------------------------------------------------------------------------------<br />参照的man手册：<br />&nbsp;cc, ld, ldd, dlopen, dlclose, dlerror, dlsym, CC</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;">另：AIX运行动态库时会加载系统内存统一管理，导致即使程序已退出，编译时仍然认为还在使用而无法覆盖。有两个办法，一是root用户执行slibclean，清理系统加载而无人使用的动态库，另一种是编译的库chmod go-rwx，使得组和其他人无权限，这种库系统会认为用户特有而不加载。</p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; line-height: 28px; font-size: 16px; color: #666666; text-align: justify; background-color: #ffffff;"><br /></p><p style="margin: 0px 0px 18px; padding: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; color: #666666; font-size: 16px; line-height: 28px; text-align: justify; background-color: #ffffff;">来自 &#8220; ITPUB博客 &#8221; ，链接：http://blog.itpub.net/283313/viewspace-2139257/，如需转载，请注明出处，否则将追究法律责任。</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-03-01 17:58 <a href="http://www.cppblog.com/prayer/archive/2019/03/01/216276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux 静态库的链接 undefined reference</title><link>http://www.cppblog.com/prayer/archive/2019/02/28/216273.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 28 Feb 2019 08:59:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/02/28/216273.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216273.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/02/28/216273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216273.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216273.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/csdn66_2016/article/details/70145962<br /><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: Arial; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 26px;">最近在Linux下编程发现一个诡异的现象，就是在链接一个静态库的时候总是报错，类似下面这样的错误：</span><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">(.text+0x13):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`func'&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 关于undefined reference这样的问题，大家其实经常会遇到，在此，我以详细地示例给出常见错误的各种原因以及解决方法，希望对初学者有所帮助。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; color: #ff0000;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-size: 16px;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">1.&nbsp; 链接时缺失了相关目标文件（.o）</span></span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; font-size: 16px;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-size: 14px;">测试代码如下：</span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><a href="http://img1.51cto.com/attachment/201011/133144914.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201011/133144914.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a>&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 然后编译。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;test.c &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;&#8211;c&nbsp;main.c&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 得到两个 .o 文件，一个是 main.o，一个是 test.o ，然后我们链接 .o 得到可执行程序：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这时，你会发现，报错了：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">main.o:&nbsp;In&nbsp;function&nbsp;`main': &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">main.c:(.text+0x7):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`test' &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">collect2:&nbsp;ld&nbsp;returned&nbsp;1&nbsp;exit&nbsp;status&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这就是最典型的undefined reference错误，因为在链接时发现找不到某个函数的实现文件，本例中test.o文件中包含了test()函数的实现，所以如果按下面这种方式链接就没事了。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;test.o&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; 【扩展】：其实上面为了让大家更加清楚底层原因，我把编译链接分开了，下面这样编译也会报undefined reference错，其实底层原因与上面是一样的。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.c&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">//缺少test()的实现文件</span>&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">需要改成如下形式才能成功，将test()函数的实现文件一起编译。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.c&nbsp;test.c&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">//ok,没问题了</span>&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; color: #ff0000;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-size: 16px;">2.&nbsp;&nbsp;&nbsp; 链接时缺少相关的库文件（.a/.so）</span></span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;在此，只举个静态库的例子，假设源码如下。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><a href="http://img1.51cto.com/attachment/201011/133734483.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201011/133734483.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 先把test.c编译成静态库(.a)文件</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;test.c &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">ar&nbsp;-rc&nbsp;test.a&nbsp;test.o&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 至此，我们得到了test.a文件。我们开始编译main.c</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;main.c&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这时，则生成了main.o文件，然后我们再通过如下命令进行链接希望得到可执行程序。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 你会发现，编译器报错了：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">/tmp/ccCPA13l.o:&nbsp;In&nbsp;function&nbsp;`main': &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">main.c:(.text+0x7):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`test' &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">collect2:&nbsp;ld&nbsp;returned&nbsp;1&nbsp;exit&nbsp;status&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 其根本原因也是找不到test()函数的实现文件，由于该test()函数的实现在test.a这个静态库中的，故在链接的时候需要在其后加入test.a这个库，链接命令修改为如下形式即可。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;./test.a&nbsp;&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">//注：./&nbsp;是给出了test.a的路径</span>&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp; 【扩展】：同样，为了把问题说清楚，上面我们把代码的编译链接分开了，如果希望一次性生成可执行程序，则可以对main.c和test.a执行如下命令。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.c&nbsp;./test.a&nbsp;&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">//同样，如果不加test.a也会报错</span>&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; color: #ff0000;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-size: 16px;">3.&nbsp;&nbsp;&nbsp; 链接的库文件中又使用了另一个库文件</span></span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这种问题比较隐蔽，也是我最近遇到的与网上大家讨论的不同的问题，举例说明如下，首先，还是看看测试代码。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><a href="http://img1.51cto.com/attachment/201011/134157339.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201011/134157339.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 从上图可以看出，main.c调用了test.c的函数，test.c中又调用了fun.c的函数。<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;&nbsp;&nbsp; 首先，我们先对fun.c，test.c，main.c进行编译，生成 .o文件。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;func.c &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;test.c &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-c&nbsp;main.c&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 然后，将test.c和func.c各自打包成为静态库文件。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">ar&nbsp;&#8211;rc&nbsp;func.a&nbsp;func.o &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">ar&nbsp;&#8211;rc&nbsp;test.a&nbsp;test.o&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这时，我们准备将main.o链接为可执行程序，由于我们的main.c中包含了对test()的调用，因此，应该在链接时将test.a作为我们的库文件，链接命令如下。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;test.a&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这时，编译器仍然会报错，如下：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">test.a(test.o):&nbsp;In&nbsp;function&nbsp;`test': &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">test.c:(.text+0x13):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`func' &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">collect2:&nbsp;ld&nbsp;returned&nbsp;1&nbsp;exit&nbsp;status&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 就是说，链接的时候，发现我们的test.a调用了func()函数，找不到对应的实现。由此我们发现，原来我们还需要将test.a所引用到的库文件也加进来才能成功链接，因此命令如下。</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;test.a&nbsp;func.a&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; ok，这样就可以成功得到最终的程序了。同样，如果我们的库或者程序中引用了第三方库（如pthread.a）则同样在链接的时候需要给出第三方库的路径和库文件，否则就会得到undefined reference的错误。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; color: #ff0000;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-size: 16px;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">4 多个库文件链接顺序问题</span></span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 这种问题也非常的隐蔽，不仔细研究你可能会感到非常地<a href="https://www.baidu.com/s?wd=%E8%8E%AB%E5%90%8D%E5%85%B6%E5%A6%99&amp;tn=24004469_oem_dg&amp;rsv_dl=gh_pl_sl_csd" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">莫名其妙</a>。我们依然回到第3小节所讨论的问题中，在最后，如果我们把链接的库的顺序换一下，看看会发生什么结果？</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">gcc&nbsp;-o&nbsp;main&nbsp;main.o&nbsp;func.a&nbsp;test.a&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 我们会得到如下报错.</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">test.a(test.o):&nbsp;In&nbsp;function&nbsp;`test': &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">test.c:(.text+0x13):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`func' &nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">collect2:&nbsp;ld&nbsp;returned&nbsp;1&nbsp;exit&nbsp;status&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 因此，我们需要注意，在链接命令中给出所依赖的库时，需要注意库之间的依赖顺序，依赖其他库的库一定要放到被依赖库的前面，这样才能真正避免undefined reference的错误，完成编译链接。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; font-size: 16px;">5. 在c++代码中链接c语言的库</span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;如果你的库文件由c代码生成的，则在c++代码中链接库中的函数时，也会碰到undefined reference的问题。下面举例说明。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;首先，编写c语言版库文件：&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;<a href="http://img1.51cto.com/attachment/201109/150358466.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201109/150358466.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;编译，打包为静态库：test.a</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: 'Courier New', monospace; white-space: pre-wrap; word-wrap: break-word; overflow: auto; line-height: 26px; background-color: #ffffff; width: 587px;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; background-color: #ffffff; border-style: none none none solid; border-left-color: #146b00; border-left-width: 3px; color: #5c5c5c;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word; border-style: none; line-height: 1.3em; list-style-position: outside !important;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; color: #000000; border-style: none;">gcc&nbsp;-c&nbsp;test.c &nbsp;</span></li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word; border-style: none; line-height: 1.3em; list-style-position: outside !important;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; color: #000000; border-style: none;">ar&nbsp;-rc&nbsp;test.a&nbsp;test.o&nbsp;</span></li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 至此，我们得到了test.a文件。下面我们开始编写c++文件main.cpp</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;<a href="http://img1.51cto.com/attachment/201109/150553287.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201109/150553287.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;然后编译main.cpp生成可执行程序：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">g++&nbsp;-o&nbsp;main&nbsp;main.cpp&nbsp;test.a&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;会发现报错：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">/tmp/ccJjiCoS.o:&nbsp;In&nbsp;function&nbsp;`main':&nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">main.cpp:(.text+0x7):&nbsp;undefined&nbsp;reference&nbsp;to&nbsp;`test()'&nbsp;</li><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">collect2:&nbsp;ld&nbsp;returned&nbsp;1&nbsp;exit&nbsp;status&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;原因就是main.cpp为c++代码，调用了c语言库的函数，因此链接的时候找不到，解决方法：即在main.cpp中，把与c语言库test.a相关的头文件包含添加一个extern "C"的声明即可。例如，修改后的main.cpp如下：</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;<a href="http://img1.51cto.com/attachment/201109/150959476.png" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;"><img border="0" alt="" src="http://img1.51cto.com/attachment/201109/150959476.png" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 1px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a></p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; font-family: Consolas, Inconsolata, Courier, monospace; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; line-height: 26px; background-color: #ffffff;"></pre><ol style="box-sizing: border-box; outline: 0px; margin: 0px 0px 24px; padding: 0px; list-style: none; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; word-wrap: break-word; color: #333333; background-color: #ffffff;"><li style="box-sizing: border-box; outline: 0px; margin: 8px 0px 0px 40px; padding: 0px; list-style-type: decimal; word-wrap: break-word;">g++&nbsp;-o&nbsp;main&nbsp;main.cpp&nbsp;test.a&nbsp;</li></ol><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp; &nbsp;再编译会发现，问题已经成功解决。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word; font-size: 16px;">6.&nbsp; 总 结</span></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-family: Arial; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 当然，上面几种是我目前发现的比较常见的undefined reference错误的原因和解决方法，可能也有其他各种原因，欢迎大家来信<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#108;&#117;&#106;&#117;&#110;&#46;&#104;&#117;&#115;&#116;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #ca0000; text-decoration: none; cursor: pointer; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; word-wrap: break-word;">lujun.hust@gmail.com</a>交流，对本文档进行补充，方面新手们解决学习过程中遇到的各种问题。</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-02-28 16:59 <a href="http://www.cppblog.com/prayer/archive/2019/02/28/216273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C中的命令行中如果本身参数有空格怎么处理</title><link>http://www.cppblog.com/prayer/archive/2019/01/14/216196.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 14 Jan 2019 01:40:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2019/01/14/216196.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216196.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2019/01/14/216196.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216196.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216196.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/szu_tanglanting/article/details/14585303<br /><p style="box-sizing: border-box; outline: 0px; padding: 0px; margin: 0px 0px 16px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">C中的命令行中如果本身参数有空格怎么处理：</p><p style="box-sizing: border-box; outline: 0px; padding: 0px; margin: 0px 0px 16px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; padding: 0px; margin: 0px 0px 16px; font-family: 'Microsoft YaHei', 'SF Pro Display', Roboto, Noto, Arial, 'PingFang SC', sans-serif; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;">用&#8220; &#8221;来处理<img src="https://img-blog.csdn.net/20131108225140156?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdGFuZ2xhbnRpbmcxMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" style="box-sizing: border-box; outline: 0px; max-width: 100%; margin: 0px; word-wrap: break-word; cursor: -webkit-zoom-in;" /><br /><br /><br /></p><div>https://blog.csdn.net/zengcccc/article/details/7063483<br /><div>如题:加入一个文件的位置是在&nbsp;</div><div></div><div>C:\Documents and Settings\Administrator\桌面\1.txt 时.</div><div></div><div>如果通过编程来索引到这个1.txt文件,并相应的对该文件做出相应, 那么程序会把该路径C:\Documents &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Settings\Administrator\桌面\1.txt &nbsp; &nbsp; &nbsp;解析成3个参数,</div><div></div><div>这样就会导致程序不能正确的执行, &nbsp;该如何处理呢, 这个问题我也思考很久, 在读了一本叫做&lt;&lt;C Primer Plus&gt;&gt;的书籍后,最后终于找到了答案.</div><div></div><div>这句话是这么说的:</div><div></div><div>"顺便提一下,很多环境(包括UNIX和DOS)允许使用引号把多个单词集中在一个参数里.例如:</div><div></div><div>repeat &nbsp; &nbsp;"I am hungry" &nbsp; &nbsp;now &nbsp;</div><div></div><div>" 这个命令会把字符串"I am hungry"分配给argv[1],把字符串"now"分配给argv[2].</div><div></div><div>&nbsp;https://docs.microsoft.com/zh-cn/previous-versions/17w5ykft(v=vs.120)</div><div><h1>分析 C++ 命令行参数</h1><ul page-metadata"="" data-bi-name="page info" dir="ltr" style="box-sizing: inherit; display: flex; color: #5e5e5e; font-size: 0.875rem; flex-wrap: wrap; list-style: none; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; line-height: 25px; background-color: #ffffff; padding: 0px !important; margin: 0px !important;"><li style="box-sizing: inherit; list-style: none; display: flex; flex-basis: auto;"><time role="presentation" datetime="2015-06-09T00:00:00.000Z" data-article-date-source="ms.date" style="box-sizing: inherit;">Tuesday, June 09, 2015</time></li></ul><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;"><span style="font-weight: 600; box-sizing: inherit;">Microsoft 专用</span></p><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;">在解释操作系统命令行上给出的参数时，Microsoft C/C++ 启动代码使用下列规则：</p><ul style="padding: 0px; margin: 16px 0px 16px 38px; box-sizing: inherit; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;"><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">参数用空白分隔，空白可以是一个空格或制表符。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">^ 字符 (^) 未被识别为转义符或者分隔符。 该字符在被传递给程序中的 argv 数组前，由操作系统的命令行分析器进行全部处理。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">无论其中是否包含空白，带双引号的字符串 ("<em style="box-sizing: inherit;">string</em>") 均被解释为单个参数。 带引号的字符串可以嵌入在参数内。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">前面有反斜杠的双引号 (\") 被解释为原义双引号字符 (")。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">反斜杠按其原义解释，除非它们紧位于双引号之前。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">如果偶数个反斜杠后跟双引号，则每对反斜杠中有一个反斜杠放置在 argv 数组中，而双引号被解释为字符串分隔符。</p></li><li style="box-sizing: inherit; list-style: disc outside none;"><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px;">如果奇数个反斜杠后跟双引号，则每对反斜杠中有一个反斜杠放置在 argv 数组中，而双引号由剩余那个反斜杠进行&#8220;转义&#8221;，从而将原义双引号 (") 放置在 argv 中。</p></li></ul><h2>示例<a docon-link=""  heading-anchor"="" tabindex="-1" aria-hidden="true" href="https://docs.microsoft.com/zh-cn/previous-versions/17w5ykft(v=vs.120)#示例" style="color: #0065b3; cursor: pointer; text-decoration: none; word-wrap: break-word; box-sizing: inherit; font-family: docons; font-size: 0.8em; speak: none; display: inline-block; font-weight: 400; text-align: center; direction: ltr; line-height: 16px; -webkit-font-smoothing: antialiased; opacity: 0; margin: 0px 0px 4px 10px; vertical-align: middle; visibility: hidden;"></a></h2><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;">以下程序演示如何传递命令行参数：</p><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; line-height: 25px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">// command_line_arguments.cpp // compile with: /EHsc #include &lt;iostream&gt;  using namespace std; int main( int argc,      // Number of strings in array argv           char *argv[],   // Array of command-line argument strings           char *envp[] )  // Array of environment variable strings {     int count;      // Display each command-line argument.     cout &lt;&lt; "\nCommand-line arguments:\n";     for( count = 0; count &lt; argc; count++ )          cout &lt;&lt; "  argv[" &lt;&lt; count &lt;&lt; "]   "                 &lt;&lt; argv[count] &lt;&lt; "\n"; } </code></pre><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;">下表显示示例输入和预期的输出，并在前面的列表中演示规则。</p><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;">分析命令行的结果</p><div style="box-sizing: inherit; overflow-x: auto; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;"><table style="box-sizing: inherit; border-collapse: collapse; border-spacing: 0px; table-layout: auto; width: 681px; font-size: 0.875rem;"><colgroup style="box-sizing: inherit;"><col style="box-sizing: inherit;"><col style="box-sizing: inherit;"><col style="box-sizing: inherit;"><col style="box-sizing: inherit;"></colgroup><thead style="box-sizing: inherit;"><tr style="box-sizing: inherit;"><th style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: bottom; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 1px; font-size: 0.875rem;"><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px;">命令行输入</p></th><th style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: bottom; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 1px; font-size: 0.875rem;"><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px;">argv[1]</p></th><th style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: bottom; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 1px; font-size: 0.875rem;"><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px;">argv[2]</p></th><th style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: bottom; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 1px; font-size: 0.875rem;"><p style="box-sizing: inherit; margin-top: 0px; margin-bottom: 0px;">argv[3]</p></th></tr></thead><tbody style="box-sizing: inherit;"><tr style="box-sizing: inherit;"><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">"abc" d e</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">abc</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">d</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">e</code></pre></td></tr><tr style="box-sizing: inherit;"><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\\b d"e f"g h</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\\b</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">de fg</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">h</code></pre></td></tr><tr style="box-sizing: inherit;"><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\\\"b c d</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\"b</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">c</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">d</code></pre></td></tr><tr style="box-sizing: inherit;"><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\\\\"b c" d e</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">a\\b c</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">d</code></pre></td><td style="box-sizing: inherit; word-wrap: break-word; padding: 12px 16px; line-height: 1.5; vertical-align: top; border-style: solid; border-color: #e3e3e3; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;"><div data-bi-name="code-header" style="box-sizing: content-box; background-color: #f3f3f3; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; font-size: 0.8rem; border-width: 1px 1px 0px; border-top-style: solid; border-right-style: solid; border-left-style: solid; border-top-color: #e3e3e3; border-right-color: #e3e3e3; border-left-color: #e3e3e3; margin-top: 16px; min-height: 30px;"><button data-bi-name="copy" style="font-family: inherit; font-size: inherit; font-style: inherit; font-variant: inherit; margin: 0px; color: #000000; overflow: visible; box-sizing: inherit; cursor: pointer; padding: 2px 10px; border-style: solid; border-color: #e3e3e3; border-width: 0px 0px 0px 1px; display: flex; -webkit-box-align: center; align-items: center;"><span style="box-sizing: inherit;">复制</span></button></div><pre style="line-height: 19px; -webkit-font-smoothing: auto; font-family: monospace, monospace; border: 1px solid #e3e3e3; background-color: #fafafa; font-size: 0.875rem; overflow: auto; padding: 16px; margin-top: 0px; margin-bottom: 0px; direction: ltr; word-spacing: normal; word-break: normal; word-wrap: normal; tab-size: 4; box-sizing: inherit;"><code style="-webkit-font-smoothing: auto; font-family: monospace, monospace; font-size: 0.875rem; direction: ltr; border-top-left-radius: 2px; border-top-right-radius: 2px; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; display: block; padding: 0px; border: 0px; box-sizing: inherit;">e</code></pre></td></tr></tbody></table></div><h2>请参见<a docon-link=""  heading-anchor"="" tabindex="-1" aria-hidden="true" href="https://docs.microsoft.com/zh-cn/previous-versions/17w5ykft(v=vs.120)#请参见" style="color: #0065b3; cursor: pointer; text-decoration: none; word-wrap: break-word; box-sizing: inherit; font-family: docons; font-size: 0.8em; speak: none; display: inline-block; font-weight: 400; text-align: center; direction: ltr; line-height: 16px; -webkit-font-smoothing: antialiased; opacity: 0; margin: 0px 0px 4px 10px; vertical-align: middle; visibility: hidden;"></a></h2><h4>参考<a docon-link=""  heading-anchor"="" tabindex="-1" aria-hidden="true" href="https://docs.microsoft.com/zh-cn/previous-versions/17w5ykft(v=vs.120)#参考" style="color: #0065b3; cursor: pointer; text-decoration: none; word-wrap: break-word; box-sizing: inherit; font-family: docons; font-size: 0.9em; speak: none; display: inline-block; font-weight: 400; text-align: center; direction: ltr; line-height: 16px; -webkit-font-smoothing: antialiased; opacity: 0; margin: 0px 0px 0px 10px; vertical-align: middle; visibility: hidden;"></a></h4><p style="box-sizing: inherit; margin-top: 1rem; margin-bottom: 0px; font-family: 'Segoe UI', SegoeUI, 'Segoe WP', 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif; font-size: 16px; line-height: 25px; background-color: #ffffff;"><a href="https://docs.microsoft.com/zh-cn/previous-versions/6wd819wh%28v%3dvs.120%29" data-linktype="relative-path" style="background-color: transparent; color: #0065b3; cursor: pointer; word-wrap: break-word; box-sizing: inherit;">main：程序启动</a></p></div></div></div><img src ="http://www.cppblog.com/prayer/aggbug/216196.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2019-01-14 09:40 <a href="http://www.cppblog.com/prayer/archive/2019/01/14/216196.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>打印出double类型在内存中的每个位</title><link>http://www.cppblog.com/prayer/archive/2018/11/29/216101.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Thu, 29 Nov 2018 05:50:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/29/216101.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216101.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/29/216101.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216101.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216101.html</trackback:ping><description><![CDATA[<p>printf没有打印二进制。</p><p>自己写了一个，先转成16进制，再转成二进制。</p><p>也可以先转成8进制，再转成二进制。</p><p>我测试环境double是8个字节，64位长度。</p><p>*/</p><p>/*打印出double在内存的中的每一个二进制位<br />*/<br />void DoubleToString(double *p_dl){<br />&nbsp;&nbsp; &nbsp; &nbsp; char c_dl_16[16+1];<br />&nbsp;&nbsp; &nbsp; &nbsp; char c_dl_64[64+1];<br />&nbsp;&nbsp; &nbsp; &nbsp; memset(c_dl_64,'\0',sizeof(c_dl_64));<br />&nbsp;&nbsp; &nbsp; &nbsp; unsigned char *t = (unsigned char *)p_dl;<br />&nbsp;&nbsp; &nbsp; &nbsp; int charCount = sizeof(double) ;<br />&nbsp;&nbsp; &nbsp; &nbsp; memset(c_dl_16,'\0',sizeof(c_dl_16));<br />&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;<br />&nbsp;&nbsp; &nbsp; &nbsp; if (t == NULL)<br />&nbsp; &nbsp; &nbsp; &nbsp;return;<br />&nbsp; &nbsp; &nbsp;int i=0;<br />&nbsp; &nbsp; &nbsp;for(i=0;i&lt;charCount;i++){<br />&nbsp; &nbsp; &nbsp; &nbsp; sprintf(c_dl_16+i*2,"%02x",t[i]);<br />&nbsp; &nbsp; &nbsp;}<br />&nbsp; &nbsp; &nbsp;/*printf("\n"); &nbsp;*/<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("[%s]\n",c_dl_16); &nbsp;<br />&nbsp; &nbsp; &nbsp;/*对每一位，将十六进制转换为二进制的字符串*/<br />&nbsp; &nbsp; &nbsp;char tmpc[4+1];<br />&nbsp; &nbsp; &nbsp;for(int j=0;j&lt;16;j++){<br />&nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; memset(tmpc,'\0',sizeof(tmpc));<br />&nbsp; &nbsp; &nbsp; &nbsp;switch(c_dl_16[j]){<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '0':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;memcpy(tmpc,"0000",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '1':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0001",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '2':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0010",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '3':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0011",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break; &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '4':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0100",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break; &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '5':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0101",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break; &nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '6':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0110",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '7':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"0111",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '8':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1000",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case '9':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1001",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'a':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1010",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'b':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1011",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'c':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1100",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'd':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1101",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'e':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1110",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; case 'f':<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp;memcpy(tmpc,"1111",4);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp;break;<br />&nbsp; &nbsp; &nbsp; &nbsp;}<br />&nbsp; &nbsp; &nbsp; &nbsp;sprintf(c_dl_64+j*4,"%s",tmpc);<br />&nbsp; &nbsp; &nbsp;}<br />&nbsp; &nbsp; &nbsp;printf("[%s]\n",c_dl_64);<br />&nbsp; &nbsp; &nbsp;<br />}<br /><br /></p><p><br /></p><p>使用</p><p>&nbsp; &nbsp; double tmpd=0.01;<br />&nbsp; &nbsp; DoubleToString(&amp;tmpd);<br />&nbsp; &nbsp; printf("%x\n",0.01);</p><img src ="http://www.cppblog.com/prayer/aggbug/216101.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-29 13:50 <a href="http://www.cppblog.com/prayer/archive/2018/11/29/216101.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>机器中float的二进制舍入问题  --很好</title><link>http://www.cppblog.com/prayer/archive/2018/11/28/216099.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 28 Nov 2018 09:34:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/28/216099.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216099.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/28/216099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216099.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216099.html</trackback:ping><description><![CDATA[<div style="box-sizing: inherit; outline: 0px; margin: 0px 0px 8px; word-wrap: break-word; font-size: 12px; color: #999999; font-family: Lato, -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; background-color: #ffffff;">版权声明：转载请注明出处，谢谢	 https://blog.csdn.net/laeen/article/details/51194684</div><div id="content_views" data-find="_1" style="box-sizing: inherit; outline: 0px; margin: 0px; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif; word-wrap: break-word; color: rgba(0, 0, 0, 0.74902); line-height: 23px; background-color: #ffffff; word-break: break-word !important;"><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px 16px 6px 56px; position: relative; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif; overflow-y: hidden; overflow-x: auto; line-height: 22px; color: #000000; word-wrap: break-word; background-color: #f6f8fa; border: none;"><code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0.5em; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif; background-color: rgba(0, 0, 0, 0.0470588); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; display: block; overflow-x: auto; word-wrap: break-word;">                    **机器中float的二进制舍入问题** </code><ul style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px 0px; list-style: none; font-size: inherit; word-wrap: break-word; position: absolute; width: 48px; background-color: #eef0f4; top: 0px; left: 0px;"><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">1</li></ul></pre><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">在计算机中，对于精度取舍的问题一直都比较模糊，到底什么时候要舍去，什么时候要输出，下面我就以计算机中的float型为例子，来简单地说一说float的四舍五&#8220;入&#8221;。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">float型在计算机用32位来表示（4个字节），和计算机表示int长度相同，但是表示的机制完全不一样，它由sign，exp，frac部分组成，也就是我们所说的符号位，阶码位，和小数位。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">具体的表示方法在这里就不细说了（主要谈论舍入问题）。我们知道的四舍五入就是小于5舍去，大于等于5就进位，那么为什么要这样。举个例子：&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />1 2 3 4&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />9 8 7 6 5&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />比如11，如果在个位运用了四舍五入，那么就会产生一个1的误差（丢失1）得到10.还有19，如果个位数是9的话，相应的产生了1的误差（增加1），四舍五入得到20.所以9个数字中1234恰好和9876对应（后面会说到5），我们期望的是在大量的数据下产生的误差中得到和失去的概率近似为1/2，这就有了四舍五入。但是，我们知道5并没有什么数字和它对应，所以增加的期望值要大于减小的期望值，这是我们不希望看到的。&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />但是在计算机中所用的表示方法都是二进制的，1,0出现的概率我们可以认为相等。所以，我们就得到了一个新型的四舍五入的方法，小于所对应精度1/2就舍去，大于就进位，等于就有两种情况，一种情况是最低有效位是1，进位。为0，舍去。（向偶取整）&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />用一道例题来说明：</p><pre name="code" style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px 16px 6px 56px; position: relative; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif; overflow-y: hidden; overflow-x: auto; line-height: 22px; color: #000000; word-wrap: break-word; background-color: #f6f8fa; border: none;"><code cpp=""  has-numbering"="" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif; display: block; overflow-x: auto; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word; color: #4f4f4f !important;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-size: inherit; word-wrap: break-word; color: #009900 !important;">#include&lt;stdio.h&gt;</span> main() {     <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #000088 !important; font-size: inherit; word-wrap: break-word;">float</span> a;                 <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #000088 !important; font-size: inherit; word-wrap: break-word;">double</span> b;                 a = <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #006666 !important; font-size: inherit; word-wrap: break-word;">123456.789e4</span>;                 b = <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #006666 !important; font-size: inherit; word-wrap: break-word;">123456.789e4</span>;                 <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-size: inherit; word-wrap: break-word;">printf</span>(&#8220;%f/n%f/n&#8221;,a,b); }   </code><ul style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px 0px; list-style: none; font-size: inherit; word-wrap: break-word; position: absolute; width: 48px; background-color: #eef0f4; top: 0px; left: 0px;"><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">1</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">2</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">3</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">4</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">5</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">6</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">7</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">8</li><li style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px 8px; font-size: inherit; list-style: none; word-wrap: break-word; color: #999999;">9</li></ul></pre><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">运行结果如下：&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />1234567936.000000&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />1234567890.000000</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;">由于double的尾数位没有进行舍入操作，因此并没有改变原数，但1234567890&gt;2^23-1要进行舍入操作。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; word-wrap: break-word;"><img src="https://img-blog.csdn.net/20160419222515662" alt="这里写图片描述" title="" style="box-sizing: border-box; outline: 0px; margin: 24px 0px; padding: 0px; border-style: none; max-width: 100%; word-wrap: break-word; cursor: -webkit-zoom-in;" />&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />所以就增加了46。</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-28 17:34 <a href="http://www.cppblog.com/prayer/archive/2018/11/28/216099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在linux中install命令和cp命令的区别</title><link>http://www.cppblog.com/prayer/archive/2018/11/28/216098.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 28 Nov 2018 09:03:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/28/216098.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216098.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/28/216098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216098.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216098.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/bugouyonggan/article/details/11962201<br /><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">转：http</span><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">://blog.yikuyiku.com/?p=2659</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">基本上，在Makefile里会用到install，其他地方会用cp命令。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">它们完成同样的任务&#8212;&#8212;拷贝文件，它们之间的区别主要如下：</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">1、最重要的一点，如果目标文件存在，cp会先清空文件后往里写入新文件，而install则会先删除掉原先的文件然后写入新文件。这是因为往正在 使用的文件中写入内容可能会导致一些问题，比如说写入正在执行的文件可能会失败，比如说往已经在持续写入的文件句柄中写入新文件会产生错误的文件。而使用 install先删除后写入（会生成新的文件句柄）的方式去安装就能避免这些问题了；</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">2、install命令会恰当地处理文件权限的问题。比如说，install -c会把目标文件的权限设置为rwxr-xr-x；</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">3、install命令可以打印出更多更合适的debug信息，还会自动处理SElinux上下文的问题。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">转：http://blog.csdn.net/stevenliyong/article/details/4663583</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">install&nbsp; - copy files and set attributes</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">install 在做拷贝的同时，设置attributes.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">因此Makefile 中尽量使用install 命令。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">例如</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@install&nbsp;-d /usr/bin</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@install -p -D -m 0755 targets /usr/bin</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">相当于</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@mkdir -p /usr/bin</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@cp targets /usr/bin</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@chmod 755 /usr/bin/targets</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">@touch /usr/bin/tagets&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;---- 更新文件时间戳</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">install 命令好强大啊。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">另外@前缀的意思是不在控制台输出结果。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; background-color: #ffffff;">转载:http://www.cnblogs.com/wwwsinagogogo/archive/2011/08/15/2139124.html</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; color: #4f4f4f; overflow-x: auto; word-wrap: break-word; font-family: 'black verdana';">&nbsp;</p><div id="cnblogs_post_body" style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; font-family: 'black verdana';"><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">【概述】</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">Install和cp类似，都可以将文件/目录拷贝到指定的地点。但是，install允许你控制目标文件的属性。install通常用于程序的makefile，使用它来将程序拷贝到目标（安装）目录。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">【语法】</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install [OPTION]... [-T] SOURCE DEST</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install [OPTION]... SOURCE... DIRECTORY</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install [OPTION]... -t DIRECTORY SOURCE...</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install [OPTION]... -d DIRECTORY...</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">*如果指定了两个文件名, `install' 将第一个文件拷贝到第二个</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">* 如果使用了 `--target-directory' (`-t') 选项，或者如果最后一个文件是一个目录并且没有使用`--no-target-directory' (`-T')选项， `install'将每一个源文件拷贝到指定的目录，目标文件名与SOURCE文件名相同。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">* 如果使用了 `--directory' (`-d') 选项, `install' 将逐级创建缺失的目标目录</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">【常用选项】</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-s:对待拷贝的可执行文件进行strip操作，取出文件中的符号表。（一般在做成nand rom时去除符号表，NFS时为了调试方便，一般不会使用此选项）</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-d(--directory)：创建制定的目录结构（逐级创建）。如，指定安装位置为/usr/local/aaa/bbb，/usr/loacal已存在，install会帮助我们创建aaa和bbb目录，并把程序安装到指定位置</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff;"></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">If we hand write a&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">Makefile</code>, we should always stick to&nbsp;<a href="http://linux.die.net/man/1/install" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">install</a>&nbsp;instead of using&nbsp;<a href="http://linux.die.net/man/1/cp" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">cp</a>&nbsp;for the installation commands. Not only is it more convenient, but it does things right (cp does things&nbsp;<em style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">wrong</em>).</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">For example, if we attempt to update&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">/bin/bash</code>, which is currently running, with &#8220;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">cp ... /bin/bash</code>&#8221;, we get a &#8220;text busy&#8221; error. If we attempt to update&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">/lib/libc.so.6</code>&nbsp;with &#8220;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">cp ... /lib/libc.so.6</code>&#8221;, then we either get &#8220;text busy&#8221; (in ancient versions of Linux) or breaks each and every running program within a fraction of a second (in recent versions of Linux).&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">install</code>&nbsp;does the thing right in both situations.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">The reason why&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">cp</code>&nbsp;fails is that it simply attempts to open the destination file in write-only mode and write the new contents. This causes problem because Linux (and all contemporary&nbsp;<a href="http://en.wikipedia.org/wiki/Unix-like" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">Unices</a>&nbsp;as well as Microsoft Windows) uses&nbsp;<a href="http://en.wikipedia.org/wiki/Memory-mapped_file" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">memory mapping</a>&nbsp;(mmap) to load executables and dynamic libraries.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">The contents of an executable or dynamic library are mmap&#8217;d into the linear address space of relevant processes. Therefore, any change in the underlying file affects the mmap&#8217;d memory regions and can potentially break programs. (<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_PRIVATE</code>&nbsp;guarantees changes by processes to those memory regions are handled by&nbsp;<a href="http://en.wikipedia.org/wiki/Copy-on-write" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">COW</a>without affecting the underlying file. On the contrary,&nbsp;<a href="http://en.wikipedia.org/wiki/POSIX" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">POSIX</a>&nbsp;leaves to implementations whether COW should be used if the underlying file is modified. In fact, for purpose of efficiency, in Linux, such modifications are&nbsp;<em style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">visible</em>&nbsp;to processes even though&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_PRIVATE</code>&nbsp;may have be used.)</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">There is an option&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_DENWRITE</code>&nbsp;which disallows any modification to the underlying file, designed to avoid situations described above. Executables and dynamic libraries are all mmap&#8217;d with this option. Unfortunately, it turned out&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_DENYWRITE</code>&nbsp;became a source of&nbsp;<a href="http://en.wikipedia.org/wiki/Denial-of-service_attack" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">DoS attacks</a>, forcing Linux to ignore this option in recent versions.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">Executables are mmap&#8217;d by the kernel (in the&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">execve</code>&nbsp;<a href="http://en.wikipedia.org/wiki/System_call" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">syscall</a>). For kernel codes,&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_DENYWRITE</code>&nbsp;still works, and therefore we get &#8220;text busy&#8221; errors if we attempt to modify the executable.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">On the other hand, dynamic libraries are mmap&#8217;d by userspace codes (for example, by loaders like&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">/lib/ld-linux.so</code>). These codes still pass&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">MAP_DENYWRITE</code>&nbsp;to the kernel, but newer kernels silently ignores this option. The bad consequence is that you can break the whole system if you think you&#8217;re only upgrading the&nbsp;<a href="http://en.wikipedia.org/wiki/C_standard_library" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">C runtime library</a>.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">Then, how does&nbsp;<code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; word-wrap: break-word;">install</code>&nbsp;solve this problem? Very simple &#8211;&nbsp;<a href="http://en.wikipedia.org/wiki/Unlink_(Unix)" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">unlinking</a>&nbsp;the file before writing the new one. Then the old file (no longer present in directory entries but still in disk until the last program referring to it exits) and the new file have different&nbsp;<a href="http://en.wikipedia.org/wiki/Inode" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;">inodes</a>. Programs started before the upgrading (continuing using the old file) and those after the upgrading (using the new version) will both be happy.</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 13px; color: #4f4f4f; line-height: 18px; overflow-x: auto; word-wrap: break-word; background-color: #ffffff; font-family: Verdana, Tahoma, 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 14px; line-height: 23px;">记得在大学的时候在编译LFS 6 的时候, 一直搞不懂 install 的命令 和 cp 以及和 chmod, chgrp 的区别?　</span></p><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">工作之后才明白一个Running 的进程不能随便进行 cp , 经常会提示 &nbsp;"text busy＂, 运维部的前辈们给的建议是采用mv 来替代 cp , 今天看起来前辈好像不知道install 这个命令啊.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">今天就简单介绍一下 install 命令.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />install copy 文件列表且同时能够设置文件的属性(包括 owner, group) , 通常用在 Makefiles 中 用来copy 程序到指定的目录. &nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">常见的用法有以下3中形式:　</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">1: &nbsp;install &nbsp;-d [option] &nbsp; DIRECTORY [DIRECTORY...] &nbsp;支持多个. 类似 mkdir -p &nbsp;支持递归.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">例如: &nbsp;install -d a/b/c e/f &nbsp;结果和 mkdir -p &nbsp;a/b/c &nbsp;e/f 一样. &nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">2: install [option] &nbsp;SOURCE DEST&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">复制 SOURCE &nbsp;文件(测试不能是目录) &nbsp; 到DEST file(文件) .&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install &nbsp;a/e &nbsp; c &nbsp; 结果类似 &nbsp;cp &nbsp;a/e &nbsp;c &nbsp; # 注意c必须是文件.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">有用选项 -D</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install -D x a/b/c &nbsp; &nbsp;# 效果类似 mkdir -p a/b &nbsp;&amp;&amp; cp &nbsp;x a/b/c &nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">3: install [option] &nbsp;SOURCE [SOURCE...] DIRECTORY</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">复制 &nbsp;多个SOURCE 文件到目的目录. &nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install a/* &nbsp;d &nbsp; 其中 d 是目录.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">有用选项</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">&nbsp;-b ：自动备份.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-m : 设置安装文件的权限</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-p :保留文件的timestamps. 也就是说文件的timestaamps 和 source 文件一样. &nbsp;当我们想要利用安装文件的mtime来跟踪文件的build时间而不是 安装时间.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-s :&nbsp;Strip the symbol tables from installed binary executables.</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-S : 备份文件的后缀.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">install &nbsp;-S .bak new &nbsp;old &nbsp;#old 文件自动被 mv 为 old.bak.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-v: verbose ,打印install 的文件的详细信息.&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">`-c'</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">&nbsp; &nbsp; &nbsp;Ignored; for compatibility with old Unix versions of `install'. &nbsp;#用来兼容旧版的unix.&nbsp;</span></div></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">-C: (大写)&nbsp;</span></div><div style="box-sizing: border-box; outline: 0px; margin: 0px; word-wrap: break-word; color: #333333; background-color: #ffffff; line-height: 23px; font-family: Arial, Helvetica, simsun, u5b8bu4f53;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">安装文件, 但是如果目标文件和源文件一样( 判断方法需要看看代码确认) 就跳过, 这样的好处是 能够保持一样文件的mtime. &nbsp;</span></div><div><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;"><br /></span></div></div></div><img src ="http://www.cppblog.com/prayer/aggbug/216098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-28 17:03 <a href="http://www.cppblog.com/prayer/archive/2018/11/28/216098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux下So覆盖导致coredump问题的分析</title><link>http://www.cppblog.com/prayer/archive/2018/11/28/216097.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 28 Nov 2018 09:01:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/28/216097.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216097.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/28/216097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216097.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216097.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/chuanhehuan1/article/details/40651891<br /><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">转自：http://blog.sina.com.cn/s/blog_622a99700100pjv3.html 感谢这位大神，我刚好遇到这个问题</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">尝试解答以下问题：</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.为什么cp的方式更新运行中进程的so，程序会coredump</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.采用什么方式更新已经加载了的so,就可以避免coredump</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">我们的公共组件绝大部分都支持so形式的自定义插件，比如s++,qzhttp,ttc。在不停进程更新so的时候往往会产生coredump，并且肯定core得莫名其妙，core得让人心碎。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">先看一下用cp的方式更新so的时候发生了什么事情</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">strace cp new.so old.so</span>&nbsp;<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; color: #008080;">#strace</span><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word; color: #008080;">是人间利器</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><a href="http://photo.blog.sina.com.cn/showpic.html#blogid=622a99700100pjv3&amp;url=http://s10.sinaimg.cn/orignal/622a9970g7637a02e3389" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;"><img src="http://s10.sinaimg.cn/middle/622a9970g7637a02e3389&amp;690" alt="linux下So覆盖导致coredump问题的分析" title="linux下So覆盖导致coredump问题的分析" height="90" width="536" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 0px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">发现老的so被trunc了，这个过程发生的具体的事情是：</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1.应用程序通过dlopen打开so的时候，kernel通过mmap把so加载到进程地址空间，对应于vma里的几个page.</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2.在这个过程中loader会把so里面引用的外部符号例如malloc printf等解析成真正的虚存地址。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.当so被cp覆盖时，确切地说是被trunc时，kernel会把so文件在虚拟内的页purge 掉。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4.当运行到so里面的代码时，因为物理内存中不再有实际的数据（仅存在于虚存空间内），会产生一次缺页中断。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.Kernel从so文件中copy一份到内存中去,a)但是这时的全局符号表并没有经过解析，当调用到时就产生segment fault ,&nbsp;b)如果需要的文件偏移大于新的so的地址范围，就会产生buserror.</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">所以，如果用相同的so去覆盖</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A) 如果so里面依赖了外部符号，coredump</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B) 如果so里面没有依赖外部符号，运气不错，不会coredump</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">所有问题的产生都是因为so被trunc了一把，所以如果不用turnc的方式就避免这个问题。Ok,该我们的install 上场了。</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; font-weight: 700; word-wrap: break-word;">strace install new.so old.so</span></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;"><a href="http://photo.blog.sina.com.cn/showpic.html#blogid=622a99700100pjv3&amp;url=http://s10.sinaimg.cn/orignal/622a9970g9e2c446138d9" rel="nofollow" target="_blank" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #6795b5; text-decoration: none; cursor: pointer; word-wrap: break-word;"><img src="http://s10.sinaimg.cn/middle/622a9970g9e2c446138d9&amp;690" name="image_operate_46561299813150712" alt="linux下So覆盖导致coredump问题的分析" title="linux下So覆盖导致coredump问题的分析" height="111" width="547" style="box-sizing: border-box; outline: #0782c1 solid 1px; margin: 0px; padding: 1px; max-width: 100%; border: none; word-wrap: break-word; cursor: -webkit-zoom-in;" /></a><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /><br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" /></p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">install 的方式跟cp不同，先unlink再creat，当unlink的时候，已经map的虚拟空间vma中的inode结点没有变，只有inode结点的引用计数为0是，kernel才把它干掉。</p><span style="color: #333333; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">也就是新的so和旧的so用的不是同一个inode结点，所以不会相互影响。这时只有得启程序才会使用到新的so。所以采用这种方式的话就可以避免先stop进程，更新so，再重启进程这样比较耗时的操作。</span></div><img src ="http://www.cppblog.com/prayer/aggbug/216097.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-28 17:01 <a href="http://www.cppblog.com/prayer/archive/2018/11/28/216097.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Makefile中用宏定义进行条件编译</title><link>http://www.cppblog.com/prayer/archive/2018/11/28/216096.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 28 Nov 2018 07:55:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/28/216096.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216096.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/28/216096.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216096.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216096.html</trackback:ping><description><![CDATA[<div>https://blog.csdn.net/gdutliuyun827/article/details/17297513<br /><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">在源代码里面如果这样是定义的：&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />#ifdef&nbsp;&nbsp; MACRONAME&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />//可选代码&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />#endif</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">那在makefile里面&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />gcc&nbsp;&nbsp; -D&nbsp;&nbsp; MACRONAME=MACRODEF&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />或者&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />gcc&nbsp;&nbsp; -D&nbsp;&nbsp; MACRONAME</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">这样就定义了预处理宏，编译的时候可选代码就会被编译进去了。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">对于GCC编译器，有如下选项：&nbsp;<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -D macro=string，等价于在头文件中定义：#define&nbsp;&nbsp; macro&nbsp;&nbsp; string。例如：-D TRUE=true，等价于：#define&nbsp;&nbsp; TRUE&nbsp;&nbsp; true<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -D macro，等价于在头文件中定义：#define&nbsp;&nbsp; macro&nbsp;&nbsp; 1，实际上也达到了定义：#define&nbsp;&nbsp; macro的目的。例如：-D LINUX，等价于：#define&nbsp;&nbsp; LINUX&nbsp;&nbsp; 1（与#define&nbsp;&nbsp; LINUX作用类似）。<br style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --define-macro&nbsp;&nbsp; macro=string与-D macro=string作用相同。</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">如：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; line-height: 22px; background-color: #ffffff;"><code hljs"="" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px; display: block; overflow-x: auto; color: #abb2bf; background-color: #282c34; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; white-space: pre; word-wrap: break-word; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif;">TEST.C 文件   <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">include</span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #98c379; word-wrap: break-word;">&lt;stdio.h&gt;</span></span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">include</span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #98c379; word-wrap: break-word;">&lt;stdlib.h&gt;</span></span>  main() { <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">ifdef</span> p1</span>   <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #e6c07b; word-wrap: break-word;">printf</span>(<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #98c379; word-wrap: break-word;">"Hello p1"</span>); <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">else</span></span>   <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #e6c07b; word-wrap: break-word;">printf</span>(<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #98c379; word-wrap: break-word;">"Hello p2"</span>); <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">endif</span></span>    } </code></pre><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">1.</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">编译： gcc -o test test.c</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">运行： ./test</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">输出： Hello p2</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">2.</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">编译： gcc -o test test.c -D p1</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">运行： ./test</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">输出： Hello p1</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">&nbsp;</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">还有另外一种使用方式：</p><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">Makefile写法：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; line-height: 22px; background-color: #ffffff;"><code style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; display: block; overflow-x: auto; white-space: pre; word-wrap: break-word; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif;">$(SERVER_NAME):$(SERVER_OBJ) $(COM_OBJS) 	$(CC) -Wall -pthread -D KRC_SERVER_NAME=$(SERVER_NAME)_FLAG</code></pre><p style="box-sizing: border-box; outline: 0px; margin: 0px 0px 16px; padding: 0px; font-size: 16px; color: #4f4f4f; line-height: 26px; overflow-x: auto; word-wrap: break-word; font-family: -apple-system, 'SF UI Text', Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif, SimHei, SimSun; background-color: #ffffff;">C代码中用法：</p><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; line-height: 22px; background-color: #ffffff;"><code hljs"="" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px; display: block; overflow-x: auto; color: #abb2bf; background-color: #282c34; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; white-space: pre; word-wrap: break-word; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif;"><span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">if</span> KRC_SERVER_NAME == krc_search_FLAG</span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">elif</span> KRC_SERVER_NAME == krc_feedback_FLAG</span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">else</span></span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">endif</span></span>  注意：其中的两个参数为宏定义，不能使用常量定义，因为需要在预编译阶段就要确定其值！ <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">define</span> krc_search_FLAG     1</span> <span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; color: #61aeee; word-wrap: break-word;">#<span style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 0px; word-wrap: break-word;">define</span> krc_feedback_FLAG   2</span></code><div data-title="复制" style="box-sizing: border-box; outline: 0px; margin: 8px; padding: 2px 8px; position: absolute; right: 4px; top: 4px; font-size: 12px; color: #4d4d4d; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; cursor: pointer; box-shadow: rgba(0, 0, 0, 0.0470588) 0px 2px 4px, rgba(0, 0, 0, 0.0470588) 0px 2px 4px; word-wrap: break-word;"></div></pre><pre style="box-sizing: border-box; outline: 0px; margin-top: 0px; margin-bottom: 24px; padding: 8px; position: relative; white-space: pre-wrap; word-wrap: break-word; overflow-x: auto; font-family: Consolas, Inconsolata, Courier, monospace; line-height: 22px; background-color: #ffffff;"><code hljs"="" style="box-sizing: border-box; outline: 0px; margin: 0px; padding: 8px; display: block; overflow-x: auto; color: #abb2bf; background-color: #282c34; border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; white-space: pre; word-wrap: break-word; font-family: 'Source Code Pro', 'DejaVu Sans Mono', 'Ubuntu Mono', 'Anonymous Pro', 'Droid Sans Mono', Menlo, Monaco, Consolas, Inconsolata, Courier, monospace, 'PingFang SC', 'Microsoft YaHei', sans-serif;">这种用法也能实现条件编译的作用，而且更好！</code></pre></div><img src ="http://www.cppblog.com/prayer/aggbug/216096.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-28 15:55 <a href="http://www.cppblog.com/prayer/archive/2018/11/28/216096.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>程序的静态链接，动态链接和装载</title><link>http://www.cppblog.com/prayer/archive/2018/11/28/216095.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 28 Nov 2018 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2018/11/28/216095.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/216095.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2018/11/28/216095.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/216095.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/216095.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">参考自：<a href="http://www.xuebuyuan.com/1730287.html" target="_blank" style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;">http://www.xuebuyuan.com/1730287.html</a></strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;"><strong style="margin: 0px; padding: 0px;">一、程序编译链接的整体流程</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;"><strong style="margin: 0px; padding: 0px;">二、目标文件的样子（以linux下的elf文件格式为例）</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;"><strong style="margin: 0px; padding: 0px;">三、静态链接</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;"><strong style="margin: 0px; padding: 0px;">四、装载</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;"><strong style="margin: 0px; padding: 0px;">五、动态链接</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">一、程序编译链接的整体流程</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">通常我们使用gcc来生成可执行程序，命令为：gcc hello.c，默认生成可执行文件a.out</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">其实编译（包括链接）的命令：gcc hello.c 可分解为如下4个大的步骤：</p><ul style="margin: 0px 0px 0px 30px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><ul style="margin: 0px 0px 0px 30px; padding: 0px;"><li style="margin: 0px; padding: 0px; list-style: circle;"><strong style="margin: 0px; padding: 0px;">预处理</strong>(Preprocessing)</li><li style="margin: 0px; padding: 0px; list-style: circle;"><strong style="margin: 0px; padding: 0px;">编译</strong>(Compilation)</li><li style="margin: 0px; padding: 0px; list-style: circle;"><strong style="margin: 0px; padding: 0px;">汇编</strong>(Assembly)</li><li style="margin: 0px; padding: 0px; list-style: circle;"><strong style="margin: 0px; padding: 0px;">链接</strong>(Linking)</li></ul></ul><div id="attachment_354"  alignnone"="" style="margin: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><a href="http://smilejay.com/2012/01/c_compilation_stages/gcc_compilation_stages/" rel="attachment wp-att-354" style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;"><img wp-image-354"="" title="gcc_compilation_stages" src="http://smilejay.b0.upaiyun.com/wp-content/uploads/2012/01/gcc_compilation_stages.jpg" alt="gcc compilation" width="554" height="267" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></a><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">gcc compilation</p></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong><strong style="margin: 0px; padding: 0px;">预处理(Preproceessing)</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">预处理的过程主要处理包括以下过程：</strong></p><ul style="margin: 0px 0px 0px 30px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><li style="margin: 0px; padding: 0px; list-style: disc;">将所有的#define删除，并且<strong style="margin: 0px; padding: 0px;">展开所有的宏定义</strong></li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">处理</strong>所有的<strong style="margin: 0px; padding: 0px;">条件预编译指令</strong>，比如#if #ifdef #elif #else #endif等</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">处理#include</strong>&nbsp;预编译指令，将被包含的文件插入到该预编译指令的位置。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">删除所有注释&nbsp;</strong>&#8220;//&#8221;和&#8221;/* */&#8221;.</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">添加行号和文件标识</strong>，以便编译时产生调试用的行号及编译错误警告行号。</li><li style="margin: 0px; padding: 0px; list-style: disc;">保留所有的<strong style="margin: 0px; padding: 0px;">#pragma</strong><strong style="margin: 0px; padding: 0px;">编译器指令</strong>，因为编译器需要使用它们</li></ul><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">通常使用以下命令来进行预处理：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">gcc -E hello.c -o hello.i</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">参数<strong style="margin: 0px; padding: 0px;">-E</strong>表示只进行预处理 或者也可以使用以下指令完成预处理过程</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">cpp hello.c &gt; hello.i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* &nbsp;cpp &#8211; The C Preprocessor&nbsp; */</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">直接cat hello.i 你就可以看到预处理后的代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong><strong style="margin: 0px; padding: 0px;">编译(Compilation)</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">编译过程就是把预处理完的文件进行一系列的词法分析，语法分析，语义分析及优化后生成相应的汇编代码。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">$gcc &#8211;S hello.i &#8211;o hello.s</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">或者</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">$ /usr/lib/gcc/i486-linux-gnu/4.4/cc1 hello.c</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">注：现在版本的GCC把预处理和编译两个步骤合成一个步骤，用cc1工具来完成。gcc其实是后台程序的一些包装，根据不同参数去调用其他的实际处理程序，比如：预编译编译程序cc1、汇编器as、连接器ld</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong><strong style="margin: 0px; padding: 0px;">汇编(Assembly)</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">汇编器是将汇编代码转变成机器可以执行的命令，每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单，根据汇编指令和机器指令的对照表一一翻译即可。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">$ gcc &#8211;c hello.c &#8211;o hello.o</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">或者</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">$ as hello.s &#8211;o hello.co</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">由于hello.o的内容为机器码，不能以普通文本形式的查看（vi 打开看到的是乱码）。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong><strong style="margin: 0px; padding: 0px;">链接(Linking)</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">通过调用链接器ld来链接程序运行需要的一大堆目标文件，以及所依赖的其它库文件，最后生成可执行文件。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">ld -static crt1.o crti.o crtbeginT.o hello.o -start-group -lgcc -lgcc_eh -lc-end-group crtend.o crtn.o (省略了文件的路径名)。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">helloworld的大体编译和链接过程就是这样了，那么编译器和链接器到底做了什么呢？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">编译过程可分为6</strong><strong style="margin: 0px; padding: 0px;">步：扫描（词法分析）、语法分析、语义分析、源代码优化、代码生成、目标代码优化。</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">词法分析：扫描器（Scanner）将源代的字符序列分割成一系列的记号（Token）。lex工具可实现词法扫描。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">语法分析：语法分析器将记号（Token）产生语法树（Syntax Tree）。yacc工具可实现语法分析(yacc: Yet Another Compiler Compiler)。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">语义分析：静态语义（在编译器可以确定的语义）、动态语义（只能在运行期才能确定的语义）。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">源代码优化：源代码优化器(Source Code Optimizer)，将整个语法书转化为中间代码（Intermediate Code）（中间代码是与目标机器和运行环境无关的）。中间代码使得编译器被分为前端和后端。编译器前端负责产生机器无关的中间代码；编译器后端将中间代码转化为目标机器代码。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">目标代码生成：代码生成器(Code Generator).</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">目标代码优化：目标代码优化器(Target Code Optimizer)。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">链接的主要内容是把各个模块之间相互引用的部分处理好，使得各个模块之间能够正确地衔接。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">链接的主要过程包括：地址和空间分配（Address and Storage Allocation），符号决议（Symbol Resolution），重定位（Relocation）等。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">链接分为静态链接和动态链接。</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">静态链接</strong>是指在编译阶段直接把静态库加入到可执行文件中去，这样可执行文件会比较大。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">而<strong style="margin: 0px; padding: 0px;">动态链接</strong>则是指链接阶段仅仅只加入一些描述信息，而程序执行时再从系统中把相应动态库加载到内存中去。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">静态链接的大致过程如下图所示：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><a href="http://smilejay.com/2012/01/c_compilation_stages/linking/" rel="attachment wp-att-355" style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;"><img wp-image-355"="" title="static linking" src="http://smilejay.b0.upaiyun.com/wp-content/uploads/2012/01/linking.jpg" alt="static linking" width="467" height="675" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></a></p><div style="margin: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><dl id="attachment_355"  alignnone"="" style="margin: 0px; padding: 0px;"><dd style="margin: 0px; padding: 0px;">static linking</dd></dl></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><br style="margin: 0px; padding: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px;">二、目标文件的样子（以linux下的elf文件格式为例）</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp;</p><div id="embody" style="margin: 0px -20px; padding: 10px; border-bottom-style: solid; border-bottom-width: 1px; border-bottom-color: #ededed; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><div id="lib" style="margin: 0px 10px 0px 0px; font-size: 12px; display: inline-block;">&nbsp;</div></div><div id="article_content" style="margin: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><img src="http://img.my.csdn.net/uploads/201302/02/1359777256_5685.jpg" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">夹在<strong style="margin: 0px; padding: 0px;">ELF头</strong>和<strong style="margin: 0px; padding: 0px;">节头部表</strong>之间的都是节。一个典型的ELF可重定位目标文件包含下面几个节：</p><ul style="margin: 0px 0px 0px 30px; padding: 0px;"><li style="margin: 0px; padding: 0px; list-style: disc;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><strong style="margin: 0px; padding: 0px;">.text</strong></span>：已编译程序的机器代码。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">.rodata</strong>：只读数据，比如printf语句中的格式串和开关（switch）语句的跳转表。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><strong style="margin: 0px; padding: 0px;">.data</strong></span>：已初始化的全局C变量。局部C变量在运行时被保存在栈中，既不出现在.data中，也不出现在.bss节中。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><strong style="margin: 0px; padding: 0px;">.bss</strong></span>：未初始化的全局C变量。在目标文件中这个节不占据实际的空间，它仅仅是一个占位符。目标文件格式区分<strong style="margin: 0px; padding: 0px;">初始化</strong>和<strong style="margin: 0px; padding: 0px;">未初始化</strong>变量是为了空间效率在：在目标文件中，未初始化变量不需要占据任何实际的磁盘空间。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><strong style="margin: 0px; padding: 0px;">.symtab</strong>：<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #333300;">一个符号表（symbol table），它存放在程序中被<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">定义</span>和<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">引用</span>的<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">函数和全局变量（包括引用到的外部变量和函数，不含有局部变量）</span>的信息。一些程序员错误地认为必须通过-g选项来编译一个程序，得到符号表信息。实际上，每个可重定位目标文件在.symtab中都有一张符号表。然而，和编译器中的符号表不同，.symtab符号表不包含局部变量的表目。</span></span></li><li style="margin: 0px; padding: 0px; list-style: disc;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><strong style="margin: 0px; padding: 0px;">.rel.text</strong></span>：当链接噐把这个目标文件和其他文件结合时，.text节中的许多位置都需要修改。一般而言，<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">任何调用外部函数或者引用全局变量（包括本目标文件内的全局变量，因为在链接时要多个目标文件的相同段合并，这样数据的地址就会改变，所以要重定位）的指令都需要修改</span>。另一方面调用本地函数的指令则不需要修改。注意，可执行目标文件中并不需要重定位信息，因此通常省略，除非使用者显式地指示链接器包含这些信息。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">.rel.data</strong>：被模块定义或引用的任何全局变量的信息。一般而言，任何已初始化全局变量的初始值是全局变量或者外部定义函数的地址都需要被修改。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">.debug</strong>：一个调试符号表，其有些表目是程序中定义的局部变量和类型定义，有些表目是程序中定义和引用的全局变量，有些是原始的C源文件。只有以-g选项调用编译驱动程序时，才会得到这张表。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">.line</strong>：原始C源程序中的行号和.text节中机器指令之间的映射。只有以-g选项调用编译驱动程序时，才会得到这张表。</li><li style="margin: 0px; padding: 0px; list-style: disc;"><strong style="margin: 0px; padding: 0px;">.strtab</strong>：一个字符串表，其内容包括.symtab和.debug节中的符号表，以及节头部中的节名字。字符串表就是以null结尾的字符串序列。</li></ul><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">旁注：为什么未初始化的数据称为.bss?</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用术语.bss来表示未初始化的数据是很普遍的。它起始于IBM 704汇编语言（大约在1957年）中&#8221;块存储开始（Block Storage Start）&#8220;指令的首字母缩写，并沿用至今。一个记住区分.data和.bss节的简单方法是把&#8220;bss&#8221;看成是&#8220;更好地节省空间（Better Save Space）！&#8220;的缩写。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">三、静态链接</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">虚拟存储器是建立在主存--辅存物理结构基础上，有附加的硬件装置及操作系统存储管理软件组成的一种存储体系。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><img src="http://hi.csdn.net/attachment/201011/28/0_1290943844z9zN.gif" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">顾名思义，虚拟存储器是虚拟的存储器，它其实是不存在的，而仅仅是由一些硬件和软件管理的一种&#8220;系统&#8221;。他提供了三个重要的能力：1，它将主存看成一个存储在磁盘上的地址空间的高速缓存，在主存中只保存活动区域，并根据需要在磁盘和主存之间来回传送数据（这里存在&#8220;交换空间&#8221;以及&#8220;页面调度&#8221;等概念），通过这种方式，高效地利用主存；2，它为每个进程提供了统一的地址空间（以虚拟地址编址），从而简化了存储器管理；3，操作系统会为每个进程提供独立的地址空间，从而保护了每个进程的地址空间不被其他进程破坏。&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">虚拟存储器与虚拟地址空间是两个不同的概念：虚拟存储器是假想的存储器，而虚拟存储空间是假想的内存。它们之间的关系应该与主存储器与内存空间之间的关系类似。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">链接部分：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">链接就是将不同部分的<span style="margin: 0px; padding: 0px; line-height: 1.8;"><a title="代码" href="http://www.xuebuyuan.com/" target="_blank" style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;">代码</a>和数据收集和组合成一个单一文件的过程，也就是把不同目标文件合并成最终可执行文件的过程。当然，务必知道：这个过程不涉及内存。链接可以分为三种情形：1，编译时链接，也就是我们常说的静态链接；2，装载时链接；3，运行时链接。装载时链接和运行时链接合称为动态链接。在此，我们的链接部分将主要讲述静态链接，而装载时链接我们放在装载部分讲，运行时链接忽略。</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1、什么是静态链接？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">静态链接就是将多个目标文件组合在一起形成一个可执行文件，如将a.o 和 b.o 链接在一起形成 可执行文件ab。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">2、静态链接的过程包括哪几个部分？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 静态链接包括两个大部分：一是空间和地址的分配；二是符号解析和重定位</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">（1）空间和地址的分配</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">编译器在将a.o 和 b.o 是如何合并在一起的？？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">第二种方法就是 相似段合并：顾名思义 就是把不同目标文件的相同名字的段合并成一个段，如下图：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><img src="https://images2015.cnblogs.com/blog/376860/201608/376860-20160806114729590-1085295555.png" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　　　　　　　　　　　　　　　　　　　　　图1</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">这是编译器实际进行合并目标文件的策略。</strong></p><div style="margin: 5px 0px; color: #000000; font-size: 12px !important;"><div style="margin: 5px 0px 0px;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.8;"><a title="复制代码" style="margin: 0px; padding: 0px; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">/*a.c*/<br style="margin: 0px; padding: 0px;" />extern</span> <span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">int</span><span style="margin: 0px; padding: 0px; line-height: 1.8;"> shared; </span><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">int</span><span style="margin: 0px; padding: 0px; line-height: 1.8;"> main() { </span><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">int</span> a = <span style="margin: 0px; padding: 0px; line-height: 1.8; color: #800080;">100</span><span style="margin: 0px; padding: 0px; line-height: 1.8;">; swap(</span>&amp;a,&amp;<span style="margin: 0px; padding: 0px; line-height: 1.8;">shared); }</span></pre><div style="margin: 5px 0px 0px;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.8;"><a title="复制代码" style="margin: 0px; padding: 0px; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><div style="margin: 5px 0px; color: #000000; font-size: 12px !important;"><div style="margin: 5px 0px 0px;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.8;"><a title="复制代码" style="margin: 0px; padding: 0px; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: 'Courier New' !important;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">/*b.c*/<br style="margin: 0px; padding: 0px;" />int</span> shared = <span style="margin: 0px; padding: 0px; line-height: 1.8; color: #800080;">1</span><span style="margin: 0px; padding: 0px; line-height: 1.8;">; </span><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">void</span> swap(<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">int</span> *a,<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">int</span> *<span style="margin: 0px; padding: 0px; line-height: 1.8;">b) {    </span>*a ^= *b ^= *a ^= *<span style="margin: 0px; padding: 0px; line-height: 1.8;">b; }  </span></pre><div style="margin: 5px 0px 0px;"><span style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.8;"><a title="复制代码" style="margin: 0px; padding: 0px; border: none !important;"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="margin: 0px; padding: 0px; max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">编译这两个文件得到&#8220;a.o&#8221;和&#8220;b.o&#8221;两个目标文件</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&#167;gcc&nbsp;-c&nbsp;a.c&nbsp;b.c</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">从代码中可以看到三个符号：share，swap和main。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">静态链接的整个过程分为两步:<br style="margin: 0px; padding: 0px;" />&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">第一步：空间和地址分配。扫描所有的输入目标文件，获得他们的各个段的长度、属性和位置，并且将输入目标文件中的符号表中所有的符号定义和符号引用收集起来，统一放到一个全局符号表。这样，连接器将能够获得所有输入目标文件的段长度，并且将它们合并，计算出输出文件中各个段合并后的长度与位置，并建立映射关系。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">这里可能会有一个问题：建立了什么样的映射关系。如上面的图1，你可能就会有所了解。映射关系就是指可执行文件与进程虚拟地址空间之间的映射。那么，这里程序还没有执行，更不会出现进程，哪里来的进程地址空间呢？此时虚拟存储器便发挥了很大的作用：虽然此时没有进程，但是每个进程的虚拟地址空间的格式都是一致的。所以，为可执行文件的每个段甚至每个符号符号分配地址也就不会有什么错了。注意：在链接之前，目标文件中的所有段的虚拟地址都是0，因为虚拟空间还没有被分配，默认都为0.等到链接之后，可执行文件中的各个段已经都被分配到了相应的虚拟地址</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">第二步：符号解析与重定位</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">首先，符号解析。解析符号就是将每个符号引用与它输入的可重定位目标文件中的符号表中的一个确定的符号定义联系起来。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">若找不到，则出现编译时错误。&nbsp;&nbsp;&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">其次是重定位；</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">不同的处理器指令对于地址的格式和方式都不一样。我们这里采用的是32位的x86处理器，介绍两种寻址方式。</p><table border="1" style="margin: 0px; padding: 0px; border-style: solid; border-color: silver; border-collapse: collapse; word-break: break-word;"><tbody style="margin: 0px; padding: 0px;"><tr style="margin: 0px; padding: 0px;"><td colspan="3" valign="top" width="573" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">X86基本重定位类型</p></td></tr><tr style="margin: 0px; padding: 0px;"><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">宏定义</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">值</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">重定位修正方法</p></td></tr><tr style="margin: 0px; padding: 0px;"><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">R_386_32</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">绝对寻址修正S&nbsp;+&nbsp;A</p></td></tr><tr style="margin: 0px; padding: 0px;"><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">R_386_PC32</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">2</p></td><td valign="top" width="191" style="margin: 0px; padding: 8px 14px; border-style: solid; border-color: silver; border-collapse: collapse;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">相对寻址修正S&nbsp;+&nbsp;A&nbsp;-&nbsp;P</p></td></tr></tbody></table><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">注：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">A：保存在被修正位置的值，对于32位cpu的话，采用<br style="margin: 0px; padding: 0px;" />R_386_PC32寻址的话<br style="margin: 0px; padding: 0px;" />它应该为0xFFFFFFFC即-4，它是代表地址的四个字节；而采用<br style="margin: 0px; padding: 0px;" />R_386_32寻址，它应该为0.</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">P：被修正的位置。考虑以下程序</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">...</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1023:&nbsp;11&nbsp;11&nbsp;11</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1026:e8&nbsp;<br style="margin: 0px; padding: 0px;" />fc<br style="margin: 0px; padding: 0px;" />&nbsp;ff&nbsp;ff&nbsp;ff</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">102b:&nbsp;11&nbsp;11&nbsp;11</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">...</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">上述蓝色fc标记处即是被修正的位置，即0x1027.</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">S：符号的实际地址。也就是第一步中空间和地址分配时得到的符号虚拟地址。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">举例来说吧！链接成的可执行文件中，假设main函数的虚拟地址为0x1000，swap函数的虚拟地址为0x2000；shared变量的虚拟地址为0x3000;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">绝对地址修正：对shared变量的地址修正。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">l&nbsp;<br style="margin: 0px; padding: 0px;" />S：shared的实际地址为0x3000；</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">l&nbsp;<br style="margin: 0px; padding: 0px;" />A：被修正位置的值，即0.</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">所以最后这个重定位修正地址为：0x3000，不变！</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">相对寻址修正：对符号&#8220;swap&#8221;进行修正。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">l&nbsp;<br style="margin: 0px; padding: 0px;" />S：符号swap的实际地址，即0x2000；</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">l&nbsp;<br style="margin: 0px; padding: 0px;" />A：被修正位置的值，即0xFFFFFFFC（-4）；</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">l&nbsp;<br style="margin: 0px; padding: 0px;" />P：被修正位置，及0x1027</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">最后的重定位修正地址为：S&nbsp;+&nbsp;A&nbsp;-P&nbsp;=&nbsp;0x2000&nbsp;+（-4）-&nbsp;0x1027&nbsp;=&nbsp;0xFD5.即修正后的程序为：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">...</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1023:&nbsp;11&nbsp;11&nbsp;11</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1026:e8&nbsp;<br style="margin: 0px; padding: 0px;" />d5&nbsp;0f&nbsp;00&nbsp;00</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">102b:&nbsp;11&nbsp;11&nbsp;11</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">...</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">发现熟悉的规则了吗？下一条指令（PC）的地址为0x102b，加上这个修正值正好等于0x2000，</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">0x102b&nbsp;+&nbsp;0xFD5&nbsp;=&nbsp;0x2000，刚好是swap函数的地址。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;<img src="http://hi.csdn.net/attachment/201011/28/0_1290945325g9vI.gif" alt="" width="277" height="239" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">以上内容没有涉及到c标准库，仅仅是自己实现的两个<span style="margin: 0px; padding: 0px; line-height: 1.8;"><a title="c语言" href="http://www.xuebuyuan.com/zt/17447.html%E2%80%8E" target="_blank" style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;">c语言</a>程序之间的链接状况，也就是&#8220;程序里面的printf怎么处理&#8221;没有说明。这里，我们就要提及&#8220;静态库&#8221;的概念。其实一个静态库可以简单地看成一组目标文件的集合，即很多目标文件经过压缩打包后形成的一个文件。与静态库链接的过程是这样的：ld链接器自动查找全局符号表，找到那些为决议的符号，然后查出它们所在的目标文件，将这些目标文件从静态库中&#8220;解压&#8221;出来，最终将它们链接在一起成为一个可执行文件。也就是说只有少数几个库和目标文件被链接入了最终的可执行文件，而非所有的库一股脑地被链接进了可执行文件。<br style="margin: 0px; padding: 0px;" /></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8;">四、装载：</span></strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">以Linux内核装载ELF为例简述一下装载过程。当我们在Linux系统的bash下输入一个命令执行某个ELF程序时，在用户层面，bash进程会调用fork()系统调用创建一个新的进程，然后新的进程调用execve()来执行指定的ELF文件，原先的bash进程继续返回等待刚才启动时新进程结束，然后继续等待用户输入命令。这里需注意，随着一个新进程的出现，操作系统会为它创建一个独立的虚拟地址空间。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">【创建虚拟地址空间】我们知道一个虚拟空间由一组映射函数将虚拟空间的各个页映射到相应的物理空间，那么创建一个虚拟空间实际上并不是创建空间而是创建映射函数所需要的数据结构。举例来说，在x86的Linux下创建虚拟地址空间实际上只是分配一个页目录（页表）就可以了，甚至不设置页映射关系，这些映射关系等到后面程序发生&#8220;缺页&#8221;时在进行设置。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">在进入execve()系统调用之后，Linux内核就开始进行真正的装载工作。在内核中，execve()系统调用相应的入口是sys_execve(),作用：参数的检查复制；调用do_execve(),流程：查找被执行的文件，读取文件的前128个字节以判断文件的格式是elf还是其它；调用search_binary_handle(),流程：通过判断文件头部的魔数确定文件的格式，并且调用相应的装载处理程序。ELF可执行文件的装载处理过程叫load_elf_binary(),它的主要步骤如下：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1，检查ELF可执行文件格式的有效性，比如魔数、程序头表中段的数量。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">2，寻找动态链接的&#8220;.interp&#8221;段，找到动态链接器的路径，以便于后面动态链接时会用上。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">3，读取可执行文件的程序头，并且创建虚拟空间与可执行文件的映射关系。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">【读取可执行文件的<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">程序头（存储了哪些部分被映射）</span>，<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">并且创建虚拟空间与可执行文件的映射关系</span>】创建虚拟空间时的页映射关系函数是虚拟空间到物理内存的映射关系，而这一步所做的事虚拟空间与可执行文件的映射关系。我们知道，当程序发生缺页是，操作系统会为物理内存分配一个物理页，然后将该缺页从磁盘中读取到内存，在设置缺页的虚拟页与物理页之间的映射关系，这样程序才可以得以正常运行。但是明显的一点是，当操作系统捕获到缺页错误时，他应当知道程序当前需要的页在可执行文件中的哪一个位置。而这就是虚拟存储与可执行文件之间的映射关系。实际上，这种映射关系仅仅是保存在操作系统内部的一个数据结构。当发生缺页错误是，CPU将控制权交给操作系统，操作系统利用专门的缺页处理例程来查询这个数据结构（映射关系），然后找到所需页所在的虚拟内存区域，以及在可执行文件的偏移，然后把该页加载进物理内存，同时将该虚拟页与物理页之间建立映射关系，最后把控制权还给进程，进程从刚才缺页位置重新开始执行。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">4，初始化ELF进程环境。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">5，将系统调用的返回地址修改成ELF可执行文件的入口点，这个入口点取决于程序的链接方式，对于静态链接的ELF可执行文件，它就是ELF文件的文件头中e_entry所指的地址；对于动态链接的ELF可执行文件，程序入口点就是动态链接器。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">【将CPU指令寄存器设置成可执行文件的入口，启动运行】对动态链接来讲，此时就启动了动态链接器。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">当load_elf_binary()执行完毕，返回至do_execve()在返回至sys_execve()时，系统调用的返回地址已经被改写成了被装载的ELF程序的入口地址了。所以，当sys_execve()系统调用从内核态返回到用户态时，EIP寄存器直接跳转到ELF程序的入口地址。此时，ELF可执行文件装载完成。接下来就是动态链接器对程序进行动态链接了。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">进程的虚拟空间：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><img src="https://images2015.cnblogs.com/blog/376860/201608/376860-20160806161516825-542579710.png" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">五、动态链接</strong></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">动态链接ELF文件的生成过程</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><img src="https://images2015.cnblogs.com/blog/376860/201608/376860-20160806163246840-1854978573.png" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">主要原因有两个：第一，考虑内存和磁盘空间。静态链接极大地浪费内存空间。因为在静态链接的情况下，假设有两个程序共享一个模块，那么在静态链接后输出的两个可执行文件中各有一个共享模块的副本。如果同时运行这两个可执行文件，那么这个共享模块将在磁盘和内存中都有两个副本，对磁盘和内存造成极大地浪费；第二，程序的更新。一旦程序中的一个模块被修改，那么整个程序都要重新链接、发布给用户。如果这个程序相当的大，那么后果就会更加严重！</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;对于一个共享对象（linux下共享的模块），<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">要实现被其他程序之间的共享，就要使其代码和数据分开，每个程序都会有该模块的数据部分的副本，代码部分是共享的。</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">共享模块被映射的虚拟地址空间就在上面进程虚拟空间中的 （Memery Mapping部分）</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">共享模块被映射的模样是</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;"><img src="https://images2015.cnblogs.com/blog/376860/201608/376860-20160806164350590-605002435.png" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">动态链接做了什么？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">务必知道，动态链接是相对于共享对象而言的。动态链接器将程序所需要的所有共享库装载到进程的地址空间，并且将程序汇总所有为决议的符号绑定到相应的动态链接库（共享库）中，并进行重定位工作。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">对于共享模块来说，要实现共享，那么其代码对数据的访问必须是地址无关（就是代码中的地址是固定的，当然这是用的相对地址喽）的，如何做到地址无关，编译器是这么干的，每一个共享模块，都会在其代码段有一个GOT(global offset table)段，如上图所示，<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">Got是一个指针数组，用来存储外部变量的地址</span>，而代码相对于Got的距离是固定的，当对<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">外部模块变量数据和函数</span>进行访问时，就去访问变量在GOT中的位置。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">共享模块对于数据的访问方式：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">本模块的全局变量和函数------相对地址</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">外模块的全局变量和函数-------GOT段</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #0000ff;">动态链接重定位时修改GOT中的值就实现了对变量的正确访问。</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">动态链接的ELF文件启动过程</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">动态链接基本分为三步：先是启动动态链接器本身，然后装载所有需要的共享对象，最后重定位和初始化。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">1，动态链接器自举</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">就我们所知道的，对普通的共享对象文件来说，它的重定位工作是由动态链接器来完成；它也可以依赖于其他共享对象，其中被依赖的共享对象由动态链接器负责链接和装载。那么，对于动态链接器本身呢，它也是一个共享对象，它的重定位工作由谁完成？它是否可以依赖于其他的共享对象文件？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">动态链接器有其自身的特殊性：首先，动态链接器本身不可以依赖其他任何共享对象（人为控制）；其次动态链接器本身所需要的全局和静态变量的重定位工作由它自身完成（自举代码）。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">我们知道，在Linux下，动态链接器ld.so实际上也是一个共享对象，操作系统同样通过映射的方式将它加载到进程的地址空间中。操作系统在加载完动态链接器之后，就将控制权交给动态链接器。动态链接器入口地址即是自举代码的入口。动态链接器启动后，它的自举代码即开始执行。自举代码首先会找到它自己的GOT(全局偏移表，记录每个段的偏移位置）。而GOT的第一个入口保存的就是&#8220;.dynamic&#8221;段的偏移地址，由此找到动态链接器本身的&#8220;.dynamic&#8221;段。通过&#8220;.dynamic&#8221;段中的信息，自举代码便可以获得动态链接器本身的重定位表和符号表等，从而得到动态链接器本身的重定位入口，然后将它们重定位。完成自举后，就可以自由地调用各种函数和全局变量。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">2，装载共享对象</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">完成自举后，<span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">动态链接器将可执行文件和链接器本身的符号表都合并到一个符号表当中</span>，称之为&#8220;全局符号表&#8221;。然后链接器开始寻找可执行文件所依赖的共享对象：从&#8220;.dynamic&#8221;段中找到DT_NEEDED类型，它所指出的就是可执行文件所依赖的共享对象。由此，动态链接器可以列出可执行文件所依赖的所有共享对象，并将这些共享对象的名字放入到一个装载集合中。然后链接器开始从集合中取出一个所需要的共享对象的名字，找到相应的文件后打开该文件，读取相应的ELF文件头和&#8220;.dynamic&#8221;，然后将它相应的代码段和数据段映射到进程空间中。如果这个ELF共享对象还依赖于其他共享对象，那么将依赖的共享对象的名字放到装载集合中。如此循环，直到所有依赖的共享对象都被装载完成为止。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.8; color: #ff0000;">当一个新的共享对象被装载进来的时候，它的符号表会被合并到全局符号表中</span>。所以当所有的共享对象都被装载进来的时候，全局符号表里面将包含动态链接器所需要的所有符号。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">3，重定位和初始化</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">当上述两步完成以后，动态链接器开始重新遍历可执行文件和每个共享对象的重定位表，将表中每个需要重定位的位置进行修正，原理同前。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">重定位完成以后，如果某个共享对象有&#8220;.init&#8221;段，那么动态链接器会执行&#8220;.init&#8221;段中的代码，用以实现共享对象特有的初始化过程。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">此时，所有的共享对象都已经装载并链接完成了，动态链接器的任务也到此结束。同时装载链接部分也将告一段落！接下来便是程序的执行了。。。</p></div><img src ="http://www.cppblog.com/prayer/aggbug/216095.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2018-11-28 15:53 <a href="http://www.cppblog.com/prayer/archive/2018/11/28/216095.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Pthread创建线程后必须使用join或detach释放线程资源</title><link>http://www.cppblog.com/prayer/archive/2012/04/23/172427.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 23 Apr 2012 02:54:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2012/04/23/172427.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/172427.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2012/04/23/172427.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/172427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/172427.html</trackback:ping><description><![CDATA[<p><span>这两天在看Pthread 资料的时候，无意中看到<a href="http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_detach.3.html" target="_blank" rel="nofollow">这样</a>一句话(man pthread_detach):</span></p>
<div><pre><span>Either <a href="http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html" target="_blank" rel="nofollow">pthread_join(3)</a> or <strong>pthread_detach</strong>() should be called for each thread<br />       that an application creates, so that system resources for the thread can be<br />       released.  (But note that the resources of all threads are freed when the<br />       process terminates.)</span></pre>
<p>也就是说：每个进程创建以后都应该调用pthread_join 或 pthread_detach 函数，只有这样在线程结束的时候资源(线程的描述信息和stack)才能被释放.</p>
<p>之后又查了<a style="color: #690000" rel="nofollow">pthread_join</a>&nbsp;但是没有明确说明必须调用pthread_join 或 pthread_detach.</p>
<p>但是再查了 Pthread for win32&nbsp;<a href="http://sourceware.org/pthreads-win32/manual/pthread_join.html" target="_blank" rel="nofollow">pthread_join</a></p>
<p>When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore,&nbsp;pthread_join must be called&nbsp; once&nbsp; for&nbsp;each joinable thread created to avoid&nbsp;<strong>memory leaks</strong>.</p></div>
<div><span><br /></span></div>
<div><span>才知道如果在新线程里面没有调用pthread_join 或 pthread_detach会导致内存泄漏, 如果你创建的线程越多，你的内存利用率就会越高, 直到你再无法创建线程，最终只能结束进程。</span></div>
<div><span><br /></span></div>
<div><span>解决方法有三个:</span></div>
<div><span>1. &nbsp; 线程里面调用&nbsp;<strong><em>pthread_detach(pthread_self())&nbsp;</em><span>这个方法最简单</span></strong></span></div>
<div><span><span style="color: #000000"><span>2<strong>.&nbsp;<span>在创建线程的设置</span><em>PTHREAD_CREATE_DETACHED</em><span>属性</span></strong></span></span></span></div>
<div><span><span style="color: #000000"><span><strong>3.&nbsp;<span>创建线程后用</span>&nbsp;<strong><em>pthread_join()</em></strong>&nbsp;<span>一直等待子线程结束。</span></strong></span></span></span></div>
<div><span><span style="color: #000000"><span><strong><span><br /></span></strong></span></span></span></div>
<div>下面是几个简单的例子</div>
<div>1.&nbsp;调用&nbsp;&nbsp;<strong><em>pthread_detach(pthread_self())</em></strong></div>
<div>
<div>#include &lt;stdio.h&gt;</div>
<div>#include &lt;stdlib.h&gt;</div>
<div>#include &lt;pthread.h&gt;</div>
<div>void *PrintHello(void)</div>
<div>{</div>
<div>pthread_detach(pthread_self());</div>
<div>int stack[1024 * 20] = {0,};</div>
<div>//sleep(1);</div>
<div>long tid = 0;</div>
<div>//printf(&#8220;Hello World! It&#8217;s me, thread #%ld!\n&#8221;, tid);</div>
<div>//pthread_exit(NULL);</div>
<div>}</div>
<div>int main (int argc, char *argv[])</div>
<div>{</div>
<div>pthread_t pid;</div>
<div>int rc;</div>
<div>long t;</div>
<div>while (1) {</div>
<div>printf(&#8220;In main: creating thread %ld\n&#8221;, t);</div>
<div>rc = pthread_create(&amp;pid, NULL, PrintHello, NULL);</div>
<div>if (rc){</div>
<div>printf(&#8220;ERROR; return code from pthread_create() is %d\n&#8221;, rc);</div>
<div>//exit(-1);</div>
<div>}</div>
<div>sleep(1);</div>
<div>}</div>
<div>printf(&#8221; \n&#8212; main End &#8212;- \n&#8221;);</div>
<div>pthread_exit(NULL);</div>
<div>}</div></div>
<div>
<div><span><span style="color: #000000"><span>2<strong>.&nbsp;<span>在创建线程的设置</span><span>PTHREAD_CREATE_DETACHED</span><span>属性</span></strong></span></span></span></div>
<div><span><span style="color: #000000"><span><strong>
<div><span>
<div>#include &lt;stdio.h&gt;</div>
<div>#include &lt;stdlib.h&gt;</div>
<div>#include &lt;pthread.h&gt;</div>
<div>void *PrintHello(void)</div>
<div>{</div>
<div>int stack[1024 * 20] = {0,};</div>
<div>//pthread_exit(NULL);</div>
<div>//pthread_detach(pthread_self());</div>
<div>}</div>
<div>int main (int argc, char *argv[])</div>
<div>{</div>
<div>pthread_t pid;</div>
<div>int rc;</div>
<div>long t;</div>
<div>while (1) {</div>
<div>printf(&#8220;In main: creating thread %ld\n&#8221;, t);</div>
<div>pthread_attr_t attr;</div>
<div>pthread_t thread;</div>
<div>pthread_attr_init (&amp;attr);</div>
<div>pthread_attr_setdetachstate (&amp;attr, PTHREAD_CREATE_DETACHED);</div>
<div>rc = pthread_create(&amp;pid, &amp;attr, PrintHello, NULL);</div>
<div>pthread_attr_destroy (&amp;attr);</div>
<div>if (rc){</div>
<div>printf(&#8220;ERROR; return code from pthread_create() is %d\n&#8221;, rc);</div>
<div>//exit(-1);</div>
<div>}</div>
<div>sleep(1);</div>
<div>}</div>
<div>printf(&#8221; \n&#8212; main End &#8212;- \n&#8221;);</div>
<div>pthread_exit(NULL);</div>
<div>}</div></span></div></strong></span></span></span></div>
<div><span><span style="color: #000000"><span>3. 创建线程后用&nbsp;pthread_join() 一直等待子线程结束。</span></span></span></div>
<div><span><span style="color: #000000"><span><strong><br /></strong></span></span></span></div></div>
<div>
<div>
<div>#include &lt;stdio.h&gt;</div>
<div>#include &lt;stdlib.h&gt;</div>
<div>#include &lt;pthread.h&gt;</div>
<div>void *PrintHello(void)</div>
<div>{</div>
<div>int stack[1024 * 20] = {0,};</div>
<div>//sleep(1);</div>
<div>long tid = 0;</div>
<div>//pthread_exit(NULL);</div>
<div>//pthread_detach(pthread_self());</div>
<div>}</div>
<div>int main (int argc, char *argv[])</div>
<div>{</div>
<div>pthread_t pid;</div>
<div>int rc;</div>
<div>long t;</div>
<div>while (1) {</div>
<div>printf(&#8220;In main: creating thread %ld\n&#8221;, t);</div>
<div>rc = pthread_create(&amp;pid, NULL, PrintHello, NULL);</div>
<div>if (rc){</div>
<div>printf(&#8220;ERROR; return code from pthread_create() is %d\n&#8221;, rc);</div>
<div>//exit(-1);</div>
<div>}</div>
<div>pthread_join(pid, NULL);</div>
<div>sleep(1);</div>
<div>}</div>
<div>printf(&#8221; \n&#8212; main End &#8212;- \n&#8221;);</div>
<div>pthread_exit(NULL);</div>
<div>}</div></div></div><img src ="http://www.cppblog.com/prayer/aggbug/172427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2012-04-23 10:54 <a href="http://www.cppblog.com/prayer/archive/2012/04/23/172427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix环境下嵌入式C程序编译 </title><link>http://www.cppblog.com/prayer/archive/2012/03/21/168489.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 21 Mar 2012 05:45:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2012/03/21/168489.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/168489.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2012/03/21/168489.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/168489.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/168489.html</trackback:ping><description><![CDATA[<div class="blog_content" id="blog_content">A.预编译部分 <br />1.预编译DB2篇 <br />1.1 什么是DB2预编译 <br />&nbsp; 在我们用C语言编写访问DB2的程序过程中,需要用到嵌入式SQL,其作用是将DB2 SQL混入一般C程序中, DB2预编译器可以将SQL语法直接转换为DB2行时服务应用程序编程接口（API）调用。 <br />1.2 什么是bind <br />&nbsp; 这是DB2 prep要做的事情，即把SQC中的SQL语句变为DB2数据库可认的API。bind的作用主要是根据你SQC中的SQL语句使用的表和操作指定一个访问时DB要使用的策略，是一种优化作用，加快数据访问的速度；当然也可以不bind，那样，访问的过程策略是在访问时才有的，速度会受很大的影响，特别是并发访问。 <br /><br />2.预编译命令 <br />&nbsp; 2.1 db2 prep .sqc文件 bindfile 其中bindfile参数作用是生成和sqc文件同名的.bnd文件 <br />例: db2 prep /export/home/shwhome/sqc/CON_DB2.sqc bindfile 如果编译正常完成,则在.sqc文件同目录下会生成CON_DB2.c和CON_DB2.bnd文件 <br />2.2 bind .bnd文件 <br />&nbsp; 例: db2 bind /export/home/shwhome/sqc/CON_DB2.bnd <br />因为是DB2的预编译命令,使用的是DB2的预编译器,所以以上两条命令需要在连接DB2数据库的情况下才可以使用 <br /><br />B.嵌入式部分 <br />1.嵌入式C程序的编译 <br />我们采用GCC来编译C程序,GCC的一般编译命令请参考文档中的相关说明,这里具体说明在目前环境下编译C程序的注意点。 <br />1.1 编译C程序 <br />gcc -m64 -c -I/export/home/shwhome/inc -o /export/home/shwhome/obj/testdb.o /export/home/shwhome/src/testdb.c <br />参数说明 <br />-m64: 在64位服务器上编译时采用,这里为了将所有的编译后的目标文件统一,所以都加上-m64,如果再之后引用目标文件没有采用-m64编译则在最后编译时会出现ELF CLASS32(或ELF CLASS64)错误. -C: 只编译并生成目标文件,不做链接。 <br />1.2 编译SQC文件生成的.C文件 <br />gcc -m64 -c -I/export/home/shwhome/inc -I/export/home/aix/sqllib/include -L/usr/include/lib -o /export/home/shwhome/obj/CON_DB2.o /export/home/shwhome/sqc/CON_DB2.c <br />参数说明 <br />-I/export/home/aix/sqllib/include: 这个目录下主要使用到2个头文件:sqladef.h和sqlca.h,这个是DB2预编译包含的都文件,可以查看你用prep编译出来的与.sqc同名的.C文件,其中就包含这两个头文件。其中aix是DB2Instance用户,DB2安装后会将include路径复制到instance用户的环境变量中,再次创建instance后只要复制过来就可以,因为Instance用户还包含其他的环境设定,所以不要直接引用-I/opt/IBM/db2/V9.5/include/这个DB2的安装路径 <br />-L/usr/include/lib: 这个目录是系统包含函数的库文件,是编写应用程序的时候使用的相当于API,也就是应用编程接口。 <br />&#8251; -I/usr/include和-L/usr/include/lib是将usr/include下的函数作为头文件包括进来,并且将程序链接到库文件,这个例子中没有用到,但是如果保险的话,在编译时最好加上这两个选项。 <br />1.3 将两个目标文件(主体C程序和嵌入式SQL)编译成可执行程序 <br />gcc -m64 -ldb2 -lc -o /export/home/shwhome/bin/testdb /export/home/shwhome/obj/CON_DB2.o /export/home/shwhome/obj/testdb.o <br />参数说明 <br />-ldb2: 链接DB2库文件。在SQC程序编译时必须链接libdb2.so库,其路径是/usr/lib/krb5/libdb2.so,之所以写成-ldb2,是在使用-l时,将库名的lib和后缀都去除,即库名是db2。以上命令是引用/export/home/shwhome/obj/CON_DB2.o /export/home/shwhome/obj/testdb.o这两个目标文件,编译后生成testdb,放在路径/export/home/shwhome/bin下。 </div><img src ="http://www.cppblog.com/prayer/aggbug/168489.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2012-03-21 13:45 <a href="http://www.cppblog.com/prayer/archive/2012/03/21/168489.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>int转换为wchar</title><link>http://www.cppblog.com/prayer/archive/2011/12/13/162016.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 13 Dec 2011 04:41:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/13/162016.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/162016.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/13/162016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/162016.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/162016.html</trackback:ping><description><![CDATA[先将int转为还char itoa<br />在将char转为wchar <br /><font color="#ff0000">#define A2W(lpa) (\<br />((_lpa = lpa) == NULL) ? NULL : (\<br />_convert = (lstrlenA(_lpa)+1),\<br />(INT_MAX/2&lt;_convert)? NULL : \<br />ATLA2WHELPER((LPWSTR) alloca(_convert*sizeof(WCHAR)), _lpa, _convert, _acp)))</font><img src ="http://www.cppblog.com/prayer/aggbug/162016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-13 12:41 <a href="http://www.cppblog.com/prayer/archive/2011/12/13/162016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CString/String/int/wchar/char类型相转（转)(</title><link>http://www.cppblog.com/prayer/archive/2011/12/13/162015.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 13 Dec 2011 04:36:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/13/162015.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/162015.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/13/162015.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/162015.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/162015.html</trackback:ping><description><![CDATA[<a href="http://blog.sina.com.cn/s/blog_4d1865f00100o26b.html">http://blog.sina.com.cn/s/blog_4d1865f00100o26b.html</a><br /><br />
<p>1.头文件中要定义宏;<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> #define&nbsp;<wbr>&nbsp;<wbr> UNICODE<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> #define&nbsp;<wbr>&nbsp;<wbr> _UNICODE<br />&nbsp;<wbr>&nbsp;<wbr><br /><strong>2.char转换成wchar<br /></strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> const&nbsp;<wbr>&nbsp;<wbr> char&nbsp;<wbr>&nbsp;<wbr> *pFilePathName&nbsp;<wbr>&nbsp;<wbr> =&nbsp;<wbr>&nbsp;<wbr> "c:\\aa.dll";<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> int&nbsp;<wbr>&nbsp;<wbr> nLen&nbsp;<wbr>&nbsp;<wbr> =&nbsp;<wbr>&nbsp;<wbr> strlen(pFilePathName)&nbsp;<wbr>&nbsp;<wbr> +&nbsp;<wbr>&nbsp;<wbr> 1;<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> int&nbsp;<wbr>&nbsp;<wbr> nwLen&nbsp;<wbr>&nbsp;<wbr> =&nbsp;<wbr>&nbsp;<wbr> MultiByteToWideChar(CP_ACP,&nbsp;<wbr>&nbsp;<wbr> 0,&nbsp;<wbr>&nbsp;<wbr> pFilePathName,&nbsp;<wbr>&nbsp;<wbr> nLen,&nbsp;<wbr>&nbsp;<wbr> NULL,&nbsp;<wbr>&nbsp;<wbr> 0);<br />&nbsp;<wbr>&nbsp;<wbr><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> TCHAR&nbsp;<wbr>&nbsp;<wbr> lpszFile[256];<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> MultiByteToWideChar(CP_ACP,&nbsp;<wbr>&nbsp;<wbr> 0,&nbsp;<wbr>&nbsp;<wbr> pFilePathName,&nbsp;<wbr>&nbsp;<wbr> nLen,&nbsp;<wbr>&nbsp;<wbr> lpszFile,&nbsp;<wbr>&nbsp;<wbr> nwLen);<br />&nbsp;<wbr>&nbsp;<wbr><br /><strong>3.wchar转换成char<br /></strong>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> char&nbsp;<wbr>&nbsp;<wbr> *pFilePathName;<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> TCHAR&nbsp;<wbr>&nbsp;<wbr> lpszFile[256];<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> _tcscpy(lpszFile,&nbsp;<wbr>&nbsp;<wbr> _T("c:\\aa.dll"));<br />&nbsp;<wbr>&nbsp;<wbr><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> int&nbsp;<wbr>&nbsp;<wbr> nLen&nbsp;<wbr>&nbsp;<wbr> =&nbsp;<wbr>&nbsp;<wbr> wcslen(wstr)+1;&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> WideCharToMultiByte(CP_ACP,&nbsp;<wbr>&nbsp;<wbr> 0,&nbsp;<wbr>&nbsp;<wbr> lpszFile,&nbsp;<wbr>&nbsp;<wbr> nLen,&nbsp;<wbr>&nbsp;<wbr> pFilePathName,&nbsp;<wbr>&nbsp;<wbr> 2*nLen,&nbsp;<wbr>&nbsp;<wbr> NULL,&nbsp;<wbr>&nbsp;<wbr> NULL);</p>
<p>&nbsp;<wbr></p>
<p><strong>4.char*和CString转换</strong></p>
<p>CString 是一种很特殊的 C++ 对象，它里面包含了三个值：一个指向某个数据缓冲区的指针、一个是该缓冲中有效的字符记数(它是不可存取的，是位于 CString 地址之下的一个隐藏区域)以及一个缓冲区长度。有效字符数的大小可以是从0到该缓冲最大长度值减1之间的任何数（因为字符串结尾有一个NULL字符）。字符记数和缓冲区长度被巧妙隐藏。</p>
<p>(1) char*转换成CString</p>
<p>　　若将char*转换成CString，除了直接赋值外，还可使用CString::Format进行。例如：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> char chArray[] = "Char test";<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> TCHAR * p = _T("Char test");( 或LPTSTR p = _T("Char test");)<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CString theString = chArray;<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> theString.Format(_T("%s"), chArray);<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> theString = p;</p>
<p>(2) CString转换成char*</p>
<p>　　若将CString类转换成char*(LPSTR)类型，常常使用下列三种方法：</p>
<p>　　方法一，使用强制转换。例如：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CString theString( (_T("Char test "));<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;</p>
<p>　　方法二，使用strcpy。例如：</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CString theString( (_T("Char test "));<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> LPTSTR lpsz = new TCHAR[theString.GetLength()+1];<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> _tcscpy(lpsz, theString);</p>
<p>　　需要说明的是，strcpy(或可移值的_tcscpy)的第二个参数是 const wchar_t* (Unicode)或const char* (ANSI)，系统编译器将会自动对其进行转换。</p>
<p>　　方法三，使用CString::GetBuffer。</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 如果你需要修改 CString 中的内容，它有一个特殊的方法可以使用，那就是 GetBuffer，它的作用是返回一个可写的缓冲指针。如果你只是打算修改字符或者截短字符串，例如：<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> CString s(_T("Char test "));<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> LPTSTR p = s.GetBuffer();</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> LPTSTR dot = strchr(p, ''.'');</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // 在这里添加使用p的代码</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> if(p != NULL)</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> *p = _T('\0');<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> s.ReleaseBuffer();&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> // 使用完后及时释放，以便能使用其它的CString成员函数</p>
<p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在 GetBuffer 和 ReleaseBuffer 之间这个范围，一定不能使用你要操作的这个缓冲的 CString 对象的任何方法。因为 ReleaseBuffer 被调用之前，该 CString 对象的完整性得不到保障。</p>
<p>&nbsp;<wbr></p>
<p><strong>5.CString 转为 int</strong></p>
<p>将字符转换为整数，可以使用atoi、_atoi64或atol。&nbsp;<wbr><br />&nbsp;<wbr>&nbsp;<wbr> CString&nbsp;<wbr>aaa&nbsp;<wbr>=&nbsp;<wbr>"16"&nbsp;<wbr>;<br />&nbsp;<wbr>&nbsp;<wbr> int&nbsp;<wbr>int_chage&nbsp;<wbr>=&nbsp;<wbr>atoi(aaa)&nbsp;<wbr>;&nbsp;<wbr></p>
<p>&nbsp;<wbr>&nbsp;<wbr> 得到&nbsp;<wbr>int_chage = 16</p>
<p>&nbsp;<wbr>&nbsp;<wbr> int&nbsp;<wbr>atoi(const&nbsp;<wbr>char&nbsp;<wbr>*nptr);<br />&nbsp;<wbr>&nbsp;<wbr> long&nbsp;<wbr>atol(const&nbsp;<wbr>char&nbsp;<wbr>*nptr);<br />&nbsp;<wbr> &nbsp;<wbr>long&nbsp;<wbr>long&nbsp;<wbr>atoll(const&nbsp;<wbr>char&nbsp;<wbr>*nptr);<br />&nbsp;<wbr> &nbsp;<wbr>long&nbsp;<wbr>long&nbsp;<wbr>atoq(const&nbsp;<wbr>char&nbsp;<wbr>*nptr);<br /><br /><br /><strong>6.int 转为 CString<br /></strong>而将数字转换为CString变量，可以使用CString的Format函数。如&nbsp;<wbr><br />CString&nbsp;<wbr>s;&nbsp;<wbr><br />int&nbsp;<wbr>i&nbsp;<wbr>=&nbsp;<wbr>64;&nbsp;<wbr><br />s.Format("%d",&nbsp;<wbr>i)&nbsp;<wbr><br /><br /><br />　itoa是广泛应用的非标准C语言扩展函数。由于它不是标准<a href="http://baike.baidu.com/view/4312050.htm" target="_blank"><font color="#136ec2">C语言函数</font></a>，所以不能在所有的编译器中使 </p>
<div class="text_pic" style="float: right; visibility: hidden; padding-bottom: 3px"><a href="http://baike.baidu.com/albums/982195/982195.html#0$d1e312f49d687ad67709d724" target="_blank"></a> 
<p class="pic-info">itoa界面</p></div>
<p>用。但是，大多数的编译器（如Windows上的）通常在&lt;stdlib.h&gt;头文件中包含这个函数。在&lt;stdlib.h&gt;中与之有相反功能的函数是atoi。功能：把一整数转换为字符串。</p><br /><br /><img src ="http://www.cppblog.com/prayer/aggbug/162015.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-13 12:36 <a href="http://www.cppblog.com/prayer/archive/2011/12/13/162015.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CHAR与WCHAR处理函数</title><link>http://www.cppblog.com/prayer/archive/2011/12/13/162005.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 13 Dec 2011 02:29:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/13/162005.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/162005.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/13/162005.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/162005.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/162005.html</trackback:ping><description><![CDATA[<table style="table-layout: fixed; width: 100%">
<tbody>
<tr>
<td>
<div class="cnt" id="blog_text">
<p>转自<a href="http://hi.baidu.com/hypkb/blog/item/8d6d724b0200432b09f7ef99.html">http://hi.baidu.com/hypkb/blog/item/8d6d724b0200432b09f7ef99.html</a></p>
<p>字符分类：&nbsp;&nbsp;&nbsp;&nbsp; 宽字符函数普通C函数描述 <br />iswalnum()&nbsp;&nbsp;&nbsp;&nbsp; isalnum() 测试字符是否为数字或字母 <br />iswalpha()&nbsp;&nbsp;&nbsp;&nbsp; isalpha() 测试字符是否是字母 <br />iswcntrl()&nbsp;&nbsp;&nbsp;&nbsp; iscntrl() 测试字符是否是控制符 <br />iswdigit()&nbsp;&nbsp;&nbsp;&nbsp; isdigit() 测试字符是否为数字 <br />iswgraph()&nbsp;&nbsp;&nbsp;&nbsp; isgraph() 测试字符是否是可见字符 <br />iswlower()&nbsp;&nbsp;&nbsp;&nbsp; islower() 测试字符是否是小写字符 <br />iswprint()&nbsp;&nbsp;&nbsp;&nbsp; isprint() 测试字符是否是可打印字符 <br />iswpunct()&nbsp;&nbsp;&nbsp;&nbsp; ispunct() 测试字符是否是标点符号 <br />iswspace()&nbsp;&nbsp;&nbsp;&nbsp; isspace() 测试字符是否是空白符号 <br />iswupper()&nbsp;&nbsp;&nbsp;&nbsp; isupper() 测试字符是否是大写字符 <br />iswxdigit()&nbsp;&nbsp;&nbsp;&nbsp; isxdigit()测试字符是否是十六进制的数字</p>
<p><br />大小写转换：&nbsp;&nbsp;&nbsp;&nbsp; <br />宽字符函数&nbsp;&nbsp;&nbsp; 普通C函数描述 <br />towlower()&nbsp;&nbsp;&nbsp;&nbsp; tolower() 把字符转换为小写 <br />towupper()&nbsp;&nbsp;&nbsp;&nbsp; toupper() 把字符转换为大写</p>
<p><br />字符比较：&nbsp;&nbsp;&nbsp;&nbsp; 宽字符函数普通C函数描述 <br />wcscoll()&nbsp;&nbsp;&nbsp;&nbsp; strcoll() 比较字符串</p>
<p><br />日期和时间转换： <br />宽字符函数描述 <br />strftime()&nbsp;&nbsp;&nbsp;&nbsp; 根据指定的字符串格式和locale设置格式化日期和时间 <br />wcsftime()&nbsp;&nbsp;&nbsp;&nbsp; 根据指定的字符串格式和locale设置格式化日期和时间， 并返回宽字符串 <br />strptime()&nbsp;&nbsp;&nbsp;&nbsp; 根据指定格式把字符串转换为时间值， 是strftime的反过程</p>
<p><br />打印和扫描字符串： <br />宽字符函数描述 <br />fprintf()/fwprintf()&nbsp;&nbsp;&nbsp;&nbsp; 使用vararg参量的格式化输出 <br />fscanf()/fwscanf()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 格式化读入 <br />printf()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用vararg参量的格式化输出到标准输出 <br />scanf()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从标准输入的格式化读入 <br />sprintf()/swprintf()&nbsp;&nbsp;&nbsp;&nbsp; 根据vararg参量表格式化成字符串 <br />sscanf()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以字符串作格式化读入 <br />vfprintf()/vfwprintf()&nbsp;&nbsp;&nbsp;&nbsp; 使用stdarg参量表格式化输出到文件 <br />vprintf()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用stdarg参量表格式化输出到标准输出 <br />vsprintf()/vswprintf()&nbsp;&nbsp;&nbsp;&nbsp; 格式化stdarg参量表并写到字符串</p>
<p><br />数字转换： <br />宽字符函数&nbsp;&nbsp;&nbsp; 普通C函数描述 <br />wcstod()&nbsp;&nbsp;&nbsp;&nbsp; strtod() 把宽字符的初始部分转换为双精度浮点数 <br />wcstol()&nbsp;&nbsp;&nbsp;&nbsp; strtol() 把宽字符的初始部分转换为长整数 <br />wcstoul()&nbsp;&nbsp;&nbsp;&nbsp; strtoul() 把宽字符的初始部分转换为无符号长整数</p>
<p><br />多字节字符和宽字符转换及操作： <br />宽字符函数描述 <br />mblen()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据locale的设置确定字符的字节数 <br />mbstowcs()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 把多字节字符串转换为宽字符串 <br />mbtowc()/btowc()&nbsp;&nbsp;&nbsp; 把多字节字符转换为宽字符 <br />wcstombs()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符串转换为多字节字符串 <br />wctomb()/wctob()&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符转换为多字节字符</p>
<p><br />输入和输出： <br />宽字符函数&nbsp;&nbsp;&nbsp; 普通C函数描述 <br />fgetwc()&nbsp;&nbsp;&nbsp;&nbsp; fgetc()&nbsp;&nbsp;&nbsp;&nbsp; 从流中读入一个字符并转换为宽字符 <br />fgetws()&nbsp;&nbsp;&nbsp;&nbsp; fgets()&nbsp;&nbsp;&nbsp;&nbsp; 从流中读入一个字符串并转换为宽字符串 <br />fputwc()&nbsp;&nbsp;&nbsp;&nbsp; fputc()&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符转换为多字节字符并且输出到标准输出 <br />fputws()&nbsp;&nbsp;&nbsp;&nbsp; fputs()&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符串转换为多字节字符并且输出到标准输出串 <br />getwc()&nbsp;&nbsp;&nbsp;&nbsp; getc()&nbsp;&nbsp;&nbsp;&nbsp; 从标准输入中读取字符， 并且转换为宽字符 <br />getwchar()&nbsp;&nbsp;&nbsp;&nbsp; getchar()&nbsp;&nbsp;&nbsp;&nbsp; 从标准输入中读取字符， 并且转换为宽字符 <br />None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gets()&nbsp;&nbsp;&nbsp;&nbsp; 使用fgetws() <br />putwc()&nbsp;&nbsp;&nbsp;&nbsp; putc()&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符转换成多字节字符并且写到标准输出 <br />putwchar()&nbsp;&nbsp;&nbsp;&nbsp; putchar()&nbsp;&nbsp;&nbsp;&nbsp; 把宽字符转换成多字节字符并且写到标准输出 <br />None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; puts()&nbsp;&nbsp;&nbsp;&nbsp; 使用fputws() <br />ungetwc()&nbsp;&nbsp;&nbsp;&nbsp; ungetc()&nbsp;&nbsp;&nbsp;&nbsp; 把一个宽字符放回到输入流中</p>
<p><br />字符串操作： <br />宽字符函数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 普通C函数描述 <br />wcscat()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcat()&nbsp;&nbsp;&nbsp;&nbsp; 把一个字符串接到另一个字符串的尾部 <br />wcsncat()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strncat()&nbsp;&nbsp;&nbsp;&nbsp; 类似于wcscat()， 而且指定粘接字符串的粘接长度. <br />wcschr()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strchr()&nbsp;&nbsp;&nbsp;&nbsp; 查找子字符串的第一个位置 <br />wcsrchr()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strrchr()&nbsp;&nbsp;&nbsp;&nbsp; 从尾部开始查找子字符串出现的第一个位置 <br />wcspbrk()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strpbrk()&nbsp;&nbsp;&nbsp;&nbsp; 从一字符字符串中查找另一字符串中任何一个字符第一次出现的位置 <br />wcswcs()/wcsstr()&nbsp;&nbsp;&nbsp;&nbsp; strchr()&nbsp;&nbsp;&nbsp;&nbsp; 在一字符串中查找另一字符串第一次出现的位置 <br />wcscspn()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcspn()&nbsp;&nbsp;&nbsp;&nbsp; 返回不包含第二个字符串的的初始数目 <br />wcsspn()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strspn()&nbsp;&nbsp;&nbsp;&nbsp; 返回包含第二个字符串的初始数目 <br />wcscpy()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy()&nbsp;&nbsp;&nbsp;&nbsp; 拷贝字符串 <br />wcsncpy()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strncpy()&nbsp;&nbsp;&nbsp;&nbsp; 类似于wcscpy()， 同时指定拷贝的数目 <br />wcscmp()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcmp()&nbsp;&nbsp;&nbsp;&nbsp; 比较两个宽字符串 <br />wcsncmp()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strncmp()&nbsp;&nbsp;&nbsp;&nbsp; 类似于wcscmp()， 还要指定比较字符字符串的数目 <br />wcslen()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strlen()&nbsp;&nbsp;&nbsp;&nbsp; 获得宽字符串的数目 <br />wcstok()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strtok()&nbsp;&nbsp;&nbsp;&nbsp; 根据标示符把宽字符串分解成一系列字符串 <br />wcswidth()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 获得宽字符串的宽度 <br />wcwidth()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 获得宽字符的宽度</p>
<p><br />另外还有对应于memory操作的 wmemcpy()， wmemchr()， wmemcmp()， wmemmove()， wmemset()．</p>
<p><font color="#ff0000">最后自己再补充两个好用的宏~<br />#define A2W(lpa) (\<br />((_lpa = lpa) == NULL) ? NULL : (\<br />_convert = (lstrlenA(_lpa)+1),\<br />(INT_MAX/2&lt;_convert)? NULL : \<br />ATLA2WHELPER((LPWSTR) alloca(_convert*sizeof(WCHAR)), _lpa, _convert, _acp)))</font></p>
<p><font color="#ff0000">#define W2A(lpw) (\<br />((_lpw = lpw) == NULL) ? NULL : (\<br />(_convert = (lstrlenW(_lpw)+1), \<br />(_convert&gt;INT_MAX/2) ? NULL : \<br />ATLW2AHELPER((LPSTR) alloca(_convert*sizeof(WCHAR)), _lpw, _convert*sizeof(WCHAR), _acp))))</font></p></div></td></tr></tbody></table><br /><img src ="http://www.cppblog.com/prayer/aggbug/162005.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-13 10:29 <a href="http://www.cppblog.com/prayer/archive/2011/12/13/162005.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从char/wchar_t到TCHAR(转)</title><link>http://www.cppblog.com/prayer/archive/2011/12/13/162004.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 13 Dec 2011 02:28:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/13/162004.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/162004.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/13/162004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/162004.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/162004.html</trackback:ping><description><![CDATA[<p>一．ANSI和UNICODE</p>
<p>1．为什么要使用Unicode？</p>
<p>（1） 可以很容易地在不同语言之间进行数据交换。</p>
<p>（2） 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。</p>
<p>（3） 提高应用程序的运行效率。</p>
<p>Windows 2000是使用Unicode从头进行开发的，如果调用任何一个Windows函数并给它传递一个ANSI字符串，那么系统首先要将字符串转换成 Unicode，然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串，系统就会首先将Unicode字符串转换成ANSI字符 串，然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序，就能够使你的应用程序 更加有效地运行。</p>
<p>Windows 98只支持ANSI，只能为开发ANSI应用程序。 Windows CE 就是使用Unicode的操作系统，完全不支持ANSI版函数。</p>
<p>Microsoft将COM从Win16转换成Win32时，所有COM接口方法都只能接受Unicode字符串。</p>
<p>2．ANSI字符和Unicode字符</p>
<p>ANSI字符类型为CHAR，指向字符串的指针PSTR(LPSTR)，指向一个常数字符串的指针PCSTR(LPCSTR)；对应的 Windows定义的Unicode字符类型为WCHAR（typedef WCHAR wchar_t），指向Unicode字符串的指针PWSTR ，指向一个常数Unicode字符串的指针PCWSTR 。</p>
<p>ANSI &#8220;ANSI&#8221;</p>
<p>Unicode L&#8220;UNICODE&#8221;</p>
<p>ANSI/Unicode T(&#8220;string&#8221;)或_TEXT(&#8220;string&#8221;)</p>
<p>3．ANSI字符和Unicode字符串的操作</p>
<p>双字节(DBCS)字符集中，字符串的每个字符可以包含一个或两个字节。如果只是调用strlen()函数，那么你就无法知道字符串到底有多少个字 符，它只能告诉你到达结尾的0之前有多少个字节。</p>
<p>标准c中的strcpy,strchr,strcat等只能用于ANSI字符串，不能正确处理Unicode字符串，因此也提供了一组补充函数，功 能等价，但用于Unicode码。我们来看看string .h字符串头文件中是怎样处理char*和wchar_t*两个字符串版本的：</p>
<p>// &#8230;\Microsoft Visual Studio 8\VC\include\string.h</p>
<p>char *strcat(char*,const char*);</p>
<p>wchar_t *wcschr(wchat_t*, const wchar_t*);</p>
<p>类似的还有strchr/wcschr，strcmp/wcscmp，strlen/wcslen etc. ANSI 操作函数以str开头 strcpy ，<strong>Unicode 操作函数以wcs开头 wcscpy</strong></p>
<p>MBCS 操作函数以_mbs开头 _mbscpy</p>
<p>ANSI/Unicode 操作函数以_tcs开头 _tcscpy（C运行期库）</p>
<p>ANSI/Unicode 操作函数以lstr开头 lstrcpy（Windows API）</p>
<p>所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示；Unicode版 本函数结尾以W表示。</p>
<p>二．ANSI/UNICODE通用字符/字符串类型TCHAR/LPTSTR/LPCTSTR</p>
<p>Neutral ANSI/UNICODE types</p>
<p>1．通用字符型TCHAR</p>
<p>ifdef UNICODE&nbsp; it is wchar_t（WCHAR）for Unicode platforms;</p>
<p>else it is char for ANSI and DBCS platforms.</p>
<p>2．通用字符串指针LPTSTR</p>
<p>ifdef UNICODE it is LPWSTR（*wchar_t） for&nbsp; Unicode platforms;</p>
<p>else it is LPSTR (*char) for ANSI and DBCS platforms.</p>
<p>3．通用通用常数字符串指针LPCTSTR</p>
<p>ifdef&nbsp; UNICODE it is LPCWSTR(*const wchar_t) for Unicode platforms;</p>
<p>else it is LPCSTR (*const char) for ANSI and DBCS platforms.</p>
<p>typedef LPWSTR LP;</p>
<p>#define __TEXT(quote) L##quote&nbsp; // r_winnt</p>
<p>&lt;1&gt;_UNICODE宏用于C运行期头文件，UNICODE宏则用于Windows头文件,当编译代码模块时，通常必须同时定义这两 个宏。</p>
<p><strong>&lt;2&gt;如果定义了_UNICODE，若要生成一个Unicode字符串,字符串前要加L宏，用于告诉编译器该字符串应该作为 Unicode字符串来编译处理。但是这样又有个问题就是如果没有定义_UNICODE则编译出错。为了解决这个问题我们必须用到_TEXT宏，这个宏也 在TChar.h中做了定义。使用该宏后，无论源文件有没有定义_UNICODE都不会出现编译错误。</strong></p>
<p>&lt;3&gt;Unicode与ANSI字符串的转换：Windows函数MultiByteToWideChar/mbstowcs函数用于 将多字节字符串转换成宽字符串,函数WideCharToMultiByte/wcstombs将宽字符串转换成等价的多字节字符串。</p>
<p>三．ANSI/UNICODE字符串通用函数lstrcmp/lstrcpy/lstrcat/lstrlen</p>
<p>// &#8230;\Microsoft Visual Studio 8\VC\PlatformSDK\Include\Winbase.h -- 已经包含在windows.h中。</p>
<p>lstrcmp(lstrcmpi)</p>
<p>WINBASEAPI</p>
<p>int</p>
<p>WINAPI</p>
<p>lstrcmpA(</p>
<p>&nbsp;&nbsp;&nbsp; __in LPCSTR lpString1,</p>
<p>&nbsp;&nbsp;&nbsp; __in LPCSTR lpString2</p>
<p>&nbsp;&nbsp;&nbsp; );</p>
<p>WINBASEAPI</p>
<p>int</p>
<p>WINAPI</p>
<p>lstrcmpW(</p>
<p>&nbsp;&nbsp;&nbsp; __in LPCWSTR lpString1,</p>
<p>&nbsp;&nbsp;&nbsp; __in LPCWSTR lpString2</p>
<p>&nbsp;&nbsp;&nbsp; );</p>
<p>#ifdef UNICODE</p>
<p>#define lstrcmp&nbsp; lstrcmpW</p>
<p>#else</p>
<p>#define lstrcmp&nbsp; lstrcmpA</p>
<p>#endif // !UNICODE</p>
<p>lstrcpy</p>
<p>WINBASEAPI</p>
<p>__out</p>
<p>LPSTR</p>
<p>WINAPI</p>
<p>lstrcpyA(</p>
<p>&nbsp;&nbsp;&nbsp; __out LPSTR lpString1,</p>
<p>&nbsp;&nbsp;&nbsp; __in&nbsp; LPCSTR lpString2</p>
<p>&nbsp;&nbsp;&nbsp; );</p>
<p>WINBASEAPI</p>
<p>__out</p>
<p>LPWSTR</p>
<p>WINAPI</p>
<p>lstrcpyW(</p>
<p>&nbsp;&nbsp;&nbsp; __out LPWSTR lpString1,</p>
<p>&nbsp;&nbsp;&nbsp; __in&nbsp; LPCWSTR lpString2</p>
<p>&nbsp;&nbsp;&nbsp; );</p>
<p>#ifdef UNICODE</p>
<p>#define lstrcpy&nbsp; lstrcpyW</p>
<p>#else</p>
<p>#define lstrcpy&nbsp; lstrcpyA</p>
<p>#endif // !UNICODE</p>
<p>另外还有lstrcat(W/A)和lstrlen(W/A)，这里未列出其函数定义。</p>
<p>四．使用shlwapi头文件中定义的函数StrCat/StrCmp/StrCpy</p>
<p>shlwapi.dll是UNC和URL地址动态链接库文件，用于注册键值和色彩设置。因为操作系统字符串函数常常被大型应用程序比如操作系统的外 壳进程Explorer.exe所使用。由于这些函数使用得很多，因此，在应用程序运行时，它们可能已经被装入RAM。这将有助于稍稍提高应用程序的运行 性能。</p>
<p>// &#8230;\Microsoft Visual Studio 8\VC\PlatformSDK\Include\shlwapi.h</p>
<p>注意：使用StrCat、StrCmp、StrCpy etc时要#include&nbsp; "shlwapi.h"</p>
<p>LWSTDAPI_(LPWSTR)&nbsp;&nbsp; StrCatW(LPWSTR psz1, LPCWSTR psz2);</p>
<p>LWSTDAPI_(int)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StrCmpW(LPCWSTR psz1, LPCWSTR psz2);</p>
<p>LWSTDAPI_(LPWSTR)&nbsp;&nbsp; StrCpyW(LPWSTR psz1, LPCWSTR psz2);</p>
<p>#ifdef UNICODE</p>
<p>#define StrCat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StrCatW</p>
<p>#define StrCmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StrCmpW</p>
<p>#define StrCpy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StrCpyW</p>
<p>#else</p>
<p>#define StrCat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lstrcatA</p>
<p>#define StrCmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lstrcmpA</p>
<p>#define StrCpy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lstrcpyA</p>
<p>五．MFC动态字符串类CString</p>
<p>// &#8230;\Microsoft Visual Studio 8\VC\atlmfc\include\afx.h</p>
<p>一个CString对象由可变长度的一队字符组成。CString使用类似于Basic的语法提供函数和操作符。连接和比较操作符以及简化的内存管 理使CString对象比普通字符串数组容易使用。</p>
<p><strong>CString是基于TCHAR数据类型的对象。如果在你的程序中定义了符号_UNICODE，则TCHAR被定义为类型wchar_t，即16位 字符类型；否则，TCHAR被定义为char，即8位字符类型。</strong>在UNICODE方式下，CString对象由16位字符组成。非UNICODE方式 下，CString对象由8位字符组成。 而VS2005默认TCHAR是wchar而不是char.</p>
<p>当不使用_UNICODE时，CString是多字节字符集（MBCS，也被认为是双字节字符集，DBCS）。注意，对于MBCS字符 串，CString仍然基于8位字符来计算，返回，以及处理字符串，并且你的应用程序必须自己解释MBCS的开始和结束字节。</p>
<p>CString 提供 operator LPCTSTR 来在 CString 和 LPCTSTR 之间进行转换。</p>
<p>有关CString的操作请参考MSDN MFC类库。</p>
<p>六．更安全的C语言字符串处理函数 Strsafe.h</p>
<p>// &#8230;\Microsoft Visual Studio 8\VC\PlatformSDK\Include\strsafe.h</p>
<p>注意：使用StringCchCopy /StringCchPrintf时要#include&nbsp; "strsafe.h".</p>
<p>STRSAFEAPI是为了解决现有的 C 语言运行时函数的代码太容易产生的&#8220;内存溢出&#8221;问题。当我们引用 strsafe 系列函数时，原有的 C 语言字符串处理函数都将被自动进行 #undef 处理。调试过程中的警告或出错信息将会告诉我们哪些函数哪些不安全，哪些已经被相应的 strsafe 系列函数取代了。&nbsp;</p>
<p>//1.不赞成使用不安全的函数，以避免产生编译错误</p>
<p>//2.如果你不要安全处理，你可以在包含strsafe.h头文件之前，</p>
<p>#define STRSAFE_NO_DEPRECATE</p>
<p>#ifdef DEPRECATE_SUPPORTED</p>
<p>// First all the names that are a/w variants (or shouldn't be #defined by now anyway).</p>
<p>#pragma deprecated(strcpy)</p>
<p>#pragma deprecated(wcscpy)</p>
<p>#pragma deprecated(lstrcpy)</p>
<p>#pragma deprecated(StrCpy)</p>
<p>类似的Strcat/wcscat/lstrcat/StrCat，sprintf/wsprintf</p>
<p>以下是D3D中预编译头文件dxstdafx.h</p>
<p>#pragma warning( disable : 4996 ) //将报警置为无效</p>
<p>#include &lt;strsafe.h&gt;</p>
<p>#pragma warning( default : 4996 ) //将报警置为默认</p>
<p>有关#pragma warning请参考：<a><font color="#1463c4">http://hi.baidu.com/iceland9/blog/item/5af9c0bfd334de0a18d81f33.html</font></a></p>
<p>以下是D3D从VS2003移植到VS2005时遇到的安全警告：</p>
<p>warning C4996: 'wcscpy' was declared deprecated</p>
<p>see declaration of 'wcscpy'</p>
<p>Message: 'This function or variable may be unsafe.</p>
<p>Consider using wcscpy_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'</p>
<p>warning C4995: 'lstrcpy': name was marked as #pragma deprecated</p>
<p>warning C4995: 'wsprintf': name was marked as #pragma deprecated</p>
<p>推荐使用新的安全可靠的TRSAFEAPI：</p>
<p>STRSAFEAPI</p>
<p>StringCchCopyA(</p>
<p>&nbsp;&nbsp;&nbsp; __out_ecount(cchDest) STRSAFE_LPSTR pszDest,</p>
<p>&nbsp;&nbsp;&nbsp; __in size_t cchDest,</p>
<p>&nbsp;&nbsp;&nbsp; __in STRSAFE_LPCSTR pszSrc);</p>
<p>STRSAFEAPI</p>
<p>StringCchCopyW(</p>
<p>&nbsp;&nbsp;&nbsp; __out_ecount(cchDest) STRSAFE_LPWSTR pszDest,</p>
<p>&nbsp;&nbsp;&nbsp; __in size_t cchDest,</p>
<p>&nbsp;&nbsp;&nbsp; __in STRSAFE_LPCWSTR pszSrc);</p>
<p>#ifdef UNICODE</p>
<p>#define StringCchCopy&nbsp; StringCchCopyW (W为Wide Unicode)</p>
<p>#else</p>
<p>#define StringCchCopy&nbsp; StringCchCopyA (A为ANSI)</p>
<p>#endif // !UNICODE</p>
<p>#undef strcpy</p>
<p>#define strcpy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy_instead_use_StringCbCopyA_or_StringCchCopyA;</p>
<p>#undef wcscpy</p>
<p>#define wcscpy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wcscpy_instead_use_StringCbCopyW_or_StringCchCopyW;</p>
<p>#undef wsprintf</p>
<p>#define wsprintf&nbsp;&nbsp;&nbsp; wsprintf_instead_use_StringCbPrintf_or_StringCchPrintf;</p>
<p>// Then all the windows.h names - we need to undef and redef based on UNICODE setting</p>
<p>#undef lstrcpy //取消已定义的宏</p>
<p>#pragma deprecated(lstrcpy) //安全警告</p>
<p>#ifdef UNICODE //使用UNICODE编程</p>
<p>#define lstrcpy&nbsp;&nbsp;&nbsp; lstrcpyW //重定义</p>
<p>#else</p>
<p>#define lstrcpy&nbsp;&nbsp;&nbsp; lstrcpyA //重定义</p>
<p>#endif</p>
<p>类似的有对lstrcat/wsprintf/wvsprintf的#undef，#pragma deprecated，#define。</p>
<p>推荐使用新的安全可靠的TRSAFEAPI：</p>
<p>#undef lstrcpy</p>
<p>#define lstrcpy&nbsp;&nbsp;&nbsp;&nbsp; lstrcpy_instead_use_StringCbCopy_or_StringCchCopy;</p>
<p>// Then the shlwapi names - they key off UNICODE also.</p>
<p>#undef&nbsp; StrCpy</p>
<p>#pragma deprecated(StrCpy)</p>
<p>#ifdef UNICODE</p>
<p>#define StrCpy&nbsp; StrCpyW</p>
<p>#else</p>
<p>#define StrCpy&nbsp; lstrcpyA</p>
<p>#endif</p>
<p>类似的有#undef StrCpyA /StrCpy /StrCatA /StrCat /StrNCat /StrCatN</p>
<p>以及对StrCpy/StrCat/StrNCat的#undef，#pragma deprecated，#define。</p>
<p>推荐使用新的安全可靠的TRSAFEAPI：</p>
<p>#undef StrCpy</p>
<p>#define StrCpy&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StrCpy_instead_use_StringCbCopy_or_StringCchCopy;</p>
<p>// Then all the CRT names - we need to undef/redef based on _UNICODE value.</p>
<p>参考：</p>
<p>《VC中的__T宏》</p>
<p><a><font color="#1463c4">http://www.diybl.com/course/3_program/vc/vc_js/2008830/138819.html</font></a></p>
<p>本文来自CSDN博客，转载请标明出处：<a><font color="#1463c4">http://blog.csdn.net/phunxm/archive/2009/12/26/5082618.aspx</font></a></p><img src ="http://www.cppblog.com/prayer/aggbug/162004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-13 10:28 <a href="http://www.cppblog.com/prayer/archive/2011/12/13/162004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>char,wchar_t,WCHAR,TCHAR,ACHAR的区别 </title><link>http://www.cppblog.com/prayer/archive/2011/12/13/162003.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 13 Dec 2011 02:24:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/13/162003.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/162003.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/13/162003.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/162003.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/162003.html</trackback:ping><description><![CDATA[<span style="color: #ff0000"><font face="Arial" size="1">char：</font></span> 
<p><span style="font-size: x-small"><span style="font-family: arial,helvetica,sans-serif"><font size="3"><span style="font-size: medium">ANSI字符串，可用字符串处理函数strcat( ),strcpy( ), strlen( <br /><span style="line-height: 1.5em">)等以str打头的函数。</span></span><br /></font><span style="color: #ff0000"><font size="1">wchar_t :</font></span></span></span></p>
<p><span style="font-size: x-small"><span style="font-family: arial,helvetica,sans-serif"><font size="3"><span style="font-size: medium; line-height: 1.5em">wchar_t是Unicode字符的数据类型,它的实际定义为：typedef </span><br /></font><font size="2"><span style="font-size: small; line-height: 1.5em">unsigned short wchar_t; </span><br /><span style="font-size: small; line-height: 1.5em">wchar_t 可用字符串处理函数：wcscat(),wcscpy(),wcslen()等以wcs打头</span></font><font size="3"><span style="font-size: medium; line-height: 1.5em">的函数。</span><br /><br /></font><span style="color: #ff0000"><font size="1">WCHAR:</font></span></span></span></p>
<p><span style="font-size: x-small"><span style="font-family: arial,helvetica,sans-serif"><font size="3"><span style="font-size: medium; line-height: 1.5em">在头文件中有这样的定义：typedef wchar_t WCHAR; 所以WCHAR实</span><span style="font-size: medium; line-height: 1.5em">际就是wchar_t。</span><br /><span style="font-size: medium; line-height: 1.5em">在C语言里面提供了 _UNICODE宏（有下划线），在Windows里面提供了</span><span style="font-size: medium; line-height: 1.5em">UNICODE宏（无下划线），只要定了_UNICODE宏和UNICODE宏，系统就会自</span><span style="font-size: medium; line-height: 1.5em">动切换到UNICODE版本，否则，系统按照ANSI的方式进行编译和运行。只定</span><br /></font><font size="2"><span style="font-size: small; line-height: 1.5em">义了宏并不能实现自动的转换，他还需要一系列的字符定义支持。</span><br /></font><font size="1"><span style="color: #ff0000">TCHAR：</span><br /></font><font size="2"><span style="font-size: small; line-height: 1.5em">如果定义了UNICODE宏则TCHAR被定义为wchar_t。typedef wchar_t TCHAR; </span><span style="font-size: small; line-height: 1.5em">否则TCHAR被定义为char typedef char TCHAR;</span><br /></font><font size="1"><span style="color: #ff0000">ACHAR:</span></font></span></span></p>
<p><span style="font-size: x-small"><span style="font-family: arial,helvetica,sans-serif"><font size="2"><span style="font-size: small; line-height: 1.5em">此类型是AUTODESK公司在adachar.h 头文件中定义的。</span><br /><span style="font-size: small; line-height: 1.5em">当定义了AD_UNICODE(AUTODESK公司使用UNICODE宏)时为wchar_t。</span></font><img id="paperPicArea1" style="display: none; position: relative" height="1" alt="" src="http://imgcache.qq.com/ac/b.gif" width="1" /></span></span></p><br /><br /><br /><br /><img src ="http://www.cppblog.com/prayer/aggbug/162003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-13 10:24 <a href="http://www.cppblog.com/prayer/archive/2011/12/13/162003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中string和string.h的作用和区别 </title><link>http://www.cppblog.com/prayer/archive/2011/12/12/161978.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 12 Dec 2011 08:52:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2011/12/12/161978.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/161978.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2011/12/12/161978.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/161978.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/161978.html</trackback:ping><description><![CDATA[<p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p><font size="2">&nbsp;#include&nbsp;&nbsp; &lt; string .h &gt;</font></p>
<p><font size="2">&nbsp;void&nbsp;&nbsp;&nbsp; main()<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string&nbsp;&nbsp;&nbsp; aaa =&nbsp;&nbsp;&nbsp; " abcsd&nbsp;&nbsp; d " ;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf( " looking&nbsp;&nbsp; for&nbsp;&nbsp; abc&nbsp;&nbsp; from&nbsp;&nbsp; abcdecd&nbsp;&nbsp; %s\n " ,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (strcmp(aaa, " abc " ))&nbsp;&nbsp; ?&nbsp;&nbsp;&nbsp; " Found "&nbsp;&nbsp;&nbsp; :&nbsp;&nbsp; " Not&nbsp;&nbsp; Found " );</font></p>
<p><font size="2">}<br />&nbsp;</font></p></td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; 不能正确执行，提示说是string类型没有定义</p>
<p>&nbsp;&nbsp;&nbsp; 而下面：<br />&nbsp;</p>
<p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p><font size="2">&nbsp; #include&nbsp;&nbsp; &lt; string &gt;</font></p>
<p><font size="2">&nbsp;using&nbsp;&nbsp;&nbsp; namespace&nbsp;&nbsp;&nbsp; std;<br />&nbsp;void&nbsp;&nbsp;&nbsp; main()<br />&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string&nbsp;&nbsp;&nbsp; aaa =&nbsp;&nbsp;&nbsp; " abcsd&nbsp;&nbsp; d " ;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf( " looking&nbsp;&nbsp; for&nbsp;&nbsp; abc&nbsp;&nbsp; from&nbsp;&nbsp; abcdecd&nbsp;&nbsp; %s\n " ,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (strcmp(aaa, " abc " ))&nbsp;&nbsp; ?&nbsp;&nbsp;&nbsp; " Found "&nbsp;&nbsp;&nbsp; :&nbsp;&nbsp; " Not&nbsp;&nbsp; Found " );<br />}</font></p></td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; 这里的string编译器就认识了，但是strcmp就不认识了呢？</p>
<p>&nbsp;&nbsp;&nbsp; 一般一个C++的老的带&#8220;。h&#8221;扩展名的库文件，比如iostream.h，在新标准后的标准库中都有一个不带&#8220;。h&#8221;扩展名的相对应，区别除了后者的好多改进之外，还有一点就是后者的东东都塞进了&#8220;std&#8221;名字空间中。</p>
<p>&nbsp;&nbsp;&nbsp; 但唯独string特别。</p>
<p>&nbsp;&nbsp;&nbsp; 问题在于C++要兼容C的标准库，而C的标准库里碰巧也已经有一个名字叫做&#8220;string.h&#8221;的头文件，包含一些常用的C字符串处理函数，比如楼主提到的strcmp.</p>
<p>&nbsp;&nbsp;&nbsp; 这个头文件跟C++的string类半点关系也没有，所以<string>并非<string.h>的&#8220;升级版本&#8221;，他们是毫无关系的两个头文件。</p>
<p>&nbsp;&nbsp;&nbsp; 要达到楼主的目的，比如同时：<br />&nbsp;</p>
<p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td><font size="2">&nbsp;#include&nbsp;&nbsp; &lt; string .h &gt;<br />#include&nbsp;&nbsp; &lt; string &gt;<br />&nbsp;using&nbsp;&nbsp;&nbsp; namespace&nbsp;&nbsp;&nbsp; std;</font></td></tr></tbody></table>&nbsp;&nbsp;&nbsp; 或者<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td><font size="2">&nbsp; #include&nbsp;&nbsp; &lt; cstring &gt;<br />#include&nbsp;&nbsp; &lt; string &gt;</font></td></tr></tbody></table></p>
<p>&nbsp;&nbsp;&nbsp; 其中<cstring>是与C标准库的<string.h>相对应，但裹有std名字空间的版本。</p>
<p>&nbsp;&nbsp;&nbsp; 笑谈（来自高质量++）</p>
<p>&nbsp;&nbsp;&nbsp; C++标准库很大。非常大。难以置信的大。怎么个大法？这么说吧：在C++标准中，关于标准库的规格说明占了密密麻麻300 多页，这还不包括标准C 库，后者只是"作为参考"（老实说，原文就是用的这个词）包含在C++库中。当然，并非总是越大越好，但在现在的情况下，确实越大越好，因为大的库会包含大量的功能。标准库中的功能越多，开发自己的应用程序时能借助的功能就越多。C++库并非提供了一切（很明显的是，没有提供并发和图形用户接口的支持），但确实提供了很多。几乎任何事你都可以求助于它。在归纳标准库中有些什么之前，需要介绍一下它是如何组织的。因为标准库中东西如此之多，你（或象你一样的其他什么人）所选择的类名或函数名就很有可能和标准库中的某个名字相同。为了避免这种情况所造成的名字冲突，实际上标准库中的一切都被放在名字空间std 中（参见条款28）。但这带来了一个新问题。无数现有的C++代码都依赖于使用了多年的伪标准库中的功能，例如，声明在<iostream.h>，<complex.h>，<limits.h>等头文件中的功能。现有软件没有针对使用名字空间而进行设计，如果用std 来包装标准库导致现有代码不能用，将是一种可耻行为。（这种釜底抽薪的做法会让现有代码的程序员说出比"可耻" 更难听的话）慑于被激怒的程序员会产生的破坏力，标准委员会决定为包装了std 的那部分标准库构件创建新的头文件名。生成新头文件的方法仅仅是将现有C++头文件名中的。h 去掉，方法本身不重要，正如最后产生的结果不一致也并不重要一样。所以<iostream.h>变成了<iostream>，<complex.h>变成了<complex>，等等。对于C 头文件，采用同样的方法，但在每个名字前还要添加一个c.所以C 的<string.h>变成了<cstring>，<stdio.h>变成了<cstdio>，等等。最后一点是，旧的C++头文件是官方所反对使用的（即，明确列出不再支持），但旧的C 头文件则没有（以保持对C 的兼容性）。实际上，编译器制造商不会停止对客户现有软件提供支持，所以可以预计，旧的C++头文件在未来几年内还是会被支持。</p>
<p>&nbsp;&nbsp;&nbsp; 所以，实际来说，下面是C++头文件的现状：</p>
<p>&nbsp;&nbsp;&nbsp; 旧的C++头文件名如<iostream.h>将会继续被支持，尽管它们不在官方标准中。这些头文件的内容不在名字空间std 中。</p>
<p>&nbsp;&nbsp;&nbsp; 新的C++头文件如<iostream>包含的基本功能和对应的旧头文件相同，但头文件的内容在名字空间std 中。（在标准化的过程中，库中有些部分的细节被修改了，所以旧头文件和新头文件中的实体不一定完全对应。）</p>
<p>&nbsp;&nbsp;&nbsp; 标准C 头文件如<stdio.h>继续被支持。头文件的内容不在std 中。</p>
<p>&nbsp;&nbsp;&nbsp; 具有C 库功能的新C++头文件具有如<cstdio>这样的名字。它们提供的内容和相应的旧C 头文件相同，只是内容在std 中。</p>
<p>&nbsp;&nbsp;&nbsp; 所有这些初看有点怪，但不难习惯它。最大的挑战是把字符串头文件理清楚：</p>
<p>&nbsp;&nbsp;&nbsp; <string.h>是旧的C 头文件，对应的是基于char*的字符串处理函数；</p>
<p>&nbsp;&nbsp;&nbsp; <cstring>是对应于旧C 头文件的std 版本；</p>
<p>&nbsp;&nbsp;&nbsp; <string>是包装了std 的C++头文件，对应的是新的string 类。</p>
<p>&nbsp;&nbsp;&nbsp; 如果能掌握这些（我相信你能），其余的也就容易了。</p><img src ="http://www.cppblog.com/prayer/aggbug/161978.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2011-12-12 16:52 <a href="http://www.cppblog.com/prayer/archive/2011/12/12/161978.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>system返回值</title><link>http://www.cppblog.com/prayer/archive/2010/11/01/132016.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 01 Nov 2010 09:46:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/11/01/132016.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/132016.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/11/01/132016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/132016.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/132016.html</trackback:ping><description><![CDATA[<p>　　<strong>system（执行shell 命令）</strong></p>
<p>　　相关函数&nbsp; fork，execve，waitpid，popen</p>
<p>　　表头文件&nbsp; #include&lt;stdlib.h&gt;</p>
<p>　　定义函数&nbsp; int system(const char * string);</p>
<p>　　函数说明&nbsp; system()会调用fork()产生子进程，由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令，此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置，SIGINT和SIGQUIT 信号则会被忽略。</p>
<p>　　返回值&nbsp; 如果system()在调用/bin/sh时失败则返回127，其他失败原因返回-1。若参数string为空指针(NULL)，则返回非零值。如果system()调用成功则最后会返回执行shell命令后的返回值，但是此返回值也有可能为system()调用/bin/sh失败所返回的127，因此最好能再检查errno 来确认执行成功。</p>
<p>　　附加说明&nbsp; 在编写具有SUID/SGID权限的程序时请勿使用system()，system()会继承环境变量，通过环境变量可能会造成系统<a class=channel_keylink href="http://security.chinaitlab.com/" target=_blank><u><font color=#0000ff>安全</font></u></a>的问题。</p>
<p>　　范例&nbsp; #include&lt;stdlib.h&gt;</p>
<p>　　main()</p>
<p>　　{</p>
<p>　　system(&#8220;ls -al /etc/passwd /etc/shadow&#8221;);</p>
<p>　　}</p>
<p>　　执行&nbsp; -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd</p>
<p>　　-r--------- 1 root root 572 Sep 2 15 :34 /etc/shadow</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Upon successful completion, the system subroutine returns the exit status of the shell. The exit status of the shell<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is returned in the same manner as a call to the wait or waitpid subroutine, using the structures in the sys/wait.h<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If the String parameter is a null pointer and a command processor is available, the system subroutine returns a<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nonzero value. If the fork subroutine fails or if the exit status of the shell cannot be obtained, the system<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subroutine returns a value of -1. If the exec l subroutine fails, the system subroutine returns a value of 127. In<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all cases, the errno global variable is set to indicate the error.<br><br><br></p>
<img src ="http://www.cppblog.com/prayer/aggbug/132016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-11-01 17:46 <a href="http://www.cppblog.com/prayer/archive/2010/11/01/132016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>  使用Bison和Flex（Windows下的基于GNU开源的Yacc和Lex） </title><link>http://www.cppblog.com/prayer/archive/2010/09/20/127135.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 20 Sep 2010 07:30:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/20/127135.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/127135.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/20/127135.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/127135.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/127135.html</trackback:ping><description><![CDATA[<p>听说Yacc很久了，今天下下来试了一下，下载地址<br>httpwww.monmouth.com~wstreettlex-yacclex-yacc.html 是gnu的开源项目，用C实现的，有源码，并且基于Windows的<br>注意，除了下bison.exe, flex.exe还要下载bison.simple文件并将其与bison.exe放于同一目录下，<br>下面进行简单的测试：</p>
<p>1. 在放置bison.exe的目录下新建一个文件test.y(扩展名是y)， 并在其中加入以下内容：<br>%{<br>&nbsp;#include ctype.h<br>%}<br>%token NUMBER<br>%left '+' '-'<br>%%</p>
<p>line&nbsp; expression 'n'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {printf( %dn, $1 ); }<br>expression&nbsp; expression '+' expression { $$ = $1 + $3; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; expression '-' expression { $$ = $1 - $3; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; '(' expression ')'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $$ = $2; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NUMBER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { $$ = $1; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>%%</p>
<p>yylex() {<br>&nbsp; int c;<br>&nbsp; c = getchar();<br>&nbsp; if ( isdigit( c ) ) {<br>&nbsp;&nbsp; yylval = c - '0';<br>&nbsp;&nbsp; return NUMBER;<br>&nbsp; }<br>&nbsp;return( c );<br>&nbsp;}</p>
<p>保存后，进入Dos命令行，进入相应目录后敲入bison test.y后回车，目录下会多一个test_tab.c文件，<br>这个便是bison自动生成的解释器的代码，不过还要自己加点代码<br>打开在文件最后加入以下代码：<br>main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp; yyparse();<br>}</p>
<p>yyerror(char msg)<br>{<br>&nbsp;&nbsp;&nbsp; printf(error %s encounteredn, msg);<br>}<br>可
以自己设计的，这里只是给出最简单的例子，加入上述代码后将test_tab.c文件进行编译，如果没错的话就会生成一个test_tab.exe文件，
在Dos命令行下敲入test_tab后回车会出现一个空行，敲入3+4（不要加空格）后回车，将会出现结果7，再敲回车会报错并退出，这就完成了一个简
单的解释器。<br>参考网站：httpdinosaur.compilertools.net<br>简单试验了一下Yacc和Lex，今后再慢慢研究一下它的语法和源代码！</p><img src ="http://www.cppblog.com/prayer/aggbug/127135.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-20 15:30 <a href="http://www.cppblog.com/prayer/archive/2010/09/20/127135.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>  使用bison和flex工具</title><link>http://www.cppblog.com/prayer/archive/2010/09/20/127134.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 20 Sep 2010 07:29:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/20/127134.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/127134.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/20/127134.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/127134.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/127134.html</trackback:ping><description><![CDATA[这里有一个使用bison建立一个简单的计算器的例子：<br>http://www.cs.berkeley.edu/~maratb/cs164/bison.html<br><br>使用bison和flex工具学习编译原理，远比单独看书然后自己编写一些程序生动的多。这样你就不会在那些复杂的字符处理，正则表达式的处理上浪费精力，最后费尽心力，却没有结果，失去了学习的兴趣。<br><br>我
这里有一个简单的计算器的程序，可以实现加、减、乘、除运算，并支持括号的处理和26个字母作为变量。以前自己使用后缀表达式方式写过一个这样的程序，单
单中缀表达式改为后缀表达式就是几百行的代码，反正自己现在还是不知道怎么处理里面复杂的堆栈的（我用了STL的List实现）。
<hr style="width: 100%; height: 2px;">
<p><br>词法处理文件<span style="font-weight: bold;">calc.lex</span>内容如下：<br>%{<br>&nbsp;&nbsp;&nbsp; /*<br>&nbsp;&nbsp;&nbsp; &nbsp;*&nbsp; 一个简单计算器的Lex词法文件<br>&nbsp;&nbsp;&nbsp; &nbsp;*/<br>&nbsp;&nbsp;&nbsp; #include &lt;stdlib.h&gt;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; void yyerror(char*);<br>&nbsp;&nbsp;&nbsp; #include "calc.tab.h"<br>%}<br>%%<br>&nbsp;&nbsp;&nbsp; /* a-z为变量 */<br>[a-z]&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; yylval = *yytext - 'a';<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return VARIABLE;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /* 整数 */<br>[0-9]+&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; yylval = atoi(yytext);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return INTEGER;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; /* 运算符 */<br>[-+()=/*\n]&nbsp;&nbsp;&nbsp; {return *yytext;}<br>&nbsp;&nbsp;&nbsp; /* 空白被忽略 */<br>[ \t]&nbsp;&nbsp;&nbsp; ;<br>&nbsp;&nbsp;&nbsp; /* 其他字符都是非法的 */<br>.&nbsp;&nbsp;&nbsp; yyerror("无效的输入字符");<br>%%<br>int&nbsp;&nbsp;&nbsp; yywrap(void)<br>{<br>&nbsp;&nbsp;&nbsp; return 1;<br>}<br>词法处理的目标就是区分出来每个成员到底是什么，这里有两种 INTEGER和VARIABLE。只要区分出来各个成分词法分析的任务就完成了。</p>
<hr style="width: 100%; height: 2px;">
<p><br>语法处理文件<span style="font-weight: bold;">calc.y</span>内容如下：<br>%token&nbsp;&nbsp;&nbsp; INTEGER VARIABLE<br>%left&nbsp;&nbsp;&nbsp; '+' '-'<br>%left&nbsp;&nbsp;&nbsp; '*' '/'<br>%{<br>&nbsp;&nbsp;&nbsp; #include &lt;stdio.h&gt;<br>&nbsp;&nbsp;&nbsp; void yyerror(char*);<br>&nbsp;&nbsp;&nbsp; int yylex(void);<br>&nbsp;&nbsp;&nbsp; int sym[26];<br>%}<br>%%<br>program:<br>&nbsp;&nbsp;&nbsp; program statement '\n'<br>&nbsp;&nbsp;&nbsp; |<br>&nbsp;&nbsp;&nbsp; ;<br>statement:<br>&nbsp;&nbsp;&nbsp; &nbsp;expr&nbsp;&nbsp;&nbsp; {printf("%d\n", $1);}<br>&nbsp;&nbsp;&nbsp; &nbsp;|VARIABLE '=' expr&nbsp;&nbsp;&nbsp; {sym[$1] = $3;}<br>&nbsp;&nbsp;&nbsp; &nbsp;;<br>expr:<br>&nbsp;&nbsp;&nbsp; INTEGER<br>&nbsp;&nbsp;&nbsp; |VARIABLE{$$ = sym[$1];}<br>&nbsp;&nbsp;&nbsp; |expr '+' expr&nbsp;&nbsp;&nbsp; {$$ = $1 + $3;}<br>&nbsp;&nbsp;&nbsp; |expr '-' expr&nbsp;&nbsp;&nbsp; {$$ = $1 - $3;}<br>&nbsp;&nbsp;&nbsp; |expr '*' expr&nbsp;&nbsp;&nbsp; {$$ = $1 * $3;}<br>&nbsp;&nbsp;&nbsp; |expr '/' expr&nbsp;&nbsp;&nbsp; {$$ = $1 / $3;}<br>&nbsp;&nbsp;&nbsp; |'('expr')'&nbsp;&nbsp;&nbsp; {$$ = $2;}<br>&nbsp;&nbsp;&nbsp; ;<br>%%<br>void yyerror(char* s)<br>{<br>&nbsp;&nbsp;&nbsp; fprintf(stderr, "%s\n", s);<br>}<br>int main(void)<br>{<br>&nbsp;&nbsp;&nbsp; printf("A simple calculator.\n");<br>&nbsp;&nbsp;&nbsp; yyparse();<br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br>语法分析文件的写法就是将BNF表达式描述一下即可，规则随着条目逐渐细化，变成了可以理解的内容。这里不用管如何实现这些语法的分析，只是需要告知如何构建这些语法。</p>
<hr style="width: 100%; height: 2px;">
<p><br>编译命令如下：<br>&gt;bison -d calc.y<br>&gt;flex calc.lex<br>&gt;gcc calc.tab.c lex.yy.c -o calc</p><img src ="http://www.cppblog.com/prayer/aggbug/127134.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-20 15:29 <a href="http://www.cppblog.com/prayer/archive/2010/09/20/127134.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Bison-Flex 笔记</title><link>http://www.cppblog.com/prayer/archive/2010/09/20/127133.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 20 Sep 2010 07:26:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/20/127133.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/127133.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/20/127133.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/127133.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/127133.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: FLEX	什么是FLEX？它是一个自动化工具，可以按照定义好的规则自动生成一个C函数yylex()，也成为扫描器（Scanner）。这个C函数把文本串作为输入，按照定义好的规则分析文本串中的字符，找到符合规则的一些字符序列后，就执行在规则中定义好的动作（Action）。例如在规则中可以这样定义：如果遇到一个换行字符\n，那么就把行计数器的值加一。	Flex文件就是一个文本文件，内容包括定义...&nbsp;&nbsp;<a href='http://www.cppblog.com/prayer/archive/2010/09/20/127133.html'>阅读全文</a><img src ="http://www.cppblog.com/prayer/aggbug/127133.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-20 15:26 <a href="http://www.cppblog.com/prayer/archive/2010/09/20/127133.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strsep</title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126657.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126657.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126657.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126657.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126657.html</trackback:ping><description><![CDATA[　　原型：char *strsep(char **stringp, const char *delim);
<div class=spctrl></div>
　　功能：分解字符串为一组字符串。
<div class=spctrl></div>
　　示例：&nbsp; &nbsp;&nbsp;
<div class=spctrl></div>
　　#include &lt;stdio.h&gt;
<div class=spctrl></div>
　　#include &lt;string.h&gt;
<div class=spctrl></div>
　　int main(void)
<div class=spctrl></div>
　　{
<div class=spctrl></div>
　　char str[] = "root:x::0:root:/root:/bin/bash:";
<div class=spctrl></div>
　　char *buf;
<div class=spctrl></div>
　　char *token;
<div class=spctrl></div>
　　buf = str;
<div class=spctrl></div>
　　while((token = strsep(&amp;buf, ":")) != NULL){
<div class=spctrl></div>
　　printf("%s\n", token);
<div class=spctrl></div>
　　}&nbsp;&nbsp;
<div class=spctrl></div>
　　return 0;
<div class=spctrl></div>
　　}
<img src ="http://www.cppblog.com/prayer/aggbug/126657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 13:56 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在C/C++中用strtok()实现Split函数的功能 </title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126656.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 05:49:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126656.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126656.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126656.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126656.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126656.html</trackback:ping><description><![CDATA[<div class=blog_content>
<p><a href="http://www.cnblogs.com/buffer/archive/2009/03/12/1409765.html"><u><font color=#108ac6>http://www.cnblogs.com/buffer/archive/2009/03/12/1409765.html</font></u></a></p>
<p>表头文件：#include &lt;string.h&gt;</p>
<div>C/C++中的Split函数是strtok()其函数原型如下: <br>char * strtok (char * str, const char * delimiters); <br><br>函数说明 <br>strtok()用来将字符串分割成一个个片段。参数str指向欲分割的字符串，参数delimiters则为分割字符串，当strtok()在参数str的字符串中发现到参数delimiters的分割字符时则会将该字符改为'\0'字符。在第一次调用时，strtok()必需给予参数str字符串，往后的调用则将参数str设置成NULL。每次调用成功则返回下一个分割后的字符串指针。 <br><br>返回值 <br>返回下一个分割后的字符串指针，如果已无从分割则返回NULL。 <br><br><br>示例-1 <br>/* strtok example */ <br>#include &lt;stdio.h&gt; <br>#include &lt;string.h&gt; <br><br>int main () <br>{ <br>char str[] ="a,b,c,d*e"; <br>const char * split = ","; <br>char * p; <br>p = strtok (str,split); <br>while(p!=NULL) { <br>printf ("%s\n",p); <br>p = strtok(NULL,split); <br>} <br><br>getchar(); <br>return 0; <br><br>} <br>本例中，实现对字符串'a,b,c,d*e"用逗号(,)来作界定符对字符串进行分割。 <br>输出结果将如下所示: <br>a <br>b <br>c <br>d*e <br><br>因为delimiters支持多个分割符, 我们将本示例中的语句行 <br>const char * split = ","; <br>改成 const char * split = ",*"; //用逗号(,)和星号(*)对字符串进行分割 <br><br>这样输出结果将如下所示: <br>a <br>b <br>c <br>d <br>e </div>
<div>例子2：</div>
<div>#include &lt;string.h&gt; <br>#include &lt;stdio.h&gt; <br>#include &lt;stdlib.h&gt; <br><br>char string[] = "1:ip:ipport:user "; <br>char seps[] = ": "; <br>char *token; <br><br>int main( void ) <br>{ <br>printf( "Tokens:\n " ); <br><br>// Establish string and get the first token: <br>token = strtok( string, seps ); // C4996 <br>// Note: strtok is deprecated; consider using strtok_s instead <br>while( token != NULL ) <br>{ <br>// While there are tokens in "string " <br>printf( "%s\n ", token ); <br><br>// Get next token: <br>token = strtok( NULL, seps ); // C4996 <br>} <br><br>system( "pause "); <br>return 0; <br>}</div>
</div>
<script type=text/javascript><!--
google_ad_client = "pub-1076724771190722";
/* JE个人博客468x60 */
google_ad_slot = "5506163105";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript>
</script>
<script src="http://pagead2.googlesyndication.com/pagead/expansion_embed.js"></script>
<script src="http://googleads.g.doubleclick.net/pagead/test_domain.js"></script>
<script src="http://pagead2.googlesyndication.com/pagead/render_ads.js"></script>
<script>google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad);</script>
<img src ="http://www.cppblog.com/prayer/aggbug/126656.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 13:49 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126656.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strtok</title><link>http://www.cppblog.com/prayer/archive/2010/09/15/126655.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Wed, 15 Sep 2010 05:47:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/15/126655.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126655.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/15/126655.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126655.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126655.html</trackback:ping><description><![CDATA[<h1 class=title>strtok</h1>
<fieldset class="text_dir nslog-area" id=catalog data-nslog-type="1016">
<p>目录</p>
<dl id=holder1 style="VISIBILITY: hidden; PADDING-BOTTOM: 20px; WIDTH: 262px">
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#1" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>原型</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#2" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>功能</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#3" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>说明</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#4" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>返回值</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>strtok函数在C和C++语言中的使用</font></u></a>
<ol style="DISPLAY: none">
    <li><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5_1" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>c</font></u></a>
    <li><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5_2" name=STAT_ONCLICK_UNSUBMIT_CATALOG><font color=#0000ff><u>c++</u></font></a></li>
</ol>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#6" name=STAT_ONCLICK_UNSUBMIT_CATALOG><font color=#0000ff><u>其他相关信息</u></font></a></dd></dl>
<dl class=arr id=holder2 style="DISPLAY: block; WIDTH: 262px">
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#1" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>原型</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#2" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>功能</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#3" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>说明</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#4" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>返回值</font></u></a>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>strtok函数在C和C++语言中的使用</font></u></a>
<ol style="DISPLAY: none">
    <li><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5_1" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>c</font></u></a>
    <li><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#5_2" name=STAT_ONCLICK_UNSUBMIT_CATALOG><font color=#0000ff><u>c++</u></font></a></li>
</ol>
<dd><a href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#6" name=STAT_ONCLICK_UNSUBMIT_CATALOG><u><font color=#0000ff>其他相关信息</font></u></a></dd>
<div class=nslog:1017 id=catalog-holder>展开</div>
</dl></fieldset>
<div class=clear></div>
<script type=text/javascript>bk.view.catalog.start();nslog.set("catalogshow",1);</script>
<div id=lemmaContent>
<h2 class=first>
<div class="text_edit editable-title" data-edit-id="1028553:1"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,1);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=1></a>原型</h2>
　　char *strtok(char *s, char *delim);
<div class=bpctrl></div>
<h2 class="">
<div class="text_edit editable-title" data-edit-id="1028553:2"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,2);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=2></a>功能</h2>
　　分解字符串为一组字符串。s为要分解的字符串，delim为分隔符字符串。
<div class=bpctrl></div>
<h2 class="">
<div class="text_edit editable-title" data-edit-id="1028553:3"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,3);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=3></a>说明</h2>
　　首次调用时，s指向要分解的字符串，之后再次调用要把s设成NULL。
<div class=spctrl></div>
　　strtok在s中查找包含在delim中的字符并用NULL('')来替换，直到找遍整个字符串。
<div class=spctrl></div>
　　char * p = strtok(s,";");
<div class=spctrl></div>
　　p = strtok(null,";");
<div class=spctrl></div>
　　在调用的过程中，字串s被改变了，这点是要注意的。
<div class=bpctrl></div>
<h2 class="">
<div class="text_edit editable-title" data-edit-id="1028553:4"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,4);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=4></a>返回值</h2>
　　从s开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。
<div class=spctrl></div>
　　所有delim中包含的字符都会被滤掉，并将被滤掉的地方设为一处分割的节点。
<div class=bpctrl></div>
<h2 class="">
<div class="text_edit editable-title" data-edit-id="1028553:5"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,5);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=5></a>strtok函数在C和C++语言中的使用</h2>
　　strtok函数会破坏被分解字符串的完整，调用前和调用后的s已经不一样了。如果
<div class=spctrl></div>
　　要保持原字符串的完整，可以使用strchr和sscanf的组合等。
<h3><a name=5_1></a>c</h3>
　　#include &lt;string.h&gt;
<div class=spctrl></div>
　　#include &lt;stdio.h&gt;
<div class=spctrl></div>
　　int main(void)
<div class=spctrl></div>
　　{
<div class=spctrl></div>
　　char input[16] = "abc,d";
<div class=spctrl></div>
　　char *p;
<div class=spctrl></div>
　　/**/ /* strtok places a NULL terminator
<div class=spctrl></div>
　　in front of the token, if found */
<div class=spctrl></div>
　　p = strtok(input, ",");
<div class=spctrl></div>
　　if (p) printf("%s\n", p);
<div class=spctrl></div>
　　/**/ /* A second call to strtok using a NULL
<div class=spctrl></div>
　　as the first parameter returns a pointer
<div class=spctrl></div>
　　to the character following the token */
<div class=spctrl></div>
　　p = strtok(NULL, ",");
<div class=spctrl></div>
　　if (p) printf("%s\n", p);
<div class=spctrl></div>
　　return 0;
<div class=spctrl></div>
　　}
<h3><a name=5_2></a>c++</h3>
　　#include &lt;iostream&gt;
<div class=spctrl></div>
　　#include &lt;cstring&gt;
<div class=spctrl></div>
　　using namespace std;
<div class=spctrl></div>
　　int main()
<div class=spctrl></div>
　　{
<div class=spctrl></div>
　　char sentence[]="This is a sentence with 7 tokens";
<div class=spctrl></div>
　　cout&lt;&lt;"The string to be tokenized is:\n"&lt;&lt;sentence&lt;&lt;"\n\nThe tokens are:\n\n";
<div class=spctrl></div>
　　char *tokenPtr=strtok(sentence," ");
<div class=spctrl></div>
　　while(tokenPtr!=NULL)
<div class=spctrl></div>
　　{
<div class=spctrl></div>
　　cout&lt;&lt;tokenPtr&lt;&lt;'\n';
<div class=spctrl></div>
　　tokenPtr=strtok(NULL," ");
<div class=spctrl></div>
　　}
<div class=spctrl></div>
　　cout&lt;&lt;"After strtok, sentence = "&lt;&lt;sentence&lt;&lt;endl;
<div class=spctrl></div>
　　return 0;
<div class=spctrl></div>
　　}
<div class=spctrl></div>
　　函数第一次调用需设置两个参数。第一次分割的结果，返回串中第一个 ',' 之前的字符串,也就是上面的程序第一次输出abc。
<div class=spctrl></div>
　　第二次调用该函数strtok(NULL,","),第一个参数设置为NULL。结果返回分割依据后面的字串，即第二次输出d。
<div class=spctrl></div>
　　strtok是一个线程不安全的函数，因为它使用了静态分配的空间来存储被分割的字符串位置
<div class=spctrl></div>
　　线程安全的函数叫strtok_r,ca
<div class=spctrl></div>
　　运用strtok来判断ip或者mac的时候务必要先用其他的方法判断'.'或':'的个数，因为用strtok截断的话，比如："192..168.0...8..."这个字符串，strtok只会截取四次，中间的...无论多少都会被当作一个key
<div class=bpctrl></div>
<h2 class="">
<div class="text_edit editable-title" data-edit-id="1028553:6"><a class=nslog:1019 onclick='bk.view.editLemma("/edit/",1028553,6);return false' href="http://baike.baidu.com/view/1028553.htm?fr=ala0_1_1#"><u><font color=#0000ff>编辑本段</font></u></a></div>
<a name=6></a>其他相关信息</h2>
　　下面的说明摘自于最新的Linux内核2.6.29，说明了这个函数已经不再使用，由速度更快的strsep（）代替
<div class=spctrl></div>
　　/*
<div class=spctrl></div>
　　* linux/lib/string.c
<div class=spctrl></div>
　　*
<div class=spctrl></div>
　　* Copyright (C) 1991, 1992 Linus Torvalds
<div class=spctrl></div>
　　*/
<div class=spctrl></div>
　　/*
<div class=spctrl></div>
　　* stupid library routines.. The optimized versions should generally be found
<div class=spctrl></div>
　　* as inline code in &lt;asm-xx/string.h&gt;
<div class=spctrl></div>
　　*
<div class=spctrl></div>
　　* These are buggy as well..
<div class=spctrl></div>
　　*
<div class=spctrl></div>
　　* * Fri Jun 25 1999, Ingo Oeser &lt;ioe@informatik.tu-chemnitz.de&gt;
<div class=spctrl></div>
　　* - Added strsep() which will replace strtok() soon (because strsep() is
<div class=spctrl></div>
　　* reentrant and should be faster). Use only strsep() in new code, please.
<div class=spctrl></div>
　　*
<div class=spctrl></div>
　　* * Sat Feb 09 2002, Jason Thomas &lt;jason@topic.com.au&gt;,
<div class=spctrl></div>
　　* Matthew Hawkins &lt;matt@mh.dropbear.id.au&gt;
<div class=spctrl></div>
　　* - Kissed strtok() goodbye </div>
<img src ="http://www.cppblog.com/prayer/aggbug/126655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-15 13:47 <a href="http://www.cppblog.com/prayer/archive/2010/09/15/126655.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>七种qsort排序方法</title><link>http://www.cppblog.com/prayer/archive/2010/09/07/126094.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 07 Sep 2010 08:02:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/07/126094.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126094.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/07/126094.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126094.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126094.html</trackback:ping><description><![CDATA[七种qsort排序方法 <br><br>&lt;本文中排序都是采用的从小到大排序&gt; <br><br>一、对int类型数组排序 <br><br>int num[100]; <br><br>Sample: <br><br>int cmp ( const void *a , const void *b ) <br>{ <br>return *(int *)a - *(int *)b; <br>} <br><br>qsort(num,100,sizeof(num[0]),cmp); <br><br>二、对char类型数组排序（同int类型） <br><br>char word[100]; <br><br>Sample: <br><br>int cmp( const void *a , const void *b ) <br>{ <br>return *(char *)a - *(int *)b; <br>} <br><br>qsort(word,100,sizeof(word[0]),cmp); <br><br>三、对double类型数组排序（特别要注意） <br><br>double in[100]; <br><br>int cmp( const void *a , const void *b ) <br>{ <br>return *(double *)a &gt; *(double *)b ? 1 : -1; <br>} <br><br>qsort(in,100,sizeof(in[0]),cmp)； <br><br>四、对结构体一级排序 <br><br>struct In <br>{ <br>double data; <br>int other; <br>}s[100] <br><br>//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种，参考上面的例子写 <br><br>int cmp( const void *a ,const void *b) <br>{ <br>return (*(In *)a).data &gt; (*(In *)b).data ? 1 : -1; <br>} <br><br>qsort(s,100,sizeof(s[0]),cmp); <br><br>五、对结构体二级排序 <br><br>struct In <br>{ <br>int x; <br>int y; <br>}s[100]; <br><br>//按照x从小到大排序，当x相等时按照y从大到小排序 <br><br>int cmp( const void *a , const void *b ) <br>{ <br>struct In *c = (In *)a; <br>struct In *d = (In *)b; <br>if(c-&gt;x != d-&gt;x) return c-&gt;x - d-&gt;x; <br>else return d-&gt;y - c-&gt;y; <br>} <br><br>qsort(s,100,sizeof(s[0]),cmp); <br><br>六、对字符串进行排序 <br><br>struct In <br>{ <br>int data; <br>char str[100]; <br>}s[100]; <br><br>//按照结构体中字符串str的字典顺序排序 <br><br>int cmp ( const void *a , const void *b ) <br>{ <br>return strcmp( (*(In *)a)-&gt;str , (*(In *)b)-&gt;str ); <br>} <br><br>qsort(s,100,sizeof(s[0]),cmp); <br><br>七、计算几何中求凸包的cmp <br><br>int cmp(const void *a,const void *b) //重点cmp函数，把除了1点外的所有点，旋转角度排序 <br>{ <br>struct point *c=(point *)a; <br>struct point *d=(point *)b; <br>if( calc(*c,*d,p[1]) &lt; 0) return 1; <br>else if( !calc(*c,*d,p[1]) &amp;&amp; dis(c-&gt;x,c-&gt;y,p[1].x,p[1].y) &lt; dis(d-&gt;x,d-&gt;y,p[1].x,p[1].y)) //如果在一条直线上，则把远的放在前面 <br>return 1; <br>else return -1; <br>} <br><br>PS: <br><br>其中的qsort函数包含在&lt;stdlib.h&gt;的头文件里，strcmp包含在&lt;string.h&gt;的头文件里
<img src ="http://www.cppblog.com/prayer/aggbug/126094.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-07 16:02 <a href="http://www.cppblog.com/prayer/archive/2010/09/07/126094.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>qsort与bsearch的cmp（转）</title><link>http://www.cppblog.com/prayer/archive/2010/09/07/126093.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Tue, 07 Sep 2010 07:07:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/07/126093.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126093.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/07/126093.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126093.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126093.html</trackback:ping><description><![CDATA[<table style="TABLE-LAYOUT: fixed; WIDTH: 100%">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <p>
            <table cellSpacing=0 cellPadding=0 width="100%" border=0>
                <tbody>
                    <tr>
                        <td>
                        <p><font size=3>qsort函数声明如下：</font></p>
                        <p><font size=3>void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));</font></p>
                        <p><font size=3>参数说明如下：<br>base: 要排序的数组<br>nmemb: 数组中的元素数目<br>size: 每个数组元素占用内存空间，可使用sizeof获得<br><strong>compar: 比较两个数组元素的比较函数。本比较函数的第一个参数值小于、等于、大于第二参数值时，本比较函数的返回值应分别小于、等于、大于零。</strong></font></p>
                        <p><font size=3><strong>也就说你要实现一个这样的函数：<br>int cmp(const void *a, const void *b)<br>如果a &gt; b，返回&gt;0<br>如果a == b, 返回0<br>如果a &lt; b，返回&lt;0<br>这里的a和b的关系仅仅是逻辑上的，并不是值比较，所以排序的可以不仅仅是数字，还可以是字符。</strong></font></p>
                        </td>
                    </tr>
                </tbody>
            </table>
            </p>
            <p>&#160;</p>
            <p><font size=3>bsearch函数声明如下：</font></p>
            <p><font size=3>void *bsearch(const void *key, const void *base, size_t *nelem, <br>size_t width, int(*fcmp)(const void *, const *));</font></p>
            <p><font size=3>参数的意思和qsort的差不多，区别在于：<br>1. qsort用来排序，bsearch用二分法来查找元素<br>2. bsearch中的base必须是升序排列的数组！！！<br><strong>3. 如果数组里有重复的答案，则bsearch会返回其中一个的地址 （具体返回哪一个不确定）</strong><br>4. bsearch有五个自变量，第一个是要找的东西，剩下的跟qsort一模一样<br>5. bsearch如果没找到所求则回传NULL ，否则回传该元素被找到的地址(void *) <br></font></p>
            <p><font size=3>c函数qsort()和bsearch()的用法 <br>使用qsort()排序 并 用 bsearch（）搜索是一个比较常用的组合，使用方便快捷。 <br>qsort 的函数原型是void __cdecl qsort ( void *base, size_t num, size_t width, int (__cdecl *comp)(const void *, const void* ) )</font></p>
            <p><font size=3>其中base是排序的一个集合数组，num是这个数组元素的个数，width是一个元素的大小，comp是一个比较函数。</font></p>
            <p><font size=3>比如：对一个长为1000的数组进行排序时，int a[1000]; 那么base应为a，num应为 1000，width应为 sizeof(int)，comp函数随自己的命名。</font></p>
            <p><font size=3>qsort(a,1000,sizeof(int ),comp);</font></p>
            <p><font size=3>其中comp函数应写为:</font></p>
            <p><font size=3>int comp(const void *a,const void *b) <br>{ <br>return *(int *)a-*(int *)b; <br>}</font></p>
            <p><font size=3>而关于bsearch() ,他和qsort的用法基本一样，只是他的返回值是一个指向找到的单位元素的一个指针，另外他多了一个参数，是一个指向查找元素的一个指针。</font></p>
            <p><font size=3>比如：从上面例子中的结构体数组中查找一个字符串：</font></p>
            <p><font size=3>str *locate; <br>char buffer[30]="abc"; <br>locate=(str*)bsearch(buffer,strin,total,sizeof(str),com);</font></p>
            <p><font size=3>int com(const void *a,const void *b) <br>{ <br>return strcmp( (char*)a, ((str*)b)-&gt;str2 ); <br>}</font></p>
            <p><font size=3>注意这里cmp与qsotr的有所不同。</font></p>
            <p><font color=#ff0000 size=4>qsort 和bsearch的cmp函数不同的<br>qsort 比较的时dict 数组的两个成员<br>bsearch比较的时key 和dict中成员</font></p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/prayer/aggbug/126093.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-07 15:07 <a href="http://www.cppblog.com/prayer/archive/2010/09/07/126093.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>atoi函数源代码</title><link>http://www.cppblog.com/prayer/archive/2010/09/06/126014.html</link><dc:creator>Prayer</dc:creator><author>Prayer</author><pubDate>Mon, 06 Sep 2010 05:13:00 GMT</pubDate><guid>http://www.cppblog.com/prayer/archive/2010/09/06/126014.html</guid><wfw:comment>http://www.cppblog.com/prayer/comments/126014.html</wfw:comment><comments>http://www.cppblog.com/prayer/archive/2010/09/06/126014.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/prayer/comments/commentRss/126014.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/prayer/services/trackbacks/126014.html</trackback:ping><description><![CDATA[<p>isspace(int x)<br>{<br>&nbsp;if(x==' '||x=='\t'||x=='\n'||x=='\f'||x=='\b'||x=='\r')<br>&nbsp; return 1;<br>&nbsp;else&nbsp; <br>&nbsp; return 0;<br>}<br>isdigit(int x)<br>{<br>&nbsp;if(x&lt;='9'&amp;&amp;x&gt;='0')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; return 1;x` <br>&nbsp;else <br>&nbsp; return 0;</p>
<p>}<br>int atoi(const char *nptr)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* current char */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int total;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* current total */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sign;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* if '-', then negative, otherwise positive */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* skip whitespace */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( isspace((int)(unsigned char)*nptr) )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++nptr;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (int)(unsigned char)*nptr++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sign = c;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* save sign indication */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (c == '-' || c == '+')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (int)(unsigned char)*nptr++;&nbsp;&nbsp;&nbsp; /* skip sign */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (isdigit(c)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total = 10 * total + (c - '0');&nbsp;&nbsp;&nbsp;&nbsp; /* accumulate digit */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = (int)(unsigned char)*nptr++;&nbsp;&nbsp;&nbsp; /* get next char */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (sign == '-')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -total;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return total;&nbsp;&nbsp; /* return result, negated if necessary */<br>} </p>
<p>&nbsp;</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/udknight/archive/2007/10/22/1836799.aspx">http://blog.csdn.net/udknight/archive/2007/10/22/1836799.aspx</a></p>
<img src ="http://www.cppblog.com/prayer/aggbug/126014.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/prayer/" target="_blank">Prayer</a> 2010-09-06 13:13 <a href="http://www.cppblog.com/prayer/archive/2010/09/06/126014.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>