<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>不然你要我怎么样 &#187; C</title>
	<atom:link href="http://www.xiangmocheng.com/tag/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xiangmocheng.com</link>
	<description>彪悍的代码不需要注释</description>
	<lastBuildDate>Wed, 30 Nov 2011 11:47:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>使用gdb在Android Emulator中进行调试c程序</title>
		<link>http://www.xiangmocheng.com/2009/06/how-to-debug-c-program-in-android-emulator-by-gdb/</link>
		<comments>http://www.xiangmocheng.com/2009/06/how-to-debug-c-program-in-android-emulator-by-gdb/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 13:42:39 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[GDB]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/%e4%bd%bf%e7%94%a8gdb%e5%9c%a8android-emulator%e4%b8%ad%e8%bf%9b%e8%a1%8c%e8%b0%83%e8%af%95c%e7%a8%8b%e5%ba%8f.html</guid>
		<description><![CDATA[参考文章：Debug Native c/c++ Application for Android(Step by Step) 和Google Android Debugging Utilities 首先，我们需要一个含有调试信息的exe文件，一般这个文件存在于out/target/product/generic/obj/EXECUTABLES/yourexefile_intermediates/LINKED/libomstts目录下，这里以我们前面文章中生成的helloworld为例。 1. 下载Android Debugging Utilities gdb and gdb-server (6.8) 2. 启动Android Emulator模拟器 $ emulator @1.5_R2 3. 把gdb和调试文件以及源代码放到模拟器上 $ adb push gdb /data/bin $ adb push helloworld /data/bin 以helloworld为例，源代码要放在/data/bin/development/hello目录下。 有的文章说将以上文件放在/system/bin目录下，但后果是一旦关掉模拟器，这些的文件就消失了，下次又要重传~所以推荐放在/data/bin目录下。 4. 启动shell $adb shell 如果提示文件系统不可写的话，执行： ＃mount -o remount 5. 因为Android文件系统没有/bin/sh, 所以这里有两种解决方法（推荐第二种方法）： (1). 拷贝一个bash文件(点击下载)到/bin目录下： #mkdir [...]]]></description>
			<content:encoded><![CDATA[<p>参考文章：<a href="http://www.cppblog.com/luonjtu/archive/2009/02/19/74310.html" target="_blank">Debug Native c/c++ Application for Android(Step by Step)</a></p>
<p>和<a href="http://ortegaalfredo.googlepages.com/android" target="_blank">Google Android Debugging Utilities</a></p>
<p>首先，我们需要一个含有调试信息的exe文件，一般这个文件存在于out/target/product/generic/obj/EXECUTABLES/<span style="color: #ff0000;">yourexefile</span>_intermediates/LINKED/libomstts目录下，这里以我们<a title="【转贴】Android编译环境(1) – 编译Native C的helloworld模块" href="http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module/" target="_blank">前面文章</a>中生成的helloworld为例。</p>
<p>1. 下载Android Debugging Utilities</p>
<p><a href="http://ortegaalfredo.googlepages.com/android-gdb-6.8.tar.bz2" target="_blank">gdb and gdb-server (6.8)</a></p>
<p>2. 启动Android Emulator模拟器</p>
<p>$ emulator @1.5_R2</p>
<p>3. 把gdb和调试文件以及源代码放到模拟器上</p>
<p>$ adb push gdb /data/bin</p>
<p>$ adb push helloworld /data/bin</p>
<p>以helloworld为例，源代码要放在/data/bin<span style="color: #ff0000;">/development/hello</span>目录下。</p>
<p>有的文章说将以上文件放在/system/bin目录下，但后果是一旦关掉模拟器，这些的文件就消失了，下次又要重传~所以推荐放在/data/bin目录下。</p>
<p>4. 启动shell</p>
<p>$adb shell</p>
<p>如果提示文件系统不可写的话，执行：</p>
<p>＃mount -o remount</p>
<p>5. 因为Android文件系统没有/bin/sh, 所以这里有两种解决方法（推荐第二种方法）：</p>
<p>(1). 拷贝一个bash文件(<a href="http://www.xiangmocheng.com/downloads/bash.tar.bz2" target="_blank">点击下载</a>)到/bin目录下：</p>
<p>#mkdir /bin</p>
<p>$adb push bash /bin</p>
<p>(2). 或者设置SHELL的路径：</p>
<p>#export SHELL=/system/bin/sh</p>
<p>6. 进入/data/bin目录，运行gdb，可以开始调试程序了</p>
<p>#cd /data/bin</p>
<p>#./gdb helloworld
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2009/06/how-to-debug-c-program-in-android-emulator-by-gdb/">使用gdb在Android Emulator中进行调试c程序</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2009/06/how-to-debug-c-program-in-android-emulator-by-gdb/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>【转贴】Android编译环境(2) &#8211; 手工编译C模块</title>
		<link>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module-manually/</link>
		<comments>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module-manually/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 12:51:46 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Native]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/%e3%80%90%e8%bd%ac%e8%b4%b4%e3%80%91android%e7%bc%96%e8%af%91%e7%8e%af%e5%a2%832-%e6%89%8b%e5%b7%a5%e7%bc%96%e8%af%91c%e6%a8%a1%e5%9d%97.html</guid>
		<description><![CDATA[原文点击这里 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- Android编译环境提供了”showcommands”选项来显示编译命令行，我们可以通过打开这个选项来查看一些编译时的细节。当然，在这之前要把上一篇中的helloworld模块clean: # make clean-helloworld 上面的“make clean-$(LOCAL_MODULE)”是Android编译环境提供的make clean的方式。 接下来使用showcommands选项重新编译helloworld: # make helloworld showcommands build/core/product_config.mk:229: WARNING: adding test OTA key target thumb C: helloworld &#60;= development/hello/hello.c prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc  -I system/core/include   -I hardware/libhardware/include   -I hardware/ril/include   -I dalvik/libnativehelper/include   -I frameworks/base/include   -I external/skia/include   -I out/target/product/generic/obj/include   -I bionic/libc/arch-arm/include   -I bionic/libc/include   -I bionic/libstdc++/include   -I bionic/libc/kernel/common   -I bionic/libc/kernel/arch-arm   -I bionic/libm/include   -I bionic/libm/include/arch/arm   [...]]]></description>
			<content:encoded><![CDATA[<p>原文点击<a href="http://www.top-e.org/jiaoshi/html/?161.html" target="_blank">这里</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Android编译环境提供了”showcommands”选项来显示编译命令行，我们可以通过打开这个选项来查看一些编译时的细节。当然，在这之前要把上一篇中的helloworld模块clean:</p>
<p># make clean-helloworld</p>
<p>上面的“make clean-$(LOCAL_MODULE)”是Android编译环境提供的make clean的方式。</p>
<p>接下来使用showcommands选项重新编译helloworld:</p>
<table class="MsoTableGrid" style="border: medium none; margin: auto auto auto 23.4pt; background: none repeat scroll 0% 0% #b3b3b3; width: 378pt; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="504">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 378pt; background-color: transparent;" width="504" valign="top">
<p># make helloworld showcommands</p>
<p>build/core/product_config.mk:229: WARNING: adding test OTA key</p>
<p>target thumb C: helloworld &lt;= development/hello/hello.c</p>
<p>prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc  -I system/core/include   -I hardware/libhardware/include   -I hardware/ril/include   -I dalvik/libnativehelper/include   -I frameworks/base/include   -I external/skia/include   -I out/target/product/generic/obj/include   -I bionic/libc/arch-arm/include   -I bionic/libc/include   -I bionic/libstdc++/include   -I bionic/libc/kernel/common   -I bionic/libc/kernel/arch-arm   -I bionic/libm/include   -I bionic/libm/include/arch/arm   -I bionic/libthread_db/include   -I development/hello   -I out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates  -c  -fno-exceptions<br />
-Wno-multichar -march=armv5te -mtune=xscale -msoft-float -fpic<br />
-mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector<br />
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__<br />
-include system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID<br />
-fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG -O2 -g<br />
-Wstrict-aliasing=2 -finline-functions<br />
-fno-inline-functions-called-once -fgcse-after-reload<br />
-frerun-cse-after-loop -frename-registers -DNDEBUG -UDEBUG -mthumb -Os<br />
-fomit-frame-pointer -fno-strict-aliasing -finline-limit=64      -MD -o out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o development/hello/hello.c</p>
<p>target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)</p>
<p>prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-g++<br />
-nostdlib -Bdynamic -Wl,-T,build/core/armelf.x<br />
-Wl,-dynamic-linker,/system/bin/linker -Wl,&#8211;gc-sections<br />
-Wl,-z,nocopyreloc -o<br />
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld<br />
-Lout/target/product/generic/obj/lib<br />
-Wl,-rpath-link=out/target/product/generic/obj/lib -lc -lstdc++ -lm  out/target/product/generic/obj/lib/crtbegin_dynamic.o         out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o       -Wl,&#8211;no-undefined<br />
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a<br />
out/target/product/generic/obj/lib/crtend_android.o</p>
<p>target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld)</p>
<p>out/host/linux-x86/bin/acp<br />
-fpt<br />
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld<br />
out/target/product/generic/symbols/system/bin/helloworld</p>
<p>target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld)</p>
<p>out/host/linux-x86/bin/soslim<br />
&#8211;strip &#8211;shady &#8211;quiet<br />
out/target/product/generic/symbols/system/bin/helloworld &#8211;outfile<br />
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld</p>
<p>Install: out/target/product/generic/system/bin/helloworld</p>
<p>out/host/linux-x86/bin/acp<br />
-fpt<br />
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld<br />
out/target/product/generic/system/bin/helloworld</td>
</tr>
</tbody>
</table>
<p>从上面的命令行可以看到，Android编译环境所用的交叉编译工具链是prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc，-I和-L参数指定了所用的C库头文件和动态库文件路径分别是bionic/libc/include 和out/target/product/generic/obj/lib，其他还包括很多编译选项以及-D所定义的预编译宏。</p>
<p>我们可以利用上面的编译命令，稍加简化来手工编译helloworld程序。先手工删除上次编译得到的helloworld程序：</p>
<table class="MsoTableGrid" style="border: medium none; margin: auto auto auto 23.4pt; background: none repeat scroll 0% 0% #b3b3b3; width: 378pt; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="504">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 378pt; background-color: transparent;" width="504" valign="top">
<p># rm out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o</p>
<p># rm out/target/product/generic/system/bin/helloworld</td>
</tr>
</tbody>
</table>
<p>再用gcc编译，生成目标文件：</p>
<table class="MsoTableGrid" style="border: medium none; margin: auto auto auto 23.4pt; background: none repeat scroll 0% 0% #b3b3b3; width: 378pt; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="504">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 378pt; background-color: transparent;" width="504" valign="top">#<br />
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -I<br />
bionic/libc/arch-arm/include -I bionic/libc/include -I<br />
bionic/libc/kernel/common   -I bionic/libc/kernel/arch-arm -c  -fno-exceptions<br />
-Wno-multichar -march=armv5te -mtune=xscale -msoft-float -fpic<br />
-mthumb-interwork -ffunction-sections -funwind-tables -fstack-protector<br />
-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__<br />
-include system/core/include/arch/linux-arm/AndroidConfig.h -DANDROID<br />
-fmessage-length=0 -W -Wall -Wno-unused -DSK_RELEASE -DNDEBUG -O2 -g<br />
-Wstrict-aliasing=2 -finline-functions<br />
-fno-inline-functions-called-once -fgcse-after-reload<br />
-frerun-cse-after-loop -frename-registers -DNDEBUG -UDEBUG -mthumb -Os<br />
-fomit-frame-pointer -fno-strict-aliasing -finline-limit=64      -MD -o out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o development/hello/hello.c</td>
</tr>
</tbody>
</table>
<p>与Android.mk编译参数比较，上面主要减少了不必要的-I参数。</p>
<p>接下来生成可执行文件：</p>
<table class="MsoTableGrid" style="border: medium none; margin: auto auto auto 23.4pt; background: none repeat scroll 0% 0% #b3b3b3; width: 378pt; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="504">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 378pt; background-color: transparent;" width="504" valign="top">#<br />
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -nostdlib<br />
-Bdynamic -Wl,-T,build/core/armelf.x<br />
-Wl,-dynamic-linker,/system/bin/linker -Wl,&#8211;gc-sections<br />
-Wl,-z,nocopyreloc -o<br />
out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld<br />
-Lout/target/product/generic/obj/lib<br />
-Wl,-rpath-link=out/target/product/generic/obj/lib -lc -lm  out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/hello.o<br />
out/target/product/generic/obj/lib/crtbegin_dynamic.o<br />
-Wl,&#8211;no-undefined<br />
./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a<br />
out/target/product/generic/obj/lib/crtend_android.o</td>
</tr>
</tbody>
</table>
<p>这里值得留意的是参数“-Wl,-dynamic-linker,/system/bin/linker”，它指定了Android专用的动态链接器/system/bin/linker，而不是通常所用的ld.so。</p>
<p>生成的可执行程序可用file和readelf命令来查看一下：</p>
<table class="MsoTableGrid" style="border: medium none; margin: auto auto auto 23.4pt; background: none repeat scroll 0% 0% #b3b3b3; width: 378pt; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="504">
<tbody>
<tr>
<td style="border: 1pt solid windowtext; padding: 0cm 5.4pt; width: 378pt; background-color: transparent;" width="504" valign="top">
<p># file out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld</p>
<p>out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld:<br />
ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked<br />
(uses shared libs), not stripped</p>
<p>#  readelf -d out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld |grep NEEDED</p>
<p>0&#215;00000001 (NEEDED)                     Shared library: [libc.so]</p>
<p>0&#215;00000001 (NEEDED)                     Shared library: [libm.so]</td>
</tr>
</tbody>
</table>
<p>这是ARM格式的动态链接可执行文件，运行时需要libc.so和libm.so。“not stripped”表示它还没被STRIP。嵌入式系统中为节省空间通常将编译完成的可执行文件或动态库进行STRIP，即去掉其中多余的符号表信息。在前面“make helloworld showcommands”命令的最后我们也可以看到，Android编译环境中使用了out/host/linux-x86/bin/soslim工具进行STRIP。</p>
<p>有关Android Toolchain的其他一些内容可参考：<a href="http://www.top-e.org/jiaoshi/html/?151.html" target="_self"><strong>Android Toolchain与Bionic Libc</strong></a></p>
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module-manually/">【转贴】Android编译环境(2) &#8211; 手工编译C模块</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module-manually/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>【转贴】Android编译环境(1) &#8211; 编译Native C的helloworld模块</title>
		<link>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module/</link>
		<comments>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 12:37:27 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Native]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/%e3%80%90%e8%bd%ac%e8%b4%b4%e3%80%91android%e7%bc%96%e8%af%91%e7%8e%af%e5%a2%831-%e7%bc%96%e8%af%91native-c%e7%9a%84helloworld%e6%a8%a1%e5%9d%97.html</guid>
		<description><![CDATA[原文点击这里 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; Android 编译环境本身比较复杂，且不像普通的编译环境：只有顶层目录下才有Makefile文件，而其他的每个component都使用统一标准的 Android.mk. Android.mk文件本身是比较简单的，不过它并不是我们熟悉的Makefile，而是经过了Android自身编译系统的很多处理，因此要真正理清楚其中的联系还比较复杂，不过这种方式的好处在于，编写一个新的Android.mk来给Android增加一个新的Component会比较简单。编译Java程序可以直接采用Eclipse的集成环境来完成，这里就不重复了。我们主要针对C/C++来说明，下面通过一个小例子来说明，如何在Android 中增加一个C程序的Hello World： 1. 在$(YOUR_ANDROID)/development目录下创建hello目录，其中$(YOUR_ANDROID)指Android源代码所在的目录。 $ mkdir $(YOUR_ANDROID)/development/hello 2. 在$(YOUR_ANDROID)/development/hello/目录编写hello.c文件，hello.c的内容当然就是经典的HelloWorld程序： 3.在$(YOUR_ANDROID)/development/hello/目录编写Android.mk文件。这是Android Makefile的标准命名，不要更改。Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法，针对helloworld程序的Android.mk文件内容如下： 注意上面LOCAL_SRC_FILES用来指定源文件，LOCAL_MODULE指定要编译的模块的名字，下一步骤编译时就要用到。include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件，如果想编译成动态库则可用BUILD_SHARED_LIBRARY，这些可以在$(YOUR_ANDROID)/build/core/config.mk查到。 4. 回到Android源代码顶层目录进行编译： # cd $(YOUR_ANDROID) &#38;&#38; make helloworld 注意make helloworld中的目标名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下： target thumb C: helloworld &#60;= development/hello/hello.c target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld) target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld) target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld) Install: out/target/product/generic/system/bin/helloworld 5．如上面的编译结果所示，编译后的可执行文件存放在out/target/product/generic/system/bin/helloworld，通过”adb push”将它传送到模拟器上，再通过”adb shell”登录到模拟器终端，就可以执行了 转载请注明： 转载自不然你要我怎么样 本文链接地址: [...]]]></description>
			<content:encoded><![CDATA[<p>原文点击<a href="http://www.top-e.org/jiaoshi/html/?157.html" target="_blank">这里</a></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Android 编译环境本身比较复杂，且不像普通的编译环境：只有顶层目录下才有Makefile文件，而其他的每个component都使用统一标准的 Android.mk. Android.mk文件本身是比较简单的，不过它并不是我们熟悉的Makefile，而是经过了Android自身编译系统的很多处理，因此要真正理清楚其中的联系还比较复杂，不过这种方式的好处在于，编写一个新的Android.mk来给Android增加一个新的Component会比较简单。编译Java程序可以直接采用Eclipse的集成环境来完成，这里就不重复了。我们主要针对C/C++来说明，下面通过一个小例子来说明，如何在Android 中增加一个C程序的Hello World：</p>
<p>1. 在<strong>$(YOUR_ANDROID)/development</strong>目录下创建<strong>hello</strong>目录，其中<strong>$(YOUR_ANDROID)</strong>指Android源代码所在的目录。</p>
<p><strong>$ mkdir $(YOUR_ANDROID)/development/hello</strong></p>
<p>2. 在<strong>$(YOUR_ANDROID)/development/hello/</strong>目录编写<strong>hello.c</strong>文件，hello.c的内容当然就是经典的HelloWorld程序：</p>
<pre class="brush: cpp; title: ; notranslate">int main()
{
printf(&quot;Hello World!\n&quot;);
return 0;
}</pre>
<p>3.在<strong>$(YOUR_ANDROID)/development/hello/</strong>目录编写<strong>Android.mk</strong>文件。这是Android Makefile的标准命名，不要更改。Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法，针对helloworld程序的Android.mk文件内容如下：</p>
<pre class="brush: cpp; title: ; notranslate">LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
hello.c

LOCAL_MODULE := helloworld
include $(BUILD_EXECUTABLE)</pre>
<p>注意上面LOCAL_SRC_FILES用来指定源文件，LOCAL_MODULE指定要编译的模块的名字，下一步骤编译时就要用到。include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件，如果想编译成动态库则可用BUILD_SHARED_LIBRARY，这些可以在<strong>$(YOUR_ANDROID)/build/core/config.mk</strong>查到。</p>
<p>4. 回到Android源代码顶层目录进行编译：</p>
<p><strong># cd $(YOUR_ANDROID) &amp;&amp; make helloworld</strong></p>
<p>注意make helloworld中的目标名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下：</p>
<p><strong>target thumb C: helloworld &lt;= development/hello/hello.c<br />
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)<br />
target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld)<br />
target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld)<br />
Install: out/target/product/generic/system/bin/helloworld</strong></p>
<p>5．如上面的编译结果所示，编译后的可执行文件存放在<strong>out/target/product/generic/system/bin/helloworld</strong>，通过”adb push”将它传送到模拟器上，再通过”adb shell”登录到模拟器终端，就可以执行了
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module/">【转贴】Android编译环境(1) &#8211; 编译Native C的helloworld模块</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2009/06/android-build-environment-how-to-compile-native-c-module/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>【转贴】sizeof(结构体)和内存对齐</title>
		<link>http://www.xiangmocheng.com/2009/03/sizeof-structure-memory-alignment/</link>
		<comments>http://www.xiangmocheng.com/2009/03/sizeof-structure-memory-alignment/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 06:04:00 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/%e3%80%90%e8%bd%ac%e8%b4%b4%e3%80%91sizeof%e7%bb%93%e6%9e%84%e4%bd%93%e5%92%8c%e5%86%85%e5%ad%98%e5%af%b9%e9%bd%90.html</guid>
		<description><![CDATA[（一） 有的时候，在脑海中停顿了很久的“显而易见”的东西，其实根本上就是错误的。就拿下面的问题来看： 使用sizeof(T)，将得到什么样的答案呢？要是以前，想都不用想，在32位机中，int是4个字节，char是1个字节，所以T一共是5个字节。实践出真知，在VC6中测试了下，答案确实8个字节。哎，反正受伤的总是我，我已经有点麻木了，还是老老实实的接受吧！为什么答案和自己想象的有出入呢？这里将引入内存对齐这个概念。 许多实际的计算机系统对基本类型数据在内存中存放的位置有限制，它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数，这就是所谓的内存对齐，而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数，我们就称类型S的对齐要求比T强(严格)，而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计，二来可以提升读取数据的速度。比如这么一种处理器，它每次读写内存的时候都从某个8倍数的地址开始，一次读出或写入8个字节的数据，假如软件能保证double类型的数据都从8倍数地址开始，那么读或写一个double类型数据就只需要一次内存操作。否则，我们就可能需要两次内存操作才能完成这个动作，因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错，但是Intel的IA32架构的处理器则不管数据是否对齐都能正确工作。不过Intel奉劝大家，如果想提升性能，那么所有的程序数据都应该尽可能地对齐。 ANSI C标准中并没有规定，相邻声明的变量在内存中一定要相邻。为了程序的高效性，内存对齐问题由编译器自行灵活处理，这样导致相邻的变量之间可能会有一些填充字节。对于基本数据类型(int char)，他们占用的内存空间在一个确定硬件系统下有个确定的值，所以，接下来我们只是考虑结构体成员内存分配情况。 Win32平台下的微软C编译器(cl.exe for 80×86)的对齐策略： 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除； 备注：编译器在给结构体开辟空间时，首先找到结构体中最宽的基本数据类型，然后寻找内存地址能被该基本数据类型所整除的位置，作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。 2) 结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字节（internal adding）； 备注:为结构体的一个成员开辟空间之前，编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍，若是，则存放本成员，反之，则在本成员和上一个成员之间填充一定的字节，以达到整数倍的要求，也就是将预开辟空间的首地址后移几个字节。 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍，如有需要，编译器会在最末一个成员之后加上填充字节（trailing padding）。 备注：结构体总大小是包括填充字节，最后一个成员满足上面两条以外，还必须满足第三条，否则就必须在最后填充几个字节以达到本条要求。 根据以上准则，在windows下，使用VC编译器，sizeof(T)的大小为1(char) + 3(填充) + 4(int) =8个字节。 而在GNU GCC编译器中，遵循的准则有些区别，对齐模数不是像上面所述的那样，根据最宽的基本数据类型来定。在GCC中，对齐模数的准则是：对齐模数最大只能是4，也就是说，即使结构体中有double类型，对齐模数还是4，所以对齐模数只能是1，2，4。而且在上述的三条中，第2条里，offset必须是成员大小的整数倍，如果这个成员大小小于等于4则按照上述准则进行，但是如果大于4了，则结构体每个成员相对于结构体首地址的偏移量（offset）只能按照是4的整数倍来进行判断是否添加填充。 看如下例子： 那么在GCC下，sizeof(T)应该等于12个字节。 如果结构体中含有位域(bit-field)，那么VC中准则又要有所更改： 1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止； 2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍； 3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式（不同位域字段存放在不同的位域类型字节中），Dev-C++和GCC都采取压缩方式； 备注：当两字段类型不一样的时候，对于不压缩方式，例如： 依然要满足不含位域结构体内存对齐准则第2条，i成员相对于结构体首地址的偏移应该是4的整数倍，所以c成员后要填充3个字节，然后再开辟4个字节的空间作为int型，其中4位用来存放i，所以上面结构体在VC中所占空间为8个字节；而对于采用压缩方式的编译器来说，遵循不含位域结构体内存对齐准则第2条，不同的是，如果填充的3个字节能容纳后面成员的位，则压缩到填充字节中，不能容纳，则要单独开辟空间，所以上面结构体N在GCC或者Dev-C++中所占空间应该是4个字节。 4) 如果位域字段之间穿插着非位域字段，则不进行压缩； 备注： 结构体 在GCC下占据的空间为16字节，在VC下占据的空间应该是24个字节。 5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。 ps: 对齐模数的选择只能是根据基本数据类型，所以对于结构体中嵌套结构体，只能考虑其拆分的基本数据类型。而对于对齐准则中的第2条，确是要将整个结构体看成是一个成员，成员大小按照该结构体根据对齐准则判断所得的大小。 类对象在内存中存放的方式和结构体类似，这里就不再说明。需要指出的是，类对象的大小只是包括类中非静态成员变量所占的空间，如果有虚函数，那么再另外增加一个指针所占的空间即可。 from：http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html (二) 在ARM 下要使结构体按指定字节对齐，可行的方法有两种： [...]]]></description>
			<content:encoded><![CDATA[<p>（一）</p>
<p>有的时候，在脑海中停顿了很久的“显而易见”的东西，其实根本上就是错误的。就拿下面的问题来看：</p>
<pre class="brush: cpp; title: ; notranslate">

struct T
{
char ch;
int i ;
};</pre>
<p>使用sizeof(T)，将得到什么样的答案呢？要是以前，想都不用想，在32位机中，int是4个字节，char是1个字节，所以T一共是5个字节。实践出真知，在VC6中测试了下，答案确实8个字节。哎，反正受伤的总是我，我已经有点麻木了，还是老老实实的接受吧！为什么答案和自己想象的有出入呢？这里将引入内存对齐这个概念。<span id="more-69362"></span></p>
<p>许多实际的计算机系统对基本类型数据在内存中存放的位置有限制，它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数，这就是所谓的内存对齐，而这个k则被称为该数据类型的对齐模数(alignment modulus)。当一种类型S的对齐模数与另一种类型T的对齐模数的比值是大于1的整数，我们就称类型S的对齐要求比T强(严格)，而称T比S弱(宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计，二来可以提升读取数据的速度。比如这么一种处理器，它每次读写内存的时候都从某个8倍数的地址开始，一次读出或写入8个字节的数据，假如软件能保证double类型的数据都从8倍数地址开始，那么读或写一个double类型数据就只需要一次内存操作。否则，我们就可能需要两次内存操作才能完成这个动作，因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。某些处理器在数据不满足对齐要求的情况下可能会出错，但是Intel的IA32架构的处理器则不管数据是否对齐都能正确工作。不过Intel奉劝大家，如果想提升性能，那么所有的程序数据都应该尽可能地对齐。</p>
<p>ANSI C标准中并没有规定，相邻声明的变量在内存中一定要相邻。为了程序的高效性，内存对齐问题由编译器自行灵活处理，这样导致相邻的变量之间可能会有一些填充字节。对于基本数据类型(int char)，他们占用的内存空间在一个确定硬件系统下有个确定的值，所以，接下来我们只是考虑结构体成员内存分配情况。</p>
<p>Win32平台下的微软C编译器(cl.exe for 80×86)的对齐策略：</p>
<p><span style="color: #ff0000;">1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除；</span></p>
<p><em>备注：编译器在给结构体开辟空间时，首先找到结构体中最宽的基本数据类型，然后寻找内存地址能被该基本数据类型所整除的位置，作为结构体的首地址。将这个最宽的基本数据类型的大小作为上面介绍的对齐模数。</em></p>
<p><span style="color: #ff0000;">2) 结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字节（internal adding）；</span></p>
<p><em>备注:为结构体的一个成员开辟空间之前，编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍，若是，则存放本成员，反之，则在本成员和上一个成员之间填充一定的字节，以达到整数倍的要求，也就是将预开辟空间的首地址后移几个字节。</em></p>
<p><span style="color: #ff0000;">3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍，如有需要，编译器会在最末一个成员之后加上填充字节（trailing padding）。</span></p>
<p><em>备注：结构体总大小是包括填充字节，最后一个成员满足上面两条以外，还必须满足第三条，否则就必须在最后填充几个字节以达到本条要求。<br />
</em><br />
根据以上准则，在windows下，使用VC编译器，sizeof(T)的大小为<span style="color: #ff0000;">1(char) + 3(填充) + 4(int) =8</span>个字节。</p>
<p>而在GNU GCC编译器中，遵循的准则有些区别，对齐模数不是像上面所述的那样，根据最宽的基本数据类型来定。在GCC中，对齐模数的准则是：对齐模数最大只能是4，也就是说，即使结构体中有double类型，对齐模数还是4，所以对齐模数只能是1，2，4。而且在上述的三条中，第2条里，offset必须是成员大小的整数倍，如果这个成员大小小于等于4则按照上述准则进行，但是如果大于4了，则结构体每个成员相对于结构体首地址的偏移量（offset）只能按照是4的整数倍来进行判断是否添加填充。</p>
<p>看如下例子：</p>
<pre class="brush: cpp; title: ; notranslate">struct T
{
char ch;
double d ;
};</pre>
<p>那么在GCC下，sizeof(T)应该等于12个字节。</p>
<p>如果结构体中含有位域(bit-field)，那么VC中准则又要有所更改：</p>
<p>1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止；</p>
<p>2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍；</p>
<p>3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式（不同位域字段存放在不同的位域类型字节中），Dev-C++和GCC都采取压缩方式；</p>
<p><em>备注：当两字段类型不一样的时候，对于不压缩方式，例如：</em></p>
<pre class="brush: cpp; title: ; notranslate">struct N
{
char c:2;
int i:4;
};</pre>
<p>依然要满足不含位域结构体内存对齐准则第2条，i成员相对于结构体首地址的偏移应该是4的整数倍，所以c成员后要填充3个字节，然后再开辟4个字节的空间作为int型，其中4位用来存放i，所以上面结构体在VC中所占空间为8个字节；而对于采用压缩方式的编译器来说，遵循不含位域结构体内存对齐准则第2条，不同的是，如果填充的3个字节能容纳后面成员的位，则压缩到填充字节中，不能容纳，则要单独开辟空间，所以上面结构体N在GCC或者Dev-C++中所占空间应该是4个字节。</p>
<p><span style="color: #ff0000;">4) 如果位域字段之间穿插着非位域字段，则不进行压缩；</span></p>
<p><em>备注：</em></p>
<p><em>结构体</em></p>
<pre class="brush: cpp; title: ; notranslate">typedef struct
{
char c:2;
double i;
int c2:4;
}N3;</pre>
<p>在GCC下占据的空间为16字节，在VC下占据的空间应该是24个字节。</p>
<p><span style="color: #ff0000;">5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。</span></p>
<p><strong>ps:</strong></p>
<p>对齐模数的选择只能是根据基本数据类型，所以对于结构体中嵌套结构体，只能考虑其拆分的基本数据类型。而对于对齐准则中的第2条，确是要将整个结构体看成是一个成员，成员大小按照该结构体根据对齐准则判断所得的大小。</p>
<p>类对象在内存中存放的方式和结构体类似，这里就不再说明。需要指出的是，类对象的大小只是包括类中非静态成员变量所占的空间，如果有虚函数，那么再另外增加一个指针所占的空间即可。</p>
<p>from：<a href="http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html">http://www.ksarea.com/articles/20071004_sizeof-struct-memory.html</a></p>
<p>(二)</p>
<p>在ARM 下要使结构体按指定字节对齐，可行的方法有两种：</p>
<p>1.在makefile里增加<span style="color: #ff0000;">-fpack-struct</span>选项，这样的话对所有的结构按一字节对齐。</p>
<p>不得不说，确实有那么些质量较差的程序可能需要你部分自然对齐，部分一字节对齐，此时</p>
<p>2. typedef struct pack{<br />
}__attribute__((packed))</p>
<p>可利用__attribute__属性</p>
<p>当然最后的方式，还是自己去看ARM体系结构与gcc编译选项了。
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2009/03/sizeof-structure-memory-alignment/">【转贴】sizeof(结构体)和内存对齐</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2009/03/sizeof-structure-memory-alignment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C语言声明之const</title>
		<link>http://www.xiangmocheng.com/2008/12/c-language-declaration-const/</link>
		<comments>http://www.xiangmocheng.com/2008/12/c-language-declaration-const/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 07:21:20 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[const]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/c%e8%af%ad%e8%a8%80%e5%a3%b0%e6%98%8e%e4%b9%8bconst.html</guid>
		<description><![CDATA[关键字const 用法： 1．可以定义 const 常量 2．const可以修饰函数的参数、返回值，甚至函数的定义体。被const修饰的东西都受到强制保护，可以预防意外的变动，能提高程序的健壮性。 const意味着”只读”。区别如下代码的功能非常重要。 前两个作用是一样的，a是一个常整型数。 第三个意味着a是一个指向常整型数的指针（也就是，整型数是不可修改的，但指针可以）。 第四个意思是a是一个指向整型数的常指针（也就是，指针指向的整型数是可以修改的，但指针是不可修改的）。 最后一个意味着a是一个指向常整型数的常指针（也就是，指针指向的整型数是不可修改的，同时指针也是不可修改的）。 关键字const的作用是为给读你代码的人传达非常有用的信息。例如，在函数的形参前添加const关键字意味着这个参数在函数体内不会被修改，属于”输入参数”。在有多个形参的时候，函数的调用者可以凭借参数前是否有const关键字，清晰的辨别哪些是输入参数，哪些是可能的输出参数。 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数，防止其被无意的代码修改，这样可以减少bug的出现。 const在C++语言中则包含了更丰富的含义，而在C语言中仅意味着：”只能读的普通变量”，可以称其为”不能改变的变量”（这个说法似乎很拗口，但却最准确的表达了C语言中const的本质），在编译阶段需要的常数仍然只能以#define宏定义！故在C语言中如下程序是非法的： 以下是工作中的使用const例子： 转载请注明： 转载自不然你要我怎么样 本文链接地址: C语言声明之const]]></description>
			<content:encoded><![CDATA[<p>关键字const</p>
<p>用法：</p>
<p>1．可以定义 const 常量</p>
<p>2．const可以修饰函数的参数、返回值，甚至函数的定义体。被const修饰的东西都受到强制保护，可以预防意外的变动，能提高程序的健壮性。</p>
<p>const意味着”只读”。区别如下代码的功能非常重要。</p>
<pre class="brush: cpp; title: ; notranslate">const int a;
int const a;
const int *a;
int * const a;
int const * a const;</pre>
<p>前两个作用是一样的，a是一个常整型数。</p>
<p>第三个意味着a是一个指向常整型数的指针（也就是，整型数是不可修改的，但指针可以）。</p>
<p>第四个意思是a是一个指向整型数的常指针（也就是，指针指向的整型数是可以修改的，但指针是不可修改的）。</p>
<p>最后一个意味着a是一个指向常整型数的常指针（也就是，指针指向的整型数是不可修改的，同时指针也是不可修改的）。</p>
<p>关键字const的作用是为给读你代码的人传达非常有用的信息。例如，在函数的形参前添加const关键字意味着这个参数在函数体内不会被修改，属于”输入参数”。在有多个形参的时候，函数的调用者可以凭借参数前是否有const关键字，清晰的辨别哪些是输入参数，哪些是可能的输出参数。</p>
<p>合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数，防止其被无意的代码修改，这样可以减少bug的出现。</p>
<p>const在C++语言中则包含了更丰富的含义，而在C语言中仅意味着：”只能读的普通变量”，可以称其为”不能改变的变量”（这个说法似乎很拗口，但却最准确的表达了C语言中const的本质），在编译阶段需要的常数仍然只能以#define宏定义！故在C语言中如下程序是非法的：</p>
<pre class="brush: cpp; title: ; notranslate">const int SIZE = 10;
char a[SIZE]; /* 非法：编译阶段不能用到变量 */</pre>
<p>以下是工作中的使用const例子：</p>
<pre class="brush: cpp; title: ; notranslate">const unsigned char * pbyData;
unsigned char const DayPerMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } ;
extern void dp_write_dsp_block ( const word *bp, word len );
const unsigned short InterMapSparseIdx[];</pre>
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2008/12/c-language-declaration-const/">C语言声明之const</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2008/12/c-language-declaration-const/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C语言声明之static</title>
		<link>http://www.xiangmocheng.com/2008/12/c-language-declaration-of-the-static/</link>
		<comments>http://www.xiangmocheng.com/2008/12/c-language-declaration-of-the-static/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 04:12:44 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[static]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/c%e8%af%ad%e8%a8%80%e5%a3%b0%e6%98%8e%e4%b9%8bstatic.html</guid>
		<description><![CDATA[<p>手边有书，心中无书。实在是厌烦了去查书，so，好好总结下。</p>
<p>---------------------------------------------------------------</p>
<p><strong>关键字static：</strong></p>
<p>关键字static是一个存储类说明符，同extern，typedef一样，因此他们不能同时使用。</p>
<p>定义：说明符static将声明的对象说明为静态存储类</p>
<p>在C语言中，关键字static有三个明显的作用：</p>
<p>1．static用于声明内部变量</p>
<p>在函数体内，一个被声明为static的变量在这一函数被调用过程中仅分配一次内存，且函数结束后其不会被销毁。</p>
<p>e.g.：</p>
<div class="source" style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New'; color: #000000; "> <span style="color: #008080; ">#include&#60;stdio.h&#62;</span><br /> <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">TestStatic</span>()<br /> <span style="color: #000000; ">{</span><br /> &#160;&#160;&#160; <span style="color: #000080; font-weight: bold; ">static</span> <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">x</span><span style="color: #000000; ">=</span><span style="color: #0000ff; ">1</span>;<br /> &#160;&#160;&#160; <span style="color: #000000; ">x</span><span style="color: #000000; ">++</span>;<br /> &#160;&#160;&#160; <span style="color: #000080; font-weight: bold; ">return</span> <span style="color: #000000; ">x</span>;<br /> <span style="color: #000000; ">}</span><br /> <span style="color: #000080; font-weight: bold; ">void</span> <span style="color: #000000; ">main</span>()<br /> <span style="color: #000000; ">{</span><br /> &#160;&#160;&#160; <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">i</span>;<br /> &#160;&#160;&#160; <span style="color: #000080; font-weight: bold; ">for</span>(<span style="color: #000000; ">i</span><span style="color: #000000; ">=</span><span style="color: #0000ff; ">0</span>;<span style="color: #000000; ">i</span><span style="color: #000000; ">&#60;</span><span style="color: #0000ff; ">5</span>;<span style="color: #000000; ">i</span><span style="color: #000000; ">++</span>)<br /> &#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: #000000; ">printf</span>(<span style="color: #0000ff; ">"%d</span><span style="color: #0000ff; ">\n</span><span style="color: #0000ff; ">"</span><span style="color: #000000; ">,</span> <span style="color: #000000; ">TestStatic</span>());<br /> <span style="color: #000000; ">}</span><br /></div>
<p>输出为：<br />2<br />3<br />4<br />5<br />6</p>
<p>2．static用于声明外部变量</p>
<p>在模块内（但在函数体外），一个被声明为static的变量可以被模块内所有函数访问，但不能被模块外其它函数访问。它是一个本地的全局变量（最常见的用法）。</p>
<p>3．static用于声明函数</p>
<p>在模块内，一个被声明为static的函数只可被这一模块内的其它函数调用。那就是，这个函数被限制在声明它的模块的本地范围内使用。</p>]]></description>
			<content:encoded><![CDATA[<p>手边有书，心中无书。实在是厌烦了去查书，so，好好总结下。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p><strong>关键字static：</strong></p>
<p>关键字static是一个存储类说明符，同extern，typedef一样，因此他们不能同时使用。</p>
<p>定义：说明符static将声明的对象说明为静态存储类</p>
<p>在C语言中，关键字static有三个明显的作用：</p>
<p>1．static用于声明内部变量</p>
<p>在函数体内，一个被声明为static的变量在这一函数被调用过程中仅分配一次内存，且函数结束后其不会被销毁。</p>
<p>e.g.：</p>
<div class="source" style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New'; color: #000000; "> <span style="color: #008080; ">#include&lt;stdio.h&gt;</span><br /> <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">TestStatic</span>()<br /> <span style="color: #000000; ">{</span><br /> &nbsp;&nbsp;&nbsp; <span style="color: #000080; font-weight: bold; ">static</span> <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">x</span><span style="color: #000000; ">=</span><span style="color: #0000ff; ">1</span>;<br /> &nbsp;&nbsp;&nbsp; <span style="color: #000000; ">x</span><span style="color: #000000; ">++</span>;<br /> &nbsp;&nbsp;&nbsp; <span style="color: #000080; font-weight: bold; ">return</span> <span style="color: #000000; ">x</span>;<br /> <span style="color: #000000; ">}</span><br /> <span style="color: #000080; font-weight: bold; ">void</span> <span style="color: #000000; ">main</span>()<br /> <span style="color: #000000; ">{</span><br /> &nbsp;&nbsp;&nbsp; <span style="color: #000080; font-weight: bold; ">int</span> <span style="color: #000000; ">i</span>;<br /> &nbsp;&nbsp;&nbsp; <span style="color: #000080; font-weight: bold; ">for</span>(<span style="color: #000000; ">i</span><span style="color: #000000; ">=</span><span style="color: #0000ff; ">0</span>;<span style="color: #000000; ">i</span><span style="color: #000000; ">&lt;</span><span style="color: #0000ff; ">5</span>;<span style="color: #000000; ">i</span><span style="color: #000000; ">++</span>)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000; ">printf</span>(<span style="color: #0000ff; ">“%d</span><span style="color: #0000ff; ">\n</span><span style="color: #0000ff; ">“</span><span style="color: #000000; ">,</span> <span style="color: #000000; ">TestStatic</span>());<br /> <span style="color: #000000; ">}</span></div>
<p>输出为：<br />2<br />3<br />4<br />5<br />6</p>
<p>2．static用于声明外部变量</p>
<p>在模块内（但在函数体外），一个被声明为static的变量可以被模块内所有函数访问，但不能被模块外其它函数访问。它是一个本地的全局变量（最常见的用法）。</p>
<p>3．static用于声明函数</p>
<p>在模块内，一个被声明为static的函数只可被这一模块内的其它函数调用。那就是，这个函数被限制在声明它的模块的本地范围内使用。</p>
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2008/12/c-language-declaration-of-the-static/">C语言声明之static</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2008/12/c-language-declaration-of-the-static/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C语言声明之typedef &amp; struct</title>
		<link>http://www.xiangmocheng.com/2008/10/c-language-declaration-typedef-and-struct/</link>
		<comments>http://www.xiangmocheng.com/2008/10/c-language-declaration-typedef-and-struct/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 07:20:00 +0000</pubDate>
		<dc:creator>xiangmocheng</dc:creator>
				<category><![CDATA[Embedded]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[struct]]></category>
		<category><![CDATA[typedef]]></category>

		<guid isPermaLink="false">http://xiangmocheng.yo2.cn/articles/c%e8%af%ad%e8%a8%80%e5%a3%b0%e6%98%8e%e4%b9%8btypedef-amp-struct.html</guid>
		<description><![CDATA[<p>例子：</p>
<p><span style="FONT-FAMILY: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; COLOR: #000000"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span> <span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span> <span style="COLOR: #000000">tagNode</span> <br /><span style="COLOR: #000000">{</span><br /><span style="COLOR: #000080; FONT-WEIGHT: bold">char</span> <span style="COLOR: #000000">*</span><span style="COLOR: #000000">pItem</span>;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span> <span style="COLOR: #000000">tagNode</span> <span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNext</span>;<br /><span style="COLOR: #000000">}</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNode</span>;<br /></span></p>
<p>正文：</p>
<p>1. 基本解释</p>
<p>　　typedef为C语言的关键字，作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型（int,char等）和自定义的数据类型（struct等）。</p>
<p>　　在编程中使用typedef目的一般有两个，一个是给变量一个易记且意义明确的新名字，另一个是简化一些比较复杂的类型声明。</p>
<p>　　至于typedef有什么微妙之处，请你接着看下面对几个问题的具体阐述。</p>
<p>2. typedef 结构的问题</p>
<p>　　当用下面的代码定义一个结构时，编译器报了一个错误，为什么呢？莫非C语言不允许在结构中包含指向它自己的指针吗？请你先猜想一下，然后看下文说明：</p>
<p><span style="FONT-FAMILY: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; COLOR: #000000"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span> <span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span> <span style="COLOR: #000000">tagNode</span> <br /><span style="COLOR: #000000">{</span><br /><span style="COLOR: #000080; FONT-WEIGHT: bold">char</span> <span style="COLOR: #000000">*</span><span style="COLOR: #000000">pItem</span>;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span> <span style="COLOR: #000000">tagNode</span> <span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNext</span>;<br /><span style="COLOR: #000000">}</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNode</span>;<br /></span></p>
<p>答案与分析：</p>
<p>1、typedef的最简单使用</p>
<p><span style="FONT-FAMILY: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; COLOR: #000000"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span> <span style="COLOR: #000080; FONT-WEIGHT: bold">long</span> <span style="COLOR: #000000">byte_4</span>;<br /></span></p>
<p>给已知数据类型long起个新名字，叫byte_4。</p>
<p>2、 typedef与结构结合使用</p>
<p><span style="FONT-FAMILY: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; COLOR: #000000"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span> <span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span> <span style="COLOR: #000000">tagMyStruct</span><br /><span style="COLOR: #000000">{</span> <br /><span style="COLOR: #000080; FONT-WEIGHT: bold">int</span> <span style="COLOR: #000000">iNum</span>;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">long</span> <span style="COLOR: #000000">lLength</span>;<br /><span style="COLOR: #000000">}</span> <span style="COLOR: #000000">MyStruct</span>;</span></p>
<p>这语句实际上完成两个操作：</p>
<p>1) 定义一个新的结构类型</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New'; "><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span>&#160;<span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagMyStruct</span><br /><span style="COLOR: #000000">{</span>&#160;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">int</span>&#160;<span style="COLOR: #000000">iNum</span>;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">long</span>&#160;<span style="COLOR: #000000">lLength</span>;<br /><span style="COLOR: #000000">}</span>;</span></p>
<p>分析：tagMyStruct称为&#8220;tag&#8221;，即&#8220;标签&#8221;，实际上是一个临时名字，struct 关键字和tagMyStruct一起，构成了这个结构类型，不论是否有typedef，这个结构都存在。</p>
<p>我们可以用struct tagMyStruct varName来定义变量，但要注意，使用tagMyStruct varName来定义变量是不对的，因为struct 和tagMyStruct合在一起才能表示一个结构类型。</p>
<p>2) typedef为这个新的结构起了一个名字，叫MyStruct。</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span>&#160;<span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;tagMyStruct MyStruct;</span></p>
<p>因此，MyStruct实际上相当于struct tagMyStruct，我们可以使用MyStruct varName来定义变量。</p>
<p>答案与分析</p>
<p>C语言当然允许在结构中包含指向它自己的指针，我们可以在建立链表等数据结构的实现上看到无数这样的例子，上述代码的根本问题在于typedef的应用。</p>
<p>根据我们上面的阐述可以知道：新结构建立的过程中遇到了pNext域的声明，类型是pNode，要知道pNode表示的是类型的新名字，那么在类型本身还没有建立完成的时候，这个类型的新名字也还不存在，也就是说这个时候编译器根本不认识pNode。</p>
<p>解决这个问题的方法有多种：</p>
<p>1)、</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span>&#160;<span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagNode</span>&#160;<br /><span style="COLOR: #000000">{</span><br /><span style="COLOR: #000080; FONT-WEIGHT: bold">char</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pItem</span>;<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagNode</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNext</span>;<br /><span style="COLOR: #000000">}</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNode</span>;</span></p>
<p>2)、</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span>&#160;<span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagNode</span>&#160;*pNode<br /><span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagNode</span>&#160;<br /><span style="COLOR: #000000">{</span><br /><span style="COLOR: #000080; FONT-WEIGHT: bold">char</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pItem</span>;<br /><span style="COLOR: #000000">pNode</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNext</span>;<br /><span style="COLOR: #000000">}</span>;</span></p>
<p>注意：在这个例子中，你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。</p>
<p>3)、规范做法：</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;<span style="COLOR: #000000">tagNode</span>&#160;<br /><span style="COLOR: #000000">{</span><br /><span style="COLOR: #000080; FONT-WEIGHT: bold">char</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pItem</span>;<br /><span style="COLOR: #000000">pNode</span>&#160;<span style="COLOR: #000000">*</span><span style="COLOR: #000000">pNext</span>;<br /><span style="COLOR: #000000">}</span>;</span><br /><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="COLOR: #000080; FONT-WEIGHT: bold">typedef</span>&#160;<span style="COLOR: #000080; FONT-WEIGHT: bold">struct</span>&#160;tagNode *pNode;</span></p>
<p>文章出处：<a href="http://www.diybl.com/course/3_program/c++/cppjs/2008828/138362.html">http://www.diybl.com/course/3_program/c++/cppjs/2008828/138362.html</a></p>]]></description>
			<content:encoded><![CDATA[<p>例子：</p>
<p><span style="font-family: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; color: #000000;"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">char</span> <span style="color: #000000;">*</span><span style="color: #000000;">pItem</span>;<br />
<span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span> <span style="color: #000000;">*</span><span style="color: #000000;">pNext</span>;<br />
<span style="color: #000000;">}</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode</span>;<br />
</span></p>
<p>正文：</p>
<p>1. 基本解释</p>
<p>typedef为C语言的关键字，作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型（int,char等）和自定义的数据类型（struct等）。</p>
<p>在编程中使用typedef目的一般有两个，一个是给变量一个易记且意义明确的新名字，另一个是简化一些比较复杂的类型声明。</p>
<p>至于typedef有什么微妙之处，请你接着看下面对几个问题的具体阐述。</p>
<p>2. typedef 结构的问题</p>
<p>当用下面的代码定义一个结构时，编译器报了一个错误，为什么呢？莫非C语言不允许在结构中包含指向它自己的指针吗？请你先猜想一下，然后看下文说明：</p>
<p><span style="font-family: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; color: #000000;"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">char</span> <span style="color: #000000;">*</span><span style="color: #000000;">pItem</span>;<br />
<span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span> <span style="color: #000000;">*</span><span style="color: #000000;">pNext</span>;<br />
<span style="color: #000000;">}</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode</span>;<br />
</span></p>
<p>答案与分析：</p>
<p>1、typedef的最简单使用</p>
<p><span style="font-family: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; color: #000000;"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">long</span> <span style="color: #000000;">byte_4</span>;<br />
</span></p>
<p>给已知数据类型long起个新名字，叫byte_4。</p>
<p>2、 typedef与结构结合使用</p>
<p><span style="font-family: '[object HTMLOptionElement]', 'Consolas', 'Lucida Console', 'Courier New'; color: #000000;"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagMyStruct</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">int</span> <span style="color: #000000;">iNum</span>;<br />
<span style="color: #000080; font-weight: bold;">long</span> <span style="color: #000000;">lLength</span>;<br />
<span style="color: #000000;">}</span> <span style="color: #000000;">MyStruct</span>;</span></p>
<p>这语句实际上完成两个操作：</p>
<p>1) 定义一个新的结构类型</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagMyStruct</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">int</span> <span style="color: #000000;">iNum</span>;<br />
<span style="color: #000080; font-weight: bold;">long</span> <span style="color: #000000;">lLength</span>;<br />
<span style="color: #000000;">}</span>;</span></p>
<p>分析：tagMyStruct称为“tag”，即“标签”，实际上是一个临时名字，struct 关键字和tagMyStruct一起，构成了这个结构类型，不论是否有typedef，这个结构都存在。</p>
<p>我们可以用struct tagMyStruct varName来定义变量，但要注意，使用tagMyStruct varName来定义变量是不对的，因为struct 和tagMyStruct合在一起才能表示一个结构类型。</p>
<p>2) typedef为这个新的结构起了一个名字，叫MyStruct。</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> tagMyStruct MyStruct;</span></p>
<p>因此，MyStruct实际上相当于struct tagMyStruct，我们可以使用MyStruct varName来定义变量。</p>
<p>答案与分析</p>
<p>C语言当然允许在结构中包含指向它自己的指针，我们可以在建立链表等数据结构的实现上看到无数这样的例子，上述代码的根本问题在于typedef的应用。</p>
<p>根据我们上面的阐述可以知道：新结构建立的过程中遇到了pNext域的声明，类型是pNode，要知道pNode表示的是类型的新名字，那么在类型本身还没有建立完成的时候，这个类型的新名字也还不存在，也就是说这个时候编译器根本不认识pNode。</p>
<p>解决这个问题的方法有多种：</p>
<p>1)、</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">char</span> <span style="color: #000000;">*</span><span style="color: #000000;">pItem</span>;<br />
<span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span> <span style="color: #000000;">*</span><span style="color: #000000;">pNext</span>;<br />
<span style="color: #000000;">}</span><span style="color: #000000;">*</span><span style="color: #000000;">pNode</span>;</span></p>
<p>2)、</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span> *pNode<br />
<span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">char</span> <span style="color: #000000;">*</span><span style="color: #000000;">pItem</span>;<br />
<span style="color: #000000;">pNode</span> <span style="color: #000000;">*</span><span style="color: #000000;">pNext</span>;<br />
<span style="color: #000000;">}</span>;</span></p>
<p>注意：在这个例子中，你用typedef给一个还未完全声明的类型起新名字。C语言编译器支持这种做法。</p>
<p>3)、规范做法：</p>
<p><span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">struct</span> <span style="color: #000000;">tagNode</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000080; font-weight: bold;">char</span> <span style="color: #000000;">*</span><span style="color: #000000;">pItem</span>;<br />
<span style="color: #000000;">pNode</span> <span style="color: #000000;">*</span><span style="color: #000000;">pNext</span>;<br />
<span style="color: #000000;">}</span>;</span><br />
<span style="font-family: '[object HTMLOptionElement]', Consolas, 'Lucida Console', 'Courier New';"><span style="color: #000080; font-weight: bold;">typedef</span> <span style="color: #000080; font-weight: bold;">struct</span> tagNode *pNode;</span></p>
<p>文章出处：<a href="http://www.diybl.com/course/3_program/c++/cppjs/2008828/138362.html">http://www.diybl.com/course/3_program/c++/cppjs/2008828/138362.html</a>
<div style="margin-top: 10px">
<p><strong>转载请注明：</strong> 转载自<a href="http://www.xiangmocheng.com/">不然你要我怎么样</a></t>        </br><strong>本文链接地址:</strong> <a href="http://www.xiangmocheng.com/2008/10/c-language-declaration-typedef-and-struct/">C语言声明之typedef &#038; struct</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.xiangmocheng.com/2008/10/c-language-declaration-typedef-and-struct/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

