﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Oo缘来是你oO-随笔分类-经典 C++</title><link>http://www.blogjava.net/majianan/category/13114.html</link><description>&lt;br&gt;
&lt;div align=center &gt;
&lt;img width=200 height=50 src="http://www.blogjava.net/images/blogjava_net/majianan/14891/r_5858488902000cu2.gif" name="welcome"&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;script language="JavaScript"&gt;
&lt;!-- Begin
text = "人本是人，不必刻意去做人；世本是世，无须精心去处世；自然的才是快乐的。"; 
color1 = "blue"; 
color2 = "red"; fontsize = "2"; 
speed = 100; 
i = 0;
if (navigator.appName == "Netscape") {
document.write("&lt;layer id=a visibility=show&gt;&lt;/layer&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;");
}
else {
document.write("&lt;div id=a&gt;&lt;/div&gt;");
}
function changeCharColor() {
if (navigator.appName == "Netscape") {
document.a.document.write("&lt;center&gt;&lt;font face=arial size =" + fontsize + "&gt;&lt;font color=" + color1 + 
"&gt;");
for (var j = 0; j &lt; text.length; j++) {
if(j == i) {
document.a.document.write("&lt;font face=arial color=" + color2 + "&gt;" + Text.charAt(i) + "&lt;/font&gt;");
}
else {
document.a.document.write(text.charAt(j));
}
}
document.a.document.write('&lt;/font&gt;&lt;/font&gt;&lt;/center&gt;');
document.a.document.close();
}
if (navigator.appName == "Microsoft Internet Explorer") {
str = "&lt;center&gt;&lt;font face=arial size=" + fontsize + "&gt;&lt;font color=" + color1 + "&gt;";
for (var j = 0; j &lt; text.length; j++) {
if( j == i) {
str += "&lt;font face=arial color=" + color2 + "&gt;" + text.charAt(i) + "&lt;/font&gt;";
}
else {
str += text.charAt(j);
}
}
str += "&lt;/font&gt;&lt;/font&gt;&lt;/center&gt;";
a.innerHTML = str;
}
(i == text.length) ? i=0 : i++;
}
setInterval("changeCharColor()", speed);
// End --&gt;
&lt;/script&gt; 
</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 12:07:24 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 12:07:24 GMT</pubDate><ttl>60</ttl><item><title>[ 学习笔记 ] Effective C++ ：Item 1</title><link>http://www.blogjava.net/majianan/archive/2006/08/21/64761.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Mon, 21 Aug 2006 04:56:00 GMT</pubDate><guid>http://www.blogjava.net/majianan/archive/2006/08/21/64761.html</guid><wfw:comment>http://www.blogjava.net/majianan/comments/64761.html</wfw:comment><comments>http://www.blogjava.net/majianan/archive/2006/08/21/64761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/majianan/comments/commentRss/64761.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/majianan/services/trackbacks/64761.html</trackback:ping><description><![CDATA[
		<div>
				<strong>
						<font size="4">Item 1：View C++ as a federation of languages</font>
				</strong>
		</div>
		<div>
				<strong>
						<font size="4">
						</font>
				</strong> </div>
		<div>
				<strong>
						<font size="4">Item 1：将C++视为语言的联合体</font>
				</strong>
		</div>
		<div>
				<strong>
						<font size="4">
						</font>
				</strong> </div>
		<div>
				<font size="4">------------------- Chinese -------------------</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">最初，C++仅仅是在C的基础上附加了一些面向对象的特征。但是，随着C++的成长发展，C++已经成为了一个多范式的编程语言，一个囊括了过程化，面向对象，函数化，泛型以及元编程特性的联合体。可以将它分成4个部分： </font>
				<div> </div>
				<div>
						<font size="4">
								<strong>
										<font color="#0000ff">C</font>
								</strong> ------ 归根结底，C++依然是基于C的。模块，语句，预处理器，内建数据类型，数组，指针等，全都来自于C。只是在很多方面，C++提出了更高级的解决问题的方法。</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
								<font color="#0000ff">
										<strong>Object-Oriented C++</strong>
								</font> ------ C++的这部分就是C with Classes 涉及到的全部：类（包括构造函数和析构函数），封装，继承，多态，虚函数（动态邦定）等。C++的这一部分直接适用于面向对象设计的经典规则。</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
								<strong>
										<font color="#0000ff">Template C++</font>
								</strong> ------ 这是C++的泛型编程部分。</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
								<strong>
										<font color="#0000ff">STL</font>
								</strong> ------ STL是一个特殊的模板库。它将容器，迭代器，算法和函数对象优雅的整合在一起。</font>
				</div>
				<div>
						<font size="4">      </font>
				</div>
				<div>
						<font size="4">头脑中保持这四个子语言，从一种子语言转到另一种时，为了高效编程，需要改变策略：</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">      例如，适用内建（类C的）类型时，传值通常比传引用更高效，但是当从C++的C部分转到C++的Object-Oriented部分，用户自定义构造函数和析构函数意味着更好的做法是将引用传递给const参数。在 Template C++ 中工作时，这一点更加重要，因为，在这种情况下，你甚至不知道你的操作涉及到的对象的类型。当你进入 STL，无论如何，你知道迭代器和函数对象以 C 的指针为原型，对于 STL 中的迭代器和函数对象，古老的 C 中的传值规则又重新生效。</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font color="#0000ff" size="4">***********************************************************</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font color="#0000ff" size="4">
								<strong>Things to Remember：</strong>
						</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">      高效C++编程规则的变化，依赖于你使用C++的哪一个部分。</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<font size="4">------------------- English --------------------</font>
				</div>
				<div>
						<font size="4">
						</font> </div>
				<div>
						<div>
								<font size="4">In the beginning, C++ was just C with some object-oriented features tacked on. As the language matured, C++ have become a multiparadigm programming language, one suppoting a combination of procedural, object-oriented, functional, generic, and metaprogramming features. </font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">There are four parts in the C++:</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">
										<strong>
												<font color="#0000ff">C</font>
										</strong> ------ Way down deep, C++ is still based on C. Blocks, statements, the preprocessor, built-in data types, arrays, pointers,etc, all come from C. In many cases, C++ just offers approaches to problems that are superior to their C counterparts.</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">
										<strong>
												<font color="#0000ff">Object-Oriented C++</font>
										</strong> ------ This part of C++ is what C with Classes was all about: classes(including constructors and destructors), encapsulation, inheritance, polymorphism, virtual functions(dynamic binding),etc. This is the part of C++ to which the classic rules for object-oriented design most directly apply.</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">
										<strong>
												<font color="#0000ff">Template C++</font>
										</strong> ------ This is the generic programming part of C++.</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">
										<strong>
												<font color="#0000ff">The STL</font>
										</strong> ------ The STL si avery special template library. Its conventions regarding containers, iterators, algorithms, and function objects mesh beautifully.</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">Keep these four sublanguages in mind, and don't be surprised when you encounter situations where effective programming requires that you change strategy when you switch from one sublanguage to another. </font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">For example, pass-by-value is generally more efficient than pass-by-reference for built-in (i.e., C-like) types, but when you move from the C part of C++ to Object-Oriented C++, the existence of user-defined constructors and destructors means that pass-by-reference-to-const is usually better. This is especially the case when working in Template C++, because there, you don't even know the type of object you're dealing with. When you cross into the STL, however, you know that iterators and function objects are modeled on pointers in C, so for iterators and function objects in the STL, the old C pass-by-value rule applies again.  </font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font color="#0000ff" size="4">**********************************************************</font>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<strong>
										<font color="#0000ff" size="4">Things to Remember</font>
								</strong>
						</div>
						<div>
								<font size="4">
								</font> </div>
						<div>
								<font size="4">Rules for effective C++ programming vary, depending on the part of C++ you are using!</font>
						</div>
				</div>
		</div>
<img src ="http://www.blogjava.net/majianan/aggbug/64761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/majianan/" target="_blank">马嘉楠</a> 2006-08-21 12:56 <a href="http://www.blogjava.net/majianan/archive/2006/08/21/64761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> iostream 和 iostream.h 的区别</title><link>http://www.blogjava.net/majianan/archive/2006/08/21/64759.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Mon, 21 Aug 2006 04:50:00 GMT</pubDate><guid>http://www.blogjava.net/majianan/archive/2006/08/21/64759.html</guid><wfw:comment>http://www.blogjava.net/majianan/comments/64759.html</wfw:comment><comments>http://www.blogjava.net/majianan/archive/2006/08/21/64759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/majianan/comments/commentRss/64759.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/majianan/services/trackbacks/64759.html</trackback:ping><description><![CDATA[
		<div align="left">
				<font size="4">转自：</font>
				<a href="http://blog.sina.com.cn/m/majianan">
						<font size="4">http://blog.sina.com.cn/m/majianan</font>
				</a>
				<font size="4">(我的新浪Blog)<br />前一段时间在自学C++，现在工作了用Java，不过以前写的一些文章自我感觉还不错，哈哈，就转来这里，大家多提意见。<br />蛮喜欢这个Blog。<br /><br /><br />                                         <font color="#0000ff"> &lt; iostream &gt; 和 &lt; iostream.h &gt; 的区别</font><br /><br />关键词：&lt; iostream &gt; 和 &lt; iostream.h &gt;</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">你写程序的时候，用&lt; iostream &gt;还是&lt; iostream.h &gt;？</font>
		</div>
		<div>
				<font size="4">你知道它们有什么区别么？还是认为他们根本就是一样的？</font>
		</div>
		<div>
				<font size="4">下面听我给你吹（文中纯属个人言论，不涉及国家机密，请放心阅读，若转载请注明出处作者^-^）</font>
		</div>
		<div>
				<font size="4">                              ---majianan</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">其实没有&lt; iostream.h &gt;这样的东西 --- 标准化委员会在简化非C标准头文件时用&lt; iostream &gt; 取代了它。但又没有完全取消&lt; iostream.h &gt;的使用，并且很多编译器都同时支持&lt; iostream &gt;和&lt; iostream.h &gt;，造成现在的局面，老大（标准化委员会）确实有不得已的苦衷。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">话说当年，在标准化委员会动手重建新的标准库的时候，遇到了问题。为了避免类名函数名的冲突问题，引入了名字空间std，但无数现有的C++代码都依赖于使用了多年的伪标准库中的功能，例如，声明在&lt; iostream.h &gt;和&lt; complex.h &gt;等头文件中的功能。现有软件没有针对使用名字空间而进行相应的设计或者升级，如果用std来包装标准库导致现有代码不能使用，那手底下的小弟（程序员）是不会同意的。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">标准化委员会为了拉拢人心，吸引更多的人入会，决定为包装了std的那部分标准库构建新的头文件名。将现有C++头文件名中的.h去掉，所以就出现了&lt; iostream.h&gt;和&lt; iostream &gt;等很多双胞胎。对于C头文件，采用同样方法但在每个名字前还要添加一个C，所以C的&lt;string.h&gt;变成了&lt;cstring&gt;。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">旧的C++头文件是官方明确反对使用的，但旧的C头文件则没有（以保持对C的兼容性）。其实编译器制造商不会停止对客户现有软件提供支持，所以在可以预计的将来，旧的C++头文件还会嚣张一段时间。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">如果能明白字符串头文件的使用，举一反三，其他的也差不多会用了。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">&lt;string.h&gt;是旧的C头文件，对应的是基于char*的字符串处理函数；</font>
		</div>
		<div>
				<font size="4">&lt;string&gt;是包装了std的C++头文件，对应的是新的strng类；</font>
		</div>
		<div>
				<font size="4">&lt;cstring&gt;是对应旧的C头文件的std版本。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">好像跑远了，言归正传。如果你的编译器都同时支持&lt; iostream &gt;和&lt; iostream.h &gt;，那使用#include &lt; iostream &gt;，得到的是置于名字空间std下的iostream库的元素；如果使用#include &lt; iostream.h &gt;，得到的是置于全局空间的同样的元素。在全局空间获取元素会导致名字冲突，而设计名字空间的初衷正是用来避免这种名字冲突的发生。还有，打字时&lt; iostream &gt;比&lt; iostream.h &gt;少两个字，所以我会使用&lt; iostream &gt; ^-^</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">困了，睡了。</font>
		</div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">
				</font> </div>
		<div>
				<font size="4">                                      马嘉楠</font>
		</div>
		<div>
				<font size="4">                                  2005-12-26 午夜</font>
		</div>
<img src ="http://www.blogjava.net/majianan/aggbug/64759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/majianan/" target="_blank">马嘉楠</a> 2006-08-21 12:50 <a href="http://www.blogjava.net/majianan/archive/2006/08/21/64759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 sizeof() 的一些思考</title><link>http://www.blogjava.net/majianan/archive/2006/08/20/64664.html</link><dc:creator>马嘉楠</dc:creator><author>马嘉楠</author><pubDate>Sun, 20 Aug 2006 13:59:00 GMT</pubDate><guid>http://www.blogjava.net/majianan/archive/2006/08/20/64664.html</guid><wfw:comment>http://www.blogjava.net/majianan/comments/64664.html</wfw:comment><comments>http://www.blogjava.net/majianan/archive/2006/08/20/64664.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/majianan/comments/commentRss/64664.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/majianan/services/trackbacks/64664.html</trackback:ping><description><![CDATA[
		<div>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#000000">
												<font color="#0000ff" size="3">                                        关于 sizeof() 的一些思考</font>
												<br />
												<br />
												<br />关键词：sizeof</font>
								</font>
						</font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#000000">这是网上的一个帖子，最初来自那里已经记不得了，不过我觉得很不错。</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">我对原文做了一些修改，并添加了一些内容。如果有什么错误的地方，请大家指正，谢谢~~ </font>
				</p>
				<p>
						<font face="Verdana" size="2">                       --- majianan 2005-12-19 </font>
				</p>
				<p>
						<strong>
								<font face="Verdana" color="#0000ff" size="2">
								</font>
						</strong> </p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">0.关键字</font>
										</strong>：sizeof，字节对齐，类型大小 </font>
						</font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">前向声明：</font>
										</strong>
										<br />    sizeof，一个其貌不扬的家伙，引无数菜鸟竟折腰. </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">    小虾我当初也没少犯迷糊，秉着“辛苦我一个，幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">    但当我总结的时候才发现，这个问题既可以简单，又可以复杂。所以本文有的地方并不适合初学者，甚至都没有必要大作文章。但如果你想“知其然，更知其所以然”的话，那么这篇文章对你或许有所帮助。<br />    </font>
				</p>
				<p>
						<font face="Verdana" size="2">    菜鸟我对C++的掌握尚未深入，其中不乏错误，欢迎各位指正啊 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">1. 定义：<br /></font>
										</strong>    sizeof是何方神圣？ </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">    sizeof 乃 C/C++ 中的一个操作符（operator）是也。简单说其作用就是返回一个对象或者类型所占的内存字节数。<br /><br />MSDN上的解释为： </font>
				</p>
				<p>
						<font face="Verdana" size="2">The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types).This keyword returns a value of type size_t. </font>
				</p>
				<p>
						<font face="Verdana" size="2">    其返回值类型为size_t，在头文件stddef.h中定义。这是一个依赖于编译系统的值，一般定义为 </font>
				</p>
				<p>
						<font face="Verdana" size="2">typedef unsigned int size_t; </font>
				</p>
				<p>
						<font face="Verdana" size="2">    世上编译器林林总总，但作为一个规范，它们都会保证char、signed char和unsigned char的sizeof值为1，毕竟char是我们编程能用的最小数据类型。<br /><br /><strong><font color="#0000ff">2. 语法：</font></strong><br />    sizeof有三种语法形式，如下：<br />    1) sizeof( object );    // sizeof( 对象 );<br />    2) sizeof( type_name ); // sizeof( 类型 );<br />    3) sizeof object;       // sizeof 对象; </font>
				</p>
				<p>
						<font face="Verdana" size="2">所以，<br />int i;<br />sizeof( i );     // ok<br />sizeof i;        // ok<br />sizeof( int );   // ok<br />sizeof int;      // error </font>
				</p>
				<p>
						<font face="Verdana" size="2">既然写法2可以用写法1代替，为求形式统一以及减少我们大脑的负担，第2种写法，忘掉它吧！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">实际上，sizeof计算对象的大小也是转换成对对象类型的计算。也就是说，同种类型的不同对象其sizeof值都是一致的。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里，对象可以进一步延伸至表达式，即sizeof可以对一个表达式求值。编译器<strong>根据表达式的最终结果类型来确定大小</strong>，一般不会对表达式进行计算。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">例如： </font>
				</p>
				<p>
						<font face="Verdana" size="2">sizeof( 2 );        // 2的类型为int，所以等价于 sizeof( int );<br />sizeof( 2 + 3.14 ); // 3.14的类型为double，2也会被提升成double类型，所以等价于 sizeof( double );<br /><br />    sizeof也可以对一个函数调用求值，其<font color="#0000ff">结果是函数返回类型的大小，函数并不会被调用。</font>我们来看一个完整的例子： </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char foo()<br />{<br />    printf("foo() has been called.\n");<br />    return 'a';<br />}<br />int main()<br />{<br />    size_t sz = sizeof( foo() );   // foo() 的返回值类型为char，所以sz = sizeof(char)，但函数foo()并不会被调用<br />    printf("sizeof( foo() ) = %d\n", sz);<br />} </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">C99标准规定，函数、不能确定类型的表达式以及位域（bit-field）成员不能被计算sizeof值，即下面这些写法都是错误的： </font>
				</p>
				<p>
						<font face="Verdana" size="2">    sizeof( foo );     // error<br />    void foo2() { }<br />    sizeof( foo2() );  // error<br />    struct S<br />    {<br />        unsigned int f1 : 1;<br />        unsigned int f2 : 5;<br />        unsigned int f3 : 12;<br />    };<br />    sizeof( S.f1 );   // error </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">3. sizeof的常量性</font>
										</font>
								</font>
						</strong>
				</p>
				<strong>
						<font color="#0000ff">
						</font>
				</strong>
				<p>
						<br />
						<font face="Verdana" size="2">    sizeof的计算发生在编译时刻，所以它可以被当作常量表达式使用。如： </font>
				</p>
				<p>
						<font face="Verdana" size="2">char ary[ sizeof( int ) * 10 ];   // ok </font>
				</p>
				<p>
						<font face="Verdana" size="2">最新的C99标准规定sizeof也可以在运行时刻进行计算。如下面的程序在Dev-C++中可以正确执行： </font>
				</p>
				<p>
						<font face="Verdana" size="2">int n;<br />n = 10;        // n动态赋值<br />char ary[n];   // C99也支持数组的动态定义<br />printf("%d\n", sizeof(ary)); // ok. 输出10 </font>
				</p>
				<p>
						<font face="Verdana" size="2">但在没有完全实现C99标准的编译器中就行不通了，上面的代码在VC6中就通不过编译。所以我们<font color="#0000ff">最好还是认为sizeof是在编译期执行的</font>，这样不会带来错误，让程序的可移植性强些。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">4. 基本数据类型的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font face="Verdana" size="2">这里的基本数据类型指short、int、long、float、double这样的简单内置数据类型。由于它们都是和系统相关的，所以在不同的系统下取值可能不同。这务必引起我们的注意，尽量不要在这方面给自己程序的移植造成麻烦。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">一般的，在32位编译环境中，sizeof(int)的取值为4。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">5. 指针变量的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font face="Verdana" size="2">学过数据结构的你应该知道指针是一个很重要的概念，它记录了另一个对象的地址。<font color="#0000ff">既然是来存放地址的，那么它当然等于计算机内部地址总线的宽度。</font>所以在32位计算机中，一个指针变量的返回值必定是4（注意结果是以字节为单位）。可以预计，在将来的64位系统中指针变量的sizeof结果为8。 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char* pc = "abc";<br />int* pi;<br />string* ps;<br />char** ppc = &amp;pc;<br />void (*pf)(); // 函数指针<br />sizeof( pc ); // 结果为4<br />sizeof( pi ); // 结果为4<br />sizeof( ps ); // 结果为4<br />sizeof( ppc );// 结果为4<br />sizeof( pf ); // 结果为4 </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">指针变量的sizeof值与指针所指的对象没有任何关系，正是由于所有的指针变量所占内存大小相等，所以MFC消息处理函数使用两个参数WPARAM、LPARAM就能传递各种复杂的消息结构（使用指向结构体的指针）。 </font>
				</p>
				<p>
						<br />
						<strong>
								<font size="2">
										<font face="Verdana">
												<font color="#0000ff">6. 数组的sizeof</font>
										</font>
								</font>
						</strong>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">数组的sizeof值等于数组所占用的内存字节数</font>，如： </font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">char a1[] = "abc";<br />int a2[3];<br />sizeof( a1 ); // 结果为4，字符 末尾还存在一个NULL终止符<br />sizeof( a2 ); // 结果为3*4=12（依赖于int） </font>
				</p>
				<p>
						<font face="Verdana" size="2">一些朋友刚开始时把sizeof当作了求数组元素的个数，现在，你应该知道这是不对的。那么应该怎么求数组元素的个数呢？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">Easy，通常有下面两种写法： </font>
				</p>
				<p>
						<font face="Verdana" size="2">int c1 = sizeof( a1 ) / sizeof( char );    // 总长度/单个元素的长度<br />int c2 = sizeof( a1 ) / sizeof( a1[0]);    // 总长度/第一个元素的长度 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">写到这里，提一问，下面的c3，c4值应该是多少呢？ </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">void foo3(char a3[3])<br />{<br />    int c3 = sizeof( a3 ); // c3 ==<br />}<br />void foo4(char a4[])<br />{<br />    int c4 = sizeof( a4 ); // c4 ==<br />} </font>
				</p>
				<p>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************</font>
								</font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">也许当你试图回答c4的值时已经意识到c3答错了，是的，c3!=3。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里函数参数<font color="#0000ff">a3已不再是数组类型，而是蜕变成指针。</font>相当于char* a3，为什么仔细想想就不难明白。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">我们调用函数foo1时，程序会在栈上分配一个大小为3的数组吗？不会！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">数组是“传址”的，调用者只需将实参的地址传递过去，所以a3自然为指针类型（char*），c3的值也就为4。 </font>
				</p>
				<p>
						<br />
						<font size="2">
								<font face="Verdana">
										<strong>
												<font color="#0000ff">7.string的sizeof</font>
										</strong>
										<br />
										<font color="#0000ff">一个string的大小与它所指向的字符串的长度无关</font>。<br /><br /><font color="#0000ff">*********************************************************</font><br />string st1("blog.sina.com.cn");<br />string st2("majianan");<br />string st3;<br />string *ps = &amp;st1;<br />cout &lt;&lt; "st1: " &lt;&lt; sizeof(st1) &lt;&lt; endl;<br />cout &lt;&lt; "st2: " &lt;&lt; sizeof(st2) &lt;&lt; endl;<br />cout &lt;&lt; "st3: " &lt;&lt; sizeof(st3) &lt;&lt; endl;<br />cout &lt;&lt; "ps: " &lt;&lt; sizeof(ps) &lt;&lt; endl;<br />cout &lt;&lt; "*ps: " &lt;&lt; sizeof(*ps) &lt;&lt; endl;<br /><font color="#0000ff">*********************************************************</font><br /><br />输出结果为：<br />st1： 28<br />st2： 28<br />st3： 28<br />ps： 4<br />*ps： 28<br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************<br /></font>对于不同的STL，String类的结构定义会有所不同<br />所以不同的工具，例如VC++，和.NET，结果会有所不同，<br />在VC++6.0中（我的机器）结果是16<br />在.NET2003中结果是28<br />但是对于同一个编译器，那么它的结果都是一定的<br /><br /><br /><font color="#0000ff"><strong>8.引用的sizeof</strong></font><br /><br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font style="BACKGROUND-COLOR: #ffffff" color="#0000ff">sizeof操作符应用在引用类型上的时候，返回的是包含被引用对象所需的内存长度（即被引用对象的大小）<br /></font>
										<br />
										<font color="#0000ff">*********************************************************</font>
										<br />cout &lt;&lt; "short:\t" &lt;&lt; sizeof(short) &lt;&lt; endl;<br />cout &lt;&lt; "short*:\t" &lt;&lt; sizeof(short*) &lt;&lt; endl; <br />cout &lt;&lt; "short&amp;:\t" &lt;&lt; sizeof(short&amp;) &lt;&lt; endl;<br />cout &lt;&lt; "short[4]:\t" &lt;&lt; sizeof(short[4]) &lt;&lt; endl;<br />cout &lt;&lt; "int&amp;:\t" &lt;&lt; sizeof(int&amp;) &lt;&lt; endl;<br /></font>
						</font>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">*********************************************************<br /></font>
										<br />输出结果为：<br />short： 2<br />short*： 4<br />short&amp;： 2<br />short[4]： 8<br />int&amp;： 4<br /><br /><br /><strong><font color="#0000ff">9. 结构体的sizeof</font></strong></font>
						</font>
				</p>
				<p>
						<font face="Verdana" size="2">这是初学者问得最多的一个问题，所以这里有必要多费点笔墨。让我们先看一个结构体： </font>
				</p>
				<p>
						<font face="Verdana" size="2">struct S1<br />{<br />    char c;<br />    int i;<br />}; </font>
				</p>
				<p>
						<font face="Verdana" size="2">问sizeof(s1)等于多少？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">聪明的你开始思考了，char占1个字节，int占4个字节，那么加起来就应该是5。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">是这样吗？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">你在你机器上试过了吗？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">也许你是对的，但很可能你是错的！ </font>
				</p>
				<p>
						<font face="Verdana" size="2">VC6中按默认设置得到的结果为8。<br /><br />    Why？为什么受伤的总是我？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">请不要沮丧，我们来好好琢磨一下sizeof的定义 —— sizeof的结果等于对象或者类型所占的内存字节数。好吧，那就让我们来看看S1的内存分配情况： </font>
				</p>
				<p>
						<font face="Verdana" size="2">S1 s1 = { 'a', 0xFFFFFFFF }; </font>
				</p>
				<p>
						<font face="Verdana" size="2">定义上面的变量后，加上断点，运行程序，观察s1所在的内存，你发现了什么？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">以我的VC6.0为例，s1的地址为0x0012FF78，其数据内容如下： </font>
				</p>
				<p>
						<font face="Verdana" size="2">0012FF78: 61 CC CC CC FF FF FF FF<br /><br />发现了什么？怎么中间夹杂了3个字节的CC？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">看看MSDN上的说明： </font>
				</p>
				<p>
						<font face="Verdana" size="2">When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">原来如此，这就是传说中的字节对齐啊！一个重要的话题出现了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">为什么需要字节对齐？ </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">计算机组成原理教导我们，这样有助于加快计算机的取数速度，否则就得多花指令周期了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">为此，编译器默认会对结构体进行处理（实际上其它地方的数据变量也是如此），<font color="#0000ff">让宽度为2的基本数据类型（short等）都位于能被2整除的地址上，让宽度为4的基本数据类型（int等）都位于能被4整除的地址上。</font>以此类推，这样，两个数中间就可能需要加入填充字节，所以整个结构体的sizeof值就增长了。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">让我们交换一下S1中char与int的位置： </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">struct S2<br />{<br />    int i;<br />    char c;<br />}; </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">看看sizeof(S2)的结果为多少？怎么还是8。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">再看看内存，原来成员c后面仍然有3个填充字节。 </font>
				</p>
				<p dir="ltr" style="MARGIN-RIGHT: 0px">
						<font face="Verdana" size="2">这又是为什么啊？别着急，下面总结规律。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">    <strong><font color="#0000ff">字节对齐的细节和编译器实现相关，但一般而言，满足三个准则：</font></strong><br />    1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除；<br />    2) 结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字节（internal adding）；<br />    3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍，如有需要编译器会在最末一个成员之后加上填充字节（trailing padding）。<br /><br />    对于上面的准则，有几点需要说明：<br />1) 前面不是说结构体成员的地址是其大小的整数倍，怎么又说到偏移量了呢？ </font>
				</p>
				<p>
						<font face="Verdana" size="2">因为有了第1点存在，所以我们就可以只考虑成员的偏移量，这样思考起来简单。想想为什么。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">结构体某个成员相对于结构体首地址的偏移量可以通过宏offsetof()来获得，这个宏也在stddef.h中定义，如下： </font>
				</p>
				<p>
						<font face="Verdana" size="2">#define offsetof(s,m) (size_t)&amp;(((s *)0)-&gt;m) </font>
				</p>
				<p>
						<font face="Verdana" size="2">例如，想要获得S2中c的偏移量，方法为 </font>
				</p>
				<p>
						<font face="Verdana" size="2">size_t pos = offsetof(S2, c);// pos等于4 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">2) 基本类型是指前面提到的像char、short、int、float、double这样的内置数据类型。这里所说的“数据宽度”就是指其sizeof的大小。由于结构体的成员可以是复合类型，比如另外一个结构体，所以在寻找最宽基本类型成员时，应当包括复合类型成员的子成员，而不是把复合成员看成是一个整体。但在确定复合类型成员的偏移位置时则是将复合类型作为整体看待。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">这里叙述起来有点拗口，思考起来也有点挠头，还是让我们看看例子吧（具体数值仍以VC6为例，以后不再说明）： </font>
				</p>
				<p>
						<font face="Verdana" size="2">struct S3<br />{<br />    char c1;<br />    S1 s;<br />    char c2;<br />}; </font>
				</p>
				<p>
						<font face="Verdana" size="2">S1的最宽简单成员的类型为int，S3在考虑最宽简单类型成员时是将S1“打散”看的，所以S3的最宽简单类型为int。这样，通过S3定义的变量，其存储空间首地址需要被4整除，整个sizeof(S3)的值也应该被4整除。 </font>
				</p>
				<p>
						<font face="Verdana" size="2">c1的偏移量为0，s的偏移量呢？这时s是一个整体，它作为结构体变量也满足前面三个准则，所以其大小为8，偏移量为4，c1与s之间便需要3个填充字节，而c2与s之间就不需要了，所以c2的偏移量为12，算上c2的大小为13，13是不能被4整除的，这样末尾还得补上3个填充字节。最后得到sizeof(S3)的值为16。 </font>
				</p>
				<p>
						<br />
						<font face="Verdana" size="2">    通过上面的叙述，我们可以得到一个公式：<br />    <font color="#0000ff"><strong>结构体的大小等于最后一个成员的偏移量加上其大小再加上末尾的填充字节数目，</strong></font>即： </font>
				</p>
				<p>
						<font face="Verdana" size="2">sizeof( struct ) = offsetof( last item ) + sizeof( last item ) + sizeof( trailing padding ) </font>
				</p>
				<p>
						<font face="Verdana" size="2">
						</font> </p>
				<div>
						<font color="#0000ff">
								<font size="2">
										<font face="Verdana">
												<strong>10.类的sizeof</strong>
										</font>
								</font>
						</font>
				</div>
				<div>
						<font face="Verdana" size="2">
						</font> </div>
				<div>
						<font face="Verdana" size="2">类的sizeof值等于类中成员变量所占用的内存字节数。如：<br /></font>
				</div>
				<div>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">****************************************************************</font>
								</font>
						</font>
				</div>
				<div>
						<font face="Verdana" size="2">  </font>
				</div>
				<div>
						<font face="Verdana" size="2">class A<br />{<br /> public:<br />     int b;<br />     float c;<br />     char d;<br />}; </font>
				</div>
				<div>
						<br />
						<font face="Verdana" size="2">int main(void)<br />{<br />  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
				</div>
				<div>
						<font face="Verdana" size="2">
						</font> </div>
				<div>
						<font size="2">
								<font face="Verdana">
										<font color="#0000ff">***************************************************************</font>
								</font>
						</font>
				</div>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">输出结果为12（我的机器上sizeof(float)值为4，字节对其前面已经讲过）。 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">不过需要注意的是，如果类中存在静态成员变量，结果又会是什么样子呢？ </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">***************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">class A<br />{<br /> public:<br />     static int a;<br />     int b;<br />     float c;<br />     char d;<br />}; </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">int main()<br />{ </font>
		</div>
		<div>
				<font face="Verdana" size="2">  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">**************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">16？不对。结果仍然是12. </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">因为在程序编译期间，就已经为static变量在静态存储区域分配了内存空间，并且这块内存在程序的整个运行期间都存在。 </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">而每次声明了类A的一个对象的时候，为该对象在堆上，根据对象的大小分配内存。 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">如果类A中包含成员函数，那么又会是怎样的情况呢？看下面的例子 </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">*************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">class A<br />{<br /> public:<br />     static int a;<br />     int b;<br />     float c;<br />     char d;<br />     int add(int x,int y)<br />     {<br />       return x+y;<br />     }<br />}; </font>
		</div>
		<div>
				<br />
				<font face="Verdana" size="2">int main()<br />{<br />  A object;<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  b = object.add(3,4);<br />  cout &lt;&lt; "sizeof(object) is " &lt;&lt; sizeof(object) &lt;&lt; endl;<br />  return 0 ;<br />} </font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font size="2">
						<font face="Verdana">
								<font color="#0000ff">***************************************************************</font>
						</font>
				</font>
		</div>
		<div>
				<font face="Verdana" size="2">
				</font> </div>
		<div>
				<font face="Verdana" size="2">结果仍为12。<font color="#0000ff"></font></font>
		</div>
		<div>
				<font face="Verdana" color="#0000ff" size="2">
				</font>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。 </font>
				</span>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">所以每个非静态成员变量在生成新object需要内存，而function是不需要的。 </font>
				</span>
		</div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">
						</font>
				</span> </div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">
						</font>
				</span> </div>
		<div dir="ltr" align="left">
				<span class="139102807-09122005">
						<font face="Verdana" size="2">注：C++中的多态和虚继承也是非常重要的东西，不过比较复杂，编译器不同，细节也有所不同。（以后慢慢研究，哈哈）<br /><br /></font>
				</span>
		</div>
<img src ="http://www.blogjava.net/majianan/aggbug/64664.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/majianan/" target="_blank">马嘉楠</a> 2006-08-20 21:59 <a href="http://www.blogjava.net/majianan/archive/2006/08/20/64664.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>