<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>younker</title>
    <description></description>
    <link>http://younker.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>谈新手修练J2EE武功及学SSH的方法</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/190299" style="color:red;">http://younker.javaeye.com/blog/190299</a>&nbsp;
          发表时间: 2008年05月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>【转帖】：</p>
<p>这是两封信，一封来自网友adamed&nbsp;，一封是我的回复，交流的是初学者如何学习J2EE及SSH的问题，得到adamed许可，这这里发出来跟大家分享，欢迎更多的朋友来交流。<br />主题：&nbsp;请教easyjf团队各位大侠<br />&nbsp;<br />&nbsp;<br />　　您好，我是一个在职软件开发人员。我是05年开始接触java开发。06年加入北京一家公司到现在。我的工作是做J2EE开发。公司使用SSH架构（Struts－Spring－hibernate）进行开发。<br />虽然进公司半年但是由于项目原因，真正只做过一个Struts＋Hibernate的项目。现在我看了许多关于SSH的书。也看了一些代码，就是感觉自己提高太慢。<br />&nbsp;<br />　　偶然机会在CSDN的blog上看到&nbsp;大侠&nbsp;的blog知道了EasyJF。很钦佩你们的勇气，敢于开创中国开源项目之先河。<br />&nbsp;<br />　　由于接触J2EE时间太短。而现在这样的开源项目名目繁多。看了Spring的一些源代码只感觉头晕到不行。我实在不知道该如何提高自己。所以斗胆给各位EasyJF的朋友写这封邮件，请大家给我一些建议好嘛？？（由于公司使用SSH开发。所以不看这些东西还不行。）该大家给些建议该如何学习。<br />&nbsp;<br />ps：看了EasyJF的介绍我很想参与可惜能力实在有限。怕遭拒绝。<br />我现在有一颗火热的心想提高，想做技术，想为中国原创出一点力。但我也知道做技术不能浮躁。故请各位帮忙。<br />&nbsp;<br />　　adamed&nbsp;<br />　　2007-01-09&nbsp;<br />下面是我的回信：</p>
<p>您好：<br />　　感谢你对EasyJF的关注以及对国内开源的支持，国内环境普遍浮躁，因为有太多像春迷这样的人存在，搞得大家都不敢表达自己的思想了，因此还希望以后能继续多对国内开源人给予支持。<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;关于您来信中说到的问题，我觉得可能是你对java的基础的掌握还不够的原因，简单来说就是内力不够。好比中国传统武侠小说中练武人的内力问题，降龙十八掌这样的绝世掌法，要是没有一定的内力作基础的话，就只能是降蛇十八掌，甚至蛇都降不了。虚竹小和尚的武功也是因为有了高深的内力，才能变得那么牛的。而修练J2EE武学的内力，我认为大致分为三层，初级层次是JAVA基础，第二层次是OO思想及模式，第三层次是特定领域(如Web开发相关技术规范、Servlet规范、JPA规范、EJB3规范等)、专业知识的学习。有了这些内力，不管他是SSH还是EasyJF，使用起来都会非常容易的。<br />&nbsp;<br />　　SSH属于框架，属于工具，也是中间件。他们是用来提高我们的开发效率，提高我们软件产品的可维护性、可扩展性乃至敏捷性的。<br />&nbsp;<br />　　他们里面有很我优秀的设计理念及模式应用。比如，struts属于MVC框架，关键是要了解MVC的概念及大致原理，掌握就很容易了；而hibernate属于orm系统，属于持久层的解决方案，同样需要对ORM的概念及原理有一个总体的了解，必要时可以去查查EJB1及EJB2里面用于持久层的Entity&nbsp;Bean的使用。而spring属于应用程序框架，其核心是IOC容器以及AOP，把这两个核心概念(也可称为大模式)了解以后，再加上一定的内力修为，其它就都不难了。Spring中还集成了很多适用东西(不过这些东西80%的在某一个项目中可能一直用不上)，比如对JDBC的封装、自己的MVC、对动态语言的简洁访问等，这些你根据自己的项目情况来选择学习，用到的时候再看看他的文档，一个项目下来应该就能把握。<br />&nbsp;<br />　　说了那么多，我累了，你一定也有点晕了，下面结合你的情况，简单发表一点我的建议：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />　　１、用一年的时间慢慢提升自己的内力，然后这期间可以通过下面的方法同步学习使用ssh。<br />　　2、看一些国内作者原创的书籍，并运行相关代码，比如孙卫琴的Struts及Hibernate等入门教程，罗时飞的Spring教程。他们的书都通谷易懂，很多属于他们在学习过程中的点滴记录，因此一定非常好懂。不要一下子就去读Rod的《J2EE&nbsp;Without&nbsp;EJB》，或者是Spring开发团队编写的《Spring框架高级编程》，甚至《Spring&nbsp;in&nbsp;action》！由于很多缘故，这些书看了你一定会更晕。<br />　　3、下载一些国内原创的SSH应用源码示例。国外有很多这样的，也可以多看看。<br />　　4、运行这些框架所附带Example示例，并了解其设计原理，并能简单修改。<br />　　5、运行并多看这些框架的测试代码。要像买彩民分析采票走势图那样慢慢琢磨分析。<br />　　6、在自己的项目中多动用，熟练使用一个开发工具，如Eclipse，并能掌握程序调试技巧。<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />　　最后，关于Spring的学习，可以看看我们最近在编写的《深入Spring&nbsp;2：轻量级J2EE开发框架原理与实践》的电子版，现在有两章可以下载，比较适合入门，网址是：<a href="http://www.easyjf.com/spring">http://www.easyjf.com/spring</a>。<br />&nbsp;<br />　　另外，我准备你给我的信及我给你的回信放到我的blog上，供大家分享我们的交流，不知道您是否愿意？<br />&nbsp;<br />　　祝：学习愉快，工作顺利！</p>
          <br/>
          <span style="color:red;">
            <a href="http://younker.javaeye.com/blog/190299#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 06 May 2008 16:56:50 +0800</pubDate>
        <link>http://younker.javaeye.com/blog/190299</link>
        <guid>http://younker.javaeye.com/blog/190299</guid>
      </item>
      <item>
        <title>C++题汇总</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/140833" style="color:red;">http://younker.javaeye.com/blog/140833</a>&nbsp;
          发表时间: 2007年11月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div id="loading" style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 3px; BORDER-TOP: rgb(204,204,204) 1px solid; DISPLAY: none; PADDING-LEFT: 3px; FONT-WEIGHT: bold; FONT-SIZE: 12px; LEFT: 808px; PADDING-BOTTOM: 0pt; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 160px; COLOR: rgb(0,0,0); PADDING-TOP: 0pt; BORDER-BOTTOM: rgb(204,204,204) 1px solid; POSITION: absolute; TOP: 10846px; HEIGHT: 30px; BACKGROUND-COLOR: rgb(255,255,175); dontFilter: yes">正在处理您的请求...</div>
<form name="Form1" method="post" onsubmit="javascript:return WebForm_OnSubmit();" action="1821937.aspx" language="javascript" id="Form1">
    <script src="file:///C:/Documents%20and%20Settings/keke/%E6%A1%8C%E9%9D%A2/%EF%BC%88%E8%BD%AC%E8%B4%B4%EF%BC%89c++%E7%AC%94%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB%20-%20unix229%E7%9A%84%E4%B8%93%E6%A0%8F%20-%20CSDNBlog.files/vote.js"></script><script src="file:///C:/Documents%20and%20Settings/keke/%E6%A1%8C%E9%9D%A2/%EF%BC%88%E8%BD%AC%E8%B4%B4%EF%BC%89c++%E7%AC%94%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB%20-%20unix229%E7%9A%84%E4%B8%93%E6%A0%8F%20-%20CSDNBlog.files/count.htm"></script>
    <div id="main">
    <div class="post">
    <div class="postText">
    <div><font color="#333333"><strong><font size="3" color="#800000">1.求下面函数的返回值（微软）<br />
    </font></strong><br />
    int func(x)<br />
    {<br />
    int countx = 0;<br />
    while(x)<br />
    {<br />
    countx ++;<br />
    x = x&amp;(x-1);<br />
    }<br />
    return countx;<br />
    } <br />
    <br />
    假定x = 9999。 答案：8<br />
    <br />
    思路：将x转化为2进制，看含有的1的个数。<br />
    <br />
    <font size="3" color="#800000"><strong>2. 什么是&ldquo;引用&rdquo;？申明和使用&ldquo;引用&rdquo;要注意哪些问题？<br />
    </strong></font><br />
    答：引用就是某个目标变量的&ldquo;别名&rdquo;(alias)，对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候，切记要对其进行初始化。引用声明完毕后，相当于目标变量名有两个名称，即该目标原名称和引用名，不能再把该引用名作为其他变量名的别名。声明一个引用，不是新定义了一个变量，它只表示该引用名是目标变量名的一个别名，它本身不是一种数据类型，因此引用本身不占存储单元，系统也不给引用分配存储单元。不能建立数组的引用。<br />
    <br />
    <strong><font size="4" color="#800000">3. 将&ldquo;引用&rdquo;作为函数参数有哪些特点？</font></strong><br />
    <br />
    （1）传递引用给函数与传递指针的效果是一样的。这时，被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用，所以在被调函数中对形参变量的操作就是对其相应的目标对象（在主调函数中）的操作。<br />
    <br />
    （2）使用引用传递函数的参数，在内存中并没有产生实参的副本，它是直接对实参操作；而使用一般变量传递函数的参数，当发生函数调用时，需要给形参分配存储单元，形参变量是实参变量的副本；如果传递的是对象，还将调用拷贝构造函数。因此，当参数传递的数据较大时，用引用比用一般变量传递参数的效率和所占空间都好。<br />
    <br />
    （3）使用指针作为函数的参数虽然也能达到与使用引用的效果，但是，在被调函数中同样要给形参分配存储单元，且需要重复使用&quot;*指针变量名&quot;的形式进行运算，这很容易产生错误且程序的阅读性较差；另一方面，在主调函数的调用点处，必须用变量的地址作为实参。而引用更容易使用，更清晰。<br />
    <br />
    <font size="4" color="#800000"><strong>4. 在什么时候需要使用&ldquo;常引用&rdquo;？</strong></font>　<br />
    <br />
    如果既要利用引用提高程序的效率，又要保护传递给函数的数据不在函数中被改变，就应使用常引用。常引用声明方式：const 类型标识符 &amp;引用名=目标变量名；<br />
    <br />
    例1<br />
    <br />
    int a ;<br />
    const int &amp;ra=a;<br />
    ra=1; //错误<br />
    a=1; //正确<br />
    <br />
    例2<br />
    <br />
    string foo( );<br />
    void bar(string &amp; s);<br />
    <br />
    那么下面的表达式将是非法的：<br />
    <br />
    bar(foo( ));<br />
    bar(&quot;hello world&quot;);<br />
    <br />
    原因在于foo( )和&quot;hello world&quot;串都会产生一个临时对象，而在C++中，这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型，这是非法的。<br />
    <br />
    引用型参数应该在能被定义为const的情况下，尽量定义为const 。<br />
    <br />
    <strong><font size="4" color="#800000">5. 将&ldquo;引用&rdquo;作为函数返回值类型的格式、好处和需要遵守的规则?<br />
    </font></strong><br />
    格式：类型标识符 &amp;函数名（形参列表及类型说明）{ //函数体 }<br />
    <br />
    好处：在内存中不产生被返回值的副本；（注意：正是因为这点原因，所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束，相应的引用也会失效，产生runtime error!<br />
    <br />
    注意事项：<br />
    <br />
    （1）不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。主要原因是局部变量会在函数返回后被销毁，因此被返回的引用就成为了&quot;无所指&quot;的引用，程序会进入未知状态。<br />
    <br />
    （2）不能返回函数内部new分配的内存的引用。这条可以参照Effective C++[1]的Item 31。虽然不存在局部变量的被动销毁问题，可对于这种情况（返回函数内部new分配内存的引用），又面临其它尴尬局面。例如，被函数返回的引用只是作为一个临时变量出现，而没有被赋予一个实际的变量，那么这个引用所指向的空间（由new分配）就无法释放，造成memory leak。<br />
    <br />
    （3）可以返回类成员的引用，但最好是const。这条原则可以参照Effective C++[1]的Item 30。主要原因是当对象的属性是与某种业务规则（business rule）相关联的时候，其赋值常常与某些其它属性或者对象的状态有关，因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常量引用（或指针），那么对该属性的单纯赋值就会破坏业务规则的完整性。<br />
    <br />
    （4）流操作符重载返回值申明为&ldquo;引用&rdquo;的作用：<br />
    <br />
    流操作符&lt;&lt;和&gt;&gt;，这两个操作符常常希望被连续使用，例如：cout &lt;&lt; &quot;hello&quot; &lt;&lt; endl;　因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括：返回一个流对象和返回一个流对象指针。但是对于返回一个流对象，程序必须重新（拷贝）构造一个新的流对象，也就是说，连续的两个&lt;&lt;操作符实际上是针对不同对象的！这无法让人接受。对于返回一个流指针则不能连续使用&lt;&lt;操作符。因此，返回一个流对象引用是惟一选择。这个唯一选择很关键，它说明了引用的重要性以及无可替代性，也许这就是C++语言中引入引用这个概念的原因吧。赋值操作符=。这个操作符象流操作符一样，是可以连续使用的，例如：x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值，以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。<br />
    <br />
    例3<br />
    <br />
    ＃i nclude &lt;iostream.h&gt;<br />
    int &amp;put(int n);<br />
    int vals[10];<br />
    int error=-1;<br />
    void main()<br />
    {<br />
    put(0)=10; //以put(0)函数值作为左值，等价于vals[0]=10;<br />
    put(9)=20; //以put(9)函数值作为左值，等价于vals[9]=20;<br />
    cout&lt;&lt;vals[0];<br />
    cout&lt;&lt;vals[9];<br />
    }<br />
    int &amp;put(int n)<br />
    {<br />
    if (n&gt;=0 &amp;&amp; n&lt;=9 ) return vals[n];<br />
    else { cout&lt;&lt;&quot;subscript error&quot;; return error; }<br />
    }<br />
    <br />
    （5）在另外的一些操作符中，却千万不能返回引用：+-*/ 四则运算符。它们不能返回引用，Effective C++[1]的Item23详细的讨论了这个问题。主要原因是这四个操作符没有side effect，因此，它们必须构造一个对象作为返回值，可选的方案包括：返回一个对象、返回一个局部变量的引用，返回一个new分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则，第2、3两个方案都被否决了。静态对象的引用又因为((a+b) == (c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。<br />
    <br />
    <font size="4" color="#800000"><strong>6. &ldquo;引用&rdquo;与多态的关系？<br />
    </strong></font><br />
    引用是除指针外另一个可以产生多态效果的手段。这意味着，一个基类的引用可以指向它的派生类实例。<br />
    <br />
    例4<br />
    <br />
    Class A; Class B : Class A{...}; B b; A&amp; ref = b;<br />
    <br />
    <font size="4" color="#800000"><strong>7. &ldquo;引用&rdquo;与指针的区别是什么？</strong></font><br />
    <br />
    指针通过某个指针变量指向一个对象后，对它所指向的变量间接操作。程序中使用指针，程序的可读性差；而引用本身就是目标变量的别名，对引用的操作就是对目标变量的操作。此外，就是上面提到的对函数传ref和pointer的区别。<br />
    <br />
    <font size="4" color="#800000"><strong>8. 什么时候需要&ldquo;引用&rdquo;？</strong></font><br />
    <br />
    流操作符&lt;&lt;和&gt;&gt;、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。<br />
    <br />
    以上 2-8 参考：http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx<br />
    <br />
    <font size="4" color="#800000"><strong>9. 结构与联合有和区别？</strong></font><br />
    1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员（所有成员共用一块地址空间）, 而结构的所有成员都存在（不同成员的存放地址不同）。 <br />
    2. 对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。<br />
    <br />
    <font size="4" color="#800000"><strong>10. 下面关于&ldquo;联合&rdquo;的题目的输出？<br />
    </strong></font><br />
    a)<br />
    <br />
    ＃i nclude &lt;stdio.h&gt;<br />
    union<br />
    {<br />
    int i;<br />
    char x[2];<br />
    }a;<br />
    <br />
    <br />
    void main()<br />
    {<br />
    a.x[0] = 10;<br />
    a.x[1] = 1;<br />
    printf(&quot;%d&quot;,a.i);<br />
    }<br />
    答案：266 (低位低地址，高位高地址，内存占用情况是Ox010A）<br />
    <br />
    b)<br />
    <br />
    main()<br />
    {<br />
    union{ /*定义一个联合*/<br />
    int i;<br />
    struct{ /*在联合中定义一个结构*/<br />
    char first;<br />
    char second;<br />
    }half;<br />
    }number;<br />
    number.i=0x4241; /*联合成员赋值*/<br />
    printf(&quot;%c%c\n&quot;, number.half.first, mumber.half.second);<br />
    number.half.first='a'; /*联合中结构成员赋值*/<br />
    number.half.second='b';<br />
    printf(&quot;%x\n&quot;, number.i);<br />
    getch();<br />
    }<br />
    答案： AB (0x41对应'A',是低位；Ox42对应'B',是高位）<br />
    <br />
    6261 (number.i和number.half共用一块地址空间）<br />
    <br />
    <font size="4" color="#800000"><strong>11. 已知strcpy的函数原型：char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串，strSrc 是源字符串。不调用C++/C 的字符串库函数，请编写函数 strcpy。<br />
    </strong></font><br />
    <br />
    答案：<br />
    char *strcpy(char *strDest, const char *strSrc)<br />
    {<br />
    if ( strDest == NULL || strSrc == NULL)<br />
    return NULL ;<br />
    if ( strDest == strSrc)<br />
    return strDest ;<br />
    char *tempptr = strDest ;<br />
    while( (*strDest++ = *strSrc++) != &lsquo;\0&rsquo;)<br />
    return tempptr ;<br />
    }<br />
    <br />
    <font size="4" color="#800000"><strong>12. 已知String类定义如下：</strong></font><br />
    <br />
    class String<br />
    {<br />
    public:<br />
    String(const char *str = NULL); // 通用构造函数<br />
    String(const String &amp;another); // 拷贝构造函数<br />
    ~ String(); // 析构函数<br />
    String &amp; operater =(const String &amp;rhs); // 赋值函数<br />
    private:<br />
    char *m_data; // 用于保存字符串<br />
    };<br />
    <br />
    尝试写出类的成员函数实现。<br />
    <br />
    答案：<br />
    <br />
    String::String(const char *str)<br />
    {<br />
    if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断<br />
    {<br />
    m_data = new char[1] ;<br />
    m_data[0] = '\0' ;<br />
    }<br />
    else<br />
    {<br />
    m_data = new char[strlen(str) + 1];<br />
    strcpy(m_data,str);<br />
    }<br />
    <br />
    } <br />
    <br />
    String::String(const String &amp;another)<br />
    {<br />
    m_data = new char[strlen(another.m_data) + 1];<br />
    strcpy(m_data,other.m_data);<br />
    }<br />
    <br />
    <br />
    String&amp; String::operator =(const String &amp;rhs)<br />
    {<br />
    if ( this == &amp;rhs)<br />
    return *this ;<br />
    delete []m_data; //删除原来的数据，新开一块内存<br />
    m_data = new char[strlen(rhs.m_data) + 1];<br />
    strcpy(m_data,rhs.m_data);<br />
    return *this ;<br />
    }<br />
    <br />
    <br />
    String::~String()<br />
    {<br />
    delete []m_data ;<br />
    }<br />
    <br />
    <font size="4" color="#800000"><strong>13. .h头文件中的ifndef/define/endif 的作用？<br />
    </strong></font><br />
    答：防止该头文件被重复引用。<br />
    <br />
    <strong><font size="4" color="#800000">14. ＃i nclude&lt;file.h&gt; 与 ＃i nclude &quot;file.h&quot;的区别？<br />
    </font></strong><br />
    答：前者是从Standard Library的路径寻找和引用file.h，而后者是从当前工作路径搜寻并引用file.h。<br />
    <br />
    <font size="4" color="#800000"><strong>15.在C++ 程序中调用被C 编译器编译后的函数，为什么要加extern &ldquo;C&rdquo;？</strong></font><br />
    <br />
    首先，作为extern是C/C++语言中表明函数和全局变量作用范围（可见性）的关键字，该关键字告诉编译器，其声明的函数和变量可以在本模块或其它模块中使用。<br />
    <br />
    通常，在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如，如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样，模块B中调用模块A中的函数时，在编译阶段，模块B虽然找不到该函数，但是并不会报错；它会在连接阶段中从模块A编译生成的目标代码中找到此函数<br />
    <br />
    extern &quot;C&quot;是连接申明(linkage declaration),被extern &quot;C&quot;修饰的变量和函数是按照C语言方式编译和连接的,来看看C++中对类似C的函数是怎样编译的：<br />
    <br />
    作为一种面向对象的语言，C++支持函数重载，而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如，假设某个函数的原型为：<br />
    <br />
    void foo( int x, int y );<br />
    　　<br />
    <br />
    该函数被C编译器编译后在符号库中的名字为_foo，而C++编译器则会产生像_foo_int_int之类的名字（不同的编译器可能生成的名字不同，但是都采用了相同的机制，生成的新名字称为&ldquo;mangled name&rdquo;）。<br />
    <br />
    _foo_int_int 这样的名字包含了函数名、函数参数数量及类型信息，C++就是靠这种机制来实现函数重载的。例如，在C++中，函数void foo( int x, int y )与void foo( int x, float y )编译生成的符号是不相同的，后者为_foo_int_float。<br />
    <br />
    同样地，C++中的变量除支持局部变量外，还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名，我们以&quot;.&quot;来区分。而本质上，编译器在进行编译时，与函数的处理相似，也为类中的变量取了一个独一无二的名字，这个名字与用户程序中同名的全局变量名字不同。<br />
    <br />
    未加extern &quot;C&quot;声明时的连接方式<br />
    <br />
    假设在C++中，模块A的头文件如下：<br />
    <br />
    // 模块A头文件　moduleA.h<br />
    #ifndef MODULE_A_H<br />
    #define MODULE_A_H<br />
    int foo( int x, int y );<br />
    #endif　　<br />
    <br />
    在模块B中引用该函数：<br />
    <br />
    // 模块B实现文件　moduleB.cpp<br />
    ＃i nclude &quot;moduleA.h&quot;<br />
    foo(2,3);<br />
    　　<br />
    <br />
    实际上，在连接阶段，连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号！<br />
    <br />
    加extern &quot;C&quot;声明后的编译和连接方式<br />
    <br />
    加extern &quot;C&quot;声明后，模块A的头文件变为：<br />
    <br />
    // 模块A头文件　moduleA.h<br />
    #ifndef MODULE_A_H<br />
    #define MODULE_A_H<br />
    extern &quot;C&quot; int foo( int x, int y );<br />
    #endif　　<br />
    <br />
    在模块B的实现文件中仍然调用foo( 2,3 )，其结果是：<br />
    （1）模块A编译生成foo的目标代码时，没有对其名字进行特殊处理，采用了C语言的方式；<br />
    <br />
    （2）连接器在为模块B的目标代码寻找foo(2,3)调用时，寻找的是未经修改的符号名_foo。<br />
    <br />
    如果在模块A中函数声明了foo为extern &quot;C&quot;类型，而模块B中包含的是extern int foo( int x, int y ) ，则模块B找不到模块A中的函数；反之亦然。<br />
    <br />
    所以，可以用一句话概括extern &ldquo;C&rdquo;这个声明的真实目的（任何语言中的任何语法特性的诞生都不是随意而为的，来源于真实世界的需求驱动。我们在思考问题时，不能只停留在这个语言是怎么做的，还要问一问它为什么要这么做，动机是什么，这样我们可以更深入地理解许多问题）：实现C++与C及其它语言的混合编程。　　<br />
    <br />
    明白了C++中extern &quot;C&quot;的设立动机，我们下面来具体分析extern &quot;C&quot;通常的使用技巧：<br />
    <br />
    extern &quot;C&quot;的惯用法<br />
    <br />
    （1）在C++中引用C语言中的函数和变量，在包含C语言头文件（假设为cExample.h）时，需进行下列处理：<br />
    <br />
    extern &quot;C&quot;<br />
    {<br />
    ＃i nclude &quot;cExample.h&quot;<br />
    }<br />
    <br />
    而在C语言的头文件中，对其外部函数只能指定为extern类型，C语言中不支持extern &quot;C&quot;声明，在.c文件中包含了extern &quot;C&quot;时会出现编译语法错误。<br />
    <br />
    C++引用C函数例子工程中包含的三个文件的源代码如下：<br />
    <br />
    /* c语言头文件：cExample.h */<br />
    #ifndef C_EXAMPLE_H<br />
    #define C_EXAMPLE_H<br />
    extern int add(int x,int y);<br />
    #endif<br />
    <br />
    <br />
    /* c语言实现文件：cExample.c */<br />
    ＃i nclude &quot;cExample.h&quot;<br />
    int add( int x, int y )<br />
    {<br />
    return x + y;<br />
    }<br />
    <br />
    <br />
    // c++实现文件，调用add：cppFile.cpp<br />
    extern &quot;C&quot;<br />
    {<br />
    ＃i nclude &quot;cExample.h&quot;<br />
    }<br />
    int main(int argc, char* argv[])<br />
    {<br />
    add(2,3);<br />
    return 0;<br />
    }<br />
    <br />
    如果C++调用一个C语言编写的.DLL时，当包括.DLL的头文件或声明接口函数时，应加extern &quot;C&quot; {　}。<br />
    <br />
    （2）在C中引用C++语言中的函数和变量时，C++的头文件需添加extern &quot;C&quot;，但是在C语言中不能直接引用声明了extern &quot;C&quot;的该头文件，应该仅将C文件中将C++中定义的extern &quot;C&quot;函数声明为extern类型。<br />
    <br />
    C引用C++函数例子工程中包含的三个文件的源代码如下：<br />
    <br />
    //C++头文件 cppExample.h<br />
    #ifndef CPP_EXAMPLE_H<br />
    #define CPP_EXAMPLE_H<br />
    extern &quot;C&quot; int add( int x, int y );<br />
    #endif<br />
    <br />
    <br />
    //C++实现文件 cppExample.cpp<br />
    ＃i nclude &quot;cppExample.h&quot;<br />
    int add( int x, int y )<br />
    {<br />
    return x + y;<br />
    }<br />
    <br />
    <br />
    /* C实现文件 cFile.c<br />
    /* 这样会编译出错：＃i nclude &quot;cExample.h&quot; */<br />
    extern int add( int x, int y );<br />
    int main( int argc, char* argv[] )<br />
    {<br />
    add( 2, 3 );<br />
    return 0;<br />
    }<br />
    <br />
    <font color="#808000"><strong>15题目的解答请参考《C++中extern &ldquo;C&rdquo;含义深层探索》注解：</strong></font><br />
    <br />
    <font size="4" color="#800000"><strong>16. 关联、聚合(Aggregation)以及组合(Composition)的区别？</strong></font><br />
    <br />
    涉及到UML中的一些概念：关联是表示两个类的一般性联系，比如&ldquo;学生&rdquo;和&ldquo;老师&rdquo;就是一种关联关系；聚合表示has-a的关系，是一种相对松散的关系，聚合类不需要对被聚合类负责，如下图所示，用空的菱形表示聚合关系：<br />
    <br />
    <br />
    <br />
    从实现的角度讲，聚合可以表示为:<br />
    <br />
    class A {...} class B { A* a; .....}<br />
    <br />
    而组合表示contains-a的关系，关联性强于聚合：组合类与被组合类有相同的生命周期，组合类要对被组合类负责，采用实心的菱形表示组合关系：<br />
    <br />
    <br />
    <br />
    实现的形式是:<br />
    <br />
    class A{...} class B{ A a; ...}<br />
    <br />
    参考文章：http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx<br />
    <br />
    http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx<br />
    <br />
    <font size="4" color="#800000"><strong>17.面向对象的三个基本特征，并简单叙述之？<br />
    </strong></font><br />
    1. 封装：将客观事物抽象成类，每个类对自身的数据和方法实行protection(private, protected,public)<br />
    <br />
    2. 继承：广义的继承有三种实现形式：实现继承（指使用基类的属性和方法而无需额外编码的能力）、可视继承（子窗体使用父窗体的外观和实现代码）、接口继承（仅使用属性和方法，实现滞后到子类实现）。前两种（类继承）和后一种（对象组合=&gt;接口继承以及纯虚函数）构成了功能复用的两种方式。<br />
    <br />
    3. 多态：是将父对象设置成为和一个或更多的他的子对象相等的技术，赋值之后，父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说，就是一句话：允许将子类类型的指针赋值给父类类型的指针。<br />
    <br />
    <strong><font size="4" color="#800000">18. 重载（overload)和重写(overried，有的书也叫做&ldquo;覆盖&rdquo;）的区别？<br />
    </font></strong><br />
    常考的题目。从定义上来说：<br />
    <br />
    重载：是指允许存在多个同名函数，而这些函数的参数表不同（或许参数个数不同，或许参数类型不同，或许两者都不同）。<br />
    <br />
    重写：是指子类重新定义复类虚函数的方法。<br />
    <br />
    从实现原理上来说：<br />
    <br />
    重载：编译器根据函数不同的参数表，对同名函数的名称做修饰，然后这些同名函数就成了不同的函数（至少对于编译器来说是这样的）。如，有两个同名函数：function func(p:integer):integer;和function func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的：int_func、str_func。对于这两个函数的调用，在编译器间就已经确定了，是静态的。也就是说，它们的地址在编译期就绑定了（早绑定），因此，重载和多态无关！<br />
    <br />
    重写：和多态真正相关。当子类重新定义了父类的虚函数后，父类指针根据赋给它的不同的子类指针，动态的调用属于子类的该函数，这样的函数调用在编译期间是无法确定的（调用的子类的虚函数的地址无法给出）。因此，这样的函数地址是在运行期绑定的（晚绑定）。<br />
    <br />
    <font size="4" color="#800000"><strong>19. 多态的作用？<br />
    </strong></font><br />
    主要是两个：1. 隐藏实现细节，使得代码能够模块化；扩展代码模块，实现代码重用；2. 接口重用：为了类在继承和派生的时候，保证使用家族中任一类的实例的某一属性时的正确调用。<br />
    <br />
    <font size="4" color="#800000"><strong>20. Ado与Ado.net的相同与不同？</strong></font><br />
    <br />
    除了&ldquo;能够让应用程序处理存储于DBMS 中的数据&ldquo;这一基本相似点外，两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM 技术，而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM 体系，ADO.NET 接口也就完全不同于ADO和OLE DB 接口，这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net 提供对XML 的支持。<br />
    <br />
    <font size="4" color="#800000"><strong>21. New delete 与malloc free 的联系与区别?<br />
    </strong></font>答案：都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象，new 会自动调用对象的构造函数。delete 会调用对象的destructor，而free 不会调用对象的destructor.<br />
    <br />
    <font size="4" color="#800000"><strong>22. #define DOUBLE(x) x+x ，i = 5*DOUBLE(5)； i 是多少？</strong></font><br />
    答案：i 为30。<br />
    <br />
    <font size="4" color="#800000"><strong>23. 有哪几种情况只能用intialization list 而不能用assignment?</strong></font><br />
    <br />
    答案：当类中含有const、reference 成员变量；基类的构造函数都需要初始化表。<br />
    <br />
    <font size="4" color="#800000"><strong>24. C++是不是类型安全的？</strong></font><br />
    答案：不是。两个不同类型的指针之间可以强制转换（用reinterpret cast)。C#是类型安全的。<br />
    <br />
    <strong><font size="4" color="#800000">25. main 函数执行以前，还会执行什么代码？</font></strong><br />
    答案：全局对象的构造函数会在main 函数之前执行。<br />
    <br />
    <strong><font size="4" color="#800000">26. 描述内存分配方式以及它们的区别?</font></strong><br />
    1） 从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的整个运行期间都存在。例如全局变量，static 变量。<br />
    2） 在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。<br />
    3） 从堆上分配，亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存，程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定，使用非常灵活，但问题也最多。<br />
    <br />
    <font size="4" color="#800000"><strong>27.struct 和 class 的区别</strong></font><br />
    <br />
    答案：struct 的成员默认是公有的，而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。<br />
    <br />
    从感情上讲，大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位，而类就象活的并且可靠的社会成员，它有智能服务，有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为，那么只有在你的类有很少的方法并且有公有数据（这种事情在良好设计的系统中是存在的!）时，你也许应该使用 struct 关键字，否则，你应该使用 class 关键字。 <br />
    <br />
    <strong><font size="3" color="#800000">28.当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少，如果不是零，请解释一下编译器为什么没有让它为零。（Autodesk）</font><br />
    </strong>答案：肯定不是零。举个反例，如果是零的话，声明一个class A[10]对象数组，而每一个对象占用的空间是零，这时就没办法区分A[0],A[1]&hellip;了。<br />
    <br />
    <font size="3" color="#800000"><strong>29. 在8086 汇编下，逻辑地址和物理地址是怎样转换的？（Intel）<br />
    </strong></font>答案：通用寄存器给出的地址，是段内偏移地址，相应段寄存器地址*10H+通用寄存器内地址，就得到了真正要访问的地址。<br />
    <br />
    <strong><font size="3" color="#800000">30. 比较C++中的4种类型转换方式？</font></strong><br />
    <br />
    请参考：http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspx，重点是static_cast, dynamic_cast和reinterpret_cast的区别和应用。<br />
    <br />
    <font size="3" color="#800000"><strong>31.分别写出BOOL,int,float,指针类型的变量a 与&ldquo;零&rdquo;的比较语句。</strong></font><br />
    答案：<br />
    BOOL : if ( !a ) or if(a)<br />
    int : if ( a == 0)<br />
    float : const EXPRESSION EXP = 0.000001<br />
    if ( a &lt; EXP &amp;&amp; a &gt;-EXP)<br />
    pointer : if ( a != NULL) or if(a == NULL)<br />
    <br />
    <br />
    <br />
    <font size="3" color="#800000"><strong>32.请说出const与#define 相比，有何优点？<br />
    </strong></font>答案：1） const 常量有数据类型，而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换，没有类型安全检查，并且在字符替换可能会产生意料不到的错误。<br />
    2） 有些集成化的调试工具可以对const 常量进行调试，但是不能对宏常量进行调试。<br />
    <br />
    <font size="3" color="#800000"><strong>33.简述数组与指针的区别？</strong></font><br />
    数组要么在静态存储区被创建（如全局数组），要么在栈上被创建。指针可以随时指向任意类型的内存块。<br />
    (1)修改内容上的差别<br />
    char a[] = &ldquo;hello&rdquo;;<br />
    a[0] = &lsquo;X&rsquo;;<br />
    char *p = &ldquo;world&rdquo;; // 注意p 指向常量字符串<br />
    p[0] = &lsquo;X&rsquo;; // 编译器不能发现该错误，运行时错误<br />
    (2) 用运算符sizeof 可以计算出数组的容量（字节数）。sizeof(p),p 为指针得到的是一个指针变量的字节数，而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量，除非在申请内存时记住它。注意当数组作为函数的参数进行传递时，该数组自动退化为同类型的指针。<br />
    char a[] = &quot;hello world&quot;;<br />
    char *p = a;<br />
    cout&lt;&lt; sizeof(a) &lt;&lt; endl; // 12 字节<br />
    cout&lt;&lt; sizeof(p) &lt;&lt; endl; // 4 字节<br />
    计算数组和指针的内存容量<br />
    void Func(char a[100])<br />
    {<br />
    cout&lt;&lt; sizeof(a) &lt;&lt; endl; // 4 字节而不是100 字节<br />
    }<br />
    <br />
    <font size="3" color="#800000"><strong>34.类成员函数的重载、覆盖和隐藏区别？</strong></font><br />
    答案：<br />
    a.成员函数被重载的特征：<br />
    （1）相同的范围（在同一个类中）；<br />
    （2）函数名字相同；<br />
    （3）参数不同；<br />
    （4）virtual 关键字可有可无。<br />
    b.覆盖是指派生类函数覆盖基类函数，特征是：<br />
    （1）不同的范围（分别位于派生类与基类）；<br />
    （2）函数名字相同；<br />
    （3）参数相同；<br />
    （4）基类函数必须有virtual 关键字。<br />
    c.&ldquo;隐藏&rdquo;是指派生类的函数屏蔽了与其同名的基类函数，规则如下：<br />
    （1）如果派生类的函数与基类的函数同名，但是参数不同。此时，不论有无virtual关键字，基类的函数将被隐藏（注意别与重载混淆）。<br />
    （2）如果派生类的函数与基类的函数同名，并且参数也相同，但是基类函数没有virtual 关键字。此时，基类的函数被隐藏（注意别与覆盖混淆）<br />
    <br />
    <font size="3" color="#800000"><strong>35. There are two int variables: a and b, don&rsquo;t use &ldquo;if&rdquo;, &ldquo;? :&rdquo;, &ldquo;switch&rdquo;or other judgement statements, find out the biggest one of the two numbers.<br />
    </strong></font>答案：( ( a + b ) + abs( a - b ) ) / 2<br />
    <br />
    <font size="3" color="#800000"><strong>36. 如何打印出当前源文件的文件名以及源文件的当前行号？<br />
    </strong></font>答案：<br />
    cout &lt;&lt; __FILE__ ;<br />
    cout&lt;&lt;__LINE__ ;<br />
    __FILE__和__LINE__是系统预定义宏，这种宏并不是在某个文件中定义的，而是由编译器定义的。<br />
    <br />
    <font size="3" color="#800000"><strong>37. main 主函数执行完毕后，是否可能会再执行一段代码，给出说明？<br />
    </strong></font>答案：可以，可以用_onexit 注册一个函数，它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void);<br />
    void main( void )<br />
    {<br />
    String str(&quot;zhanglin&quot;);<br />
    _onexit( fn1 );<br />
    _onexit( fn2 );<br />
    _onexit( fn3 );<br />
    _onexit( fn4 );<br />
    printf( &quot;This is executed first.\n&quot; );<br />
    }<br />
    int fn1()<br />
    {<br />
    printf( &quot;next.\n&quot; );<br />
    return 0;<br />
    }<br />
    int fn2()<br />
    {<br />
    printf( &quot;executed &quot; );<br />
    return 0;<br />
    }<br />
    int fn3()<br />
    {<br />
    printf( &quot;is &quot; );<br />
    return 0;<br />
    }<br />
    int fn4()<br />
    {<br />
    printf( &quot;This &quot; );<br />
    return 0;<br />
    }<br />
    The _onexit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to _onexit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to _onexit cannot take parameters.<br />
    <br />
    <font size="3" color="#800000"><strong>38. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的？<br />
    </strong></font>答案：<br />
    #ifdef __cplusplus<br />
    cout&lt;&lt;&quot;c++&quot;;<br />
    #else<br />
    cout&lt;&lt;&quot;c&quot;;<br />
    #endif<br />
    <br />
    <font size="3" color="#800000"><strong>39.文件中有一组整数，要求排序后输出到另一个文件中<br />
    </strong></font>答案：<br />
    <br />
    ＃i nclude&lt;iostream&gt;<br />
    <br />
    ＃i nclude&lt;fstream&gt;<br />
    <br />
    using namespace std;<br />
    <br />
    <br />
    void Order(vector&lt;int&gt;&amp; data) //bubble sort<br />
    {<br />
    int count = data.size() ;<br />
    int tag = false ; // 设置是否需要继续冒泡的标志位<br />
    for ( int i = 0 ; i &lt; count ; i++)<br />
    {<br />
    for ( int j = 0 ; j &lt; count - i - 1 ; j++)<br />
    {<br />
    if ( data[j] &gt; data[j+1])<br />
    {<br />
    tag = true ;<br />
    int temp = data[j] ;<br />
    data[j] = data[j+1] ;<br />
    data[j+1] = temp ;<br />
    }<br />
    }<br />
    if ( !tag )<br />
    break ;<br />
    }<br />
    }<br />
    <br />
    <br />
    void main( void )<br />
    {<br />
    vector&lt;int&gt;data;<br />
    ifstream in(&quot;c:\\data.txt&quot;);<br />
    if ( !in)<br />
    {<br />
    cout&lt;&lt;&quot;file error!&quot;;<br />
    exit(1);<br />
    }<br />
    int temp;<br />
    while (!in.eof())<br />
    {<br />
    in&gt;&gt;temp;<br />
    data.push_back(temp);<br />
    }<br />
    in.close(); //关闭输入文件流<br />
    Order(data);<br />
    ofstream out(&quot;c:\\result.txt&quot;);<br />
    if ( !out)<br />
    {<br />
    cout&lt;&lt;&quot;file error!&quot;;<br />
    exit(1);<br />
    }<br />
    for ( i = 0 ; i &lt; data.size() ; i++)<br />
    out&lt;&lt;data[i]&lt;&lt;&quot; &quot;;<br />
    out.close(); //关闭输出文件流<br />
    }<br />
    <br />
    <br />
    <br />
    <font size="3" color="#800000"><strong>40. 链表题：一个链表的结点结构<br />
    </strong></font>struct Node<br />
    {<br />
    int data ;<br />
    Node *next ;<br />
    };<br />
    typedef struct Node Node ;<br />
    <br />
    <br />
    (1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)<br />
    <br />
    Node * ReverseList(Node *head) //链表逆序<br />
    {<br />
    if ( head == NULL || head-&gt;next == NULL )<br />
    return head;<br />
    Node *p1 = head ;<br />
    Node *p2 = p1-&gt;next ;<br />
    Node *p3 = p2-&gt;next ;<br />
    p1-&gt;next = NULL ;<br />
    while ( p3 != NULL )<br />
    {<br />
    p2-&gt;next = p1 ;<br />
    p1 = p2 ;<br />
    p2 = p3 ;<br />
    p3 = p3-&gt;next ;<br />
    }<br />
    p2-&gt;next = p1 ;<br />
    head = p2 ;<br />
    return head ;<br />
    }<br />
    (2)已知两个链表head1 和head2 各自有序，请把它们合并成一个链表依然有序。(保留所有结点，即便大小相同）<br />
    Node * Merge(Node *head1 , Node *head2)<br />
    {<br />
    if ( head1 == NULL)<br />
    return head2 ;<br />
    if ( head2 == NULL)<br />
    return head1 ;<br />
    Node *head = NULL ;<br />
    Node *p1 = NULL;<br />
    Node *p2 = NULL;<br />
    if ( head1-&gt;data &lt; head2-&gt;data )<br />
    {<br />
    head = head1 ;<br />
    p1 = head1-&gt;next;<br />
    p2 = head2 ;<br />
    }<br />
    else<br />
    {<br />
    head = head2 ;<br />
    p2 = head2-&gt;next ;<br />
    p1 = head1 ;<br />
    }<br />
    Node *pcurrent = head ;<br />
    while ( p1 != NULL &amp;&amp; p2 != NULL)<br />
    {<br />
    if ( p1-&gt;data &lt;= p2-&gt;data )<br />
    {<br />
    pcurrent-&gt;next = p1 ;<br />
    pcurrent = p1 ;<br />
    p1 = p1-&gt;next ;<br />
    }<br />
    else<br />
    {<br />
    pcurrent-&gt;next = p2 ;<br />
    pcurrent = p2 ;<br />
    p2 = p2-&gt;next ;<br />
    }<br />
    }<br />
    if ( p1 != NULL )<br />
    pcurrent-&gt;next = p1 ;<br />
    if ( p2 != NULL )<br />
    pcurrent-&gt;next = p2 ;<br />
    return head ;<br />
    }<br />
    (3)已知两个链表head1 和head2 各自有序，请把它们合并成一个链表依然有序，这次要求用递归方法进行。 (Autodesk)<br />
    答案：<br />
    Node * MergeRecursive(Node *head1 , Node *head2)<br />
    {<br />
    if ( head1 == NULL )<br />
    return head2 ;<br />
    if ( head2 == NULL)<br />
    return head1 ;<br />
    Node *head = NULL ;<br />
    if ( head1-&gt;data &lt; head2-&gt;data )<br />
    {<br />
    head = head1 ;<br />
    head-&gt;next = MergeRecursive(head1-&gt;next,head2);<br />
    }<br />
    else<br />
    {<br />
    head = head2 ;<br />
    head-&gt;next = MergeRecursive(head1,head2-&gt;next);<br />
    }<br />
    return head ;<br />
    }<br />
    <br />
    <font size="3" color="#800000"><strong>41. 分析一下这段程序的输出 (Autodesk)</strong></font><br />
    class B<br />
    {<br />
    public:<br />
    B()<br />
    {<br />
    cout&lt;&lt;&quot;default constructor&quot;&lt;&lt;endl;<br />
    }<br />
    ~B()<br />
    {<br />
    cout&lt;&lt;&quot;destructed&quot;&lt;&lt;endl;<br />
    }<br />
    B(int i):data(i) //B(int) works as a converter ( int -&gt; instance of B)<br />
    {<br />
    cout&lt;&lt;&quot;constructed by parameter &quot; &lt;&lt; data &lt;&lt;endl;<br />
    }<br />
    private:<br />
    int data;<br />
    };<br />
    <br />
    <br />
    B Play( B b)<br />
    {<br />
    return b ;<br />
    }<br />
    <br />
    (1) results:<br />
    int main(int argc, char* argv[]) constructed by parameter 5<br />
    { destructed B(5)形参析构<br />
    B t1 = Play(5); B t2 = Play(t1); 　 destructed t1形参析构<br />
    return 0;　　　　　　　　　　　　　　 destructed t2　注意顺序！<br />
    } destructed t1<br />
    <br />
    (2) results:<br />
    int main(int argc, char* argv[]) constructed by parameter 5<br />
    { destructed B(5)形参析构<br />
    B t1 = Play(5); B t2 = Play(10); 　 constructed by parameter 10<br />
    return 0;　　　　　　　　　　　　　　 destructed B(10)形参析构<br />
    } destructed t2　注意顺序！<br />
    <br />
    destructed t1<br />
    <br />
    <font size="3" color="#800000"><strong>42. 写一个函数找出一个整数数组中，第二大的数 （microsoft）</strong></font><br />
    答案：<br />
    const int MINNUMBER = -32767 ;<br />
    int find_sec_max( int data[] , int count)<br />
    {<br />
    int maxnumber = data[0] ;<br />
    int sec_max = MINNUMBER ;<br />
    for ( int i = 1 ; i &lt; count ; i++)<br />
    {<br />
    if ( data[i] &gt; maxnumber )<br />
    {<br />
    sec_max = maxnumber ;<br />
    maxnumber = data[i] ;<br />
    }<br />
    else<br />
    {<br />
    if ( data[i] &gt; sec_max )<br />
    sec_max = data[i] ;<br />
    }<br />
    }<br />
    return sec_max ;<br />
    }<br />
    <br />
    <font size="3" color="#800000"><strong>43. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。</strong></font><br />
    <br />
    KMP算法效率最好，时间复杂度是Ｏ(n+m)。<br />
    <br />
    <font size="3" color="#800000"><strong>44. 多重继承的内存分配问题：</strong></font><br />
    比如有class A : public class B, public class C {}<br />
    那么A的内存结构大致是怎么样的？<br />
    <br />
    这个是compiler-dependent的, 不同的实现其细节可能不同。<br />
    如果不考虑有虚函数、虚继承的话就相当简单；否则的话，相当复杂。<br />
    可以参考《深入探索C++对象模型》，或者：<br />
    http://blog.csdn.net/wfwd/archive/2006/05/30/763797.aspx<br />
    <br />
    <font size="3" color="#800000"><strong>45. 如何判断一个单链表是有环的？（注意不能用标志位，最多只能用两个额外指针）</strong></font><br />
    <br />
    struct node { char val; node* next;}<br />
    <br />
    bool check(const node* head) {} //return false : 无环；true: 有环<br />
    <br />
    一种O（n）的办法就是（搞两个指针，一个每次递增一步，一个每次递增两步，如果有环的话两者必然重合，反之亦然）：<br />
    bool check(const node* head)<br />
    {<br />
    if(head==NULL) return false;<br />
    node *low=head, *fast=head-&gt;next;<br />
    while(fast!=NULL &amp;&amp; fast-&gt;next!=NULL)<br />
    {<br />
    low=low-&gt;next;<br />
    fast=fast-&gt;next-&gt;next;<br />
    if(low==fast) return true;<br />
    }<br />
    return false;<br />
    }</font><br />
    </div>
    <br />
    &nbsp;<br />
    <br />
    </div>
    </div>
    </div>
</form>
<script language="javascript" type="text/javascript">
	<!--
	    try
        {
	        hide();
        }
        catch(e){}
	//-->
    </script><script src="file:///C:/Documents%20and%20Settings/keke/%E6%A1%8C%E9%9D%A2/%EF%BC%88%E8%BD%AC%E8%B4%B4%EF%BC%89c++%E7%AC%94%E8%AF%95%E9%A2%98%E6%B1%87%E6%80%BB%20-%20unix229%E7%9A%84%E4%B8%93%E6%A0%8F%20-%20CSDNBlog.files/urchin.js" type="text/javascript">
</script><script type="text/javascript">
_uacct = "UA-1148926-2";
urchinTracker();
</script>
          <br/>
          <span style="color:red;">
            <a href="http://younker.javaeye.com/blog/140833#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 15 Nov 2007 12:15:36 +0800</pubDate>
        <link>http://younker.javaeye.com/blog/140833</link>
        <guid>http://younker.javaeye.com/blog/140833</guid>
      </item>
      <item>
        <title>Java面试题</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/140147" style="color:red;">http://younker.javaeye.com/blog/140147</a>&nbsp;
          发表时间: 2007年11月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div><strong>1、Vector 与 ArrayList</strong><br />
&nbsp;&nbsp; 1.vector是线程同步的，所以它也是线程安全的，而arraylist是线程异步的，是不安全的。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果不考虑到线程的安全因素，一 般用arraylist效率比较高。<br />
&nbsp;&nbsp; 2.如果集合中的元素的数目大于目前集合数组的长度时，vector增长率为目前数组长度的100%,<br />
&nbsp;&nbsp;&nbsp;&nbsp; 而arraylist增长率为目前数组长度的50%.如过在集合中使用数据量比较大的数据，用vector有一定的优势。<br />
&nbsp;&nbsp; 3.如果查找一个指定位置的数据，vector和arraylist使用的时间是相同的，都是0(1),这个时候使用vector和arraylist都可以。而<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果移动一个指定位置的数据花费的时间为0(n-i)n为总长度，这个时候就应该考虑到使用linklist,因为它移动一个指定位置的<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据所花费的时间为0(1),而查询一个指定位置的数据时花费的时间为0(i)。 <br />
</div>
&nbsp;
          <br/>
          <span style="color:red;">
            <a href="http://younker.javaeye.com/blog/140147#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 13 Nov 2007 11:32:08 +0800</pubDate>
        <link>http://younker.javaeye.com/blog/140147</link>
        <guid>http://younker.javaeye.com/blog/140147</guid>
      </item>
      <item>
        <title>面试常考数据库题</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/140130" style="color:red;">http://younker.javaeye.com/blog/140130</a>&nbsp;
          发表时间: 2007年11月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="tit"><strong>1、SQL之inner join/left join/right join</strong></div>
<div class="date"></div>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class="cnt">
            <p><strong>表A记录如下：<br />
            </strong>aID　　　　　aData<br />
            1　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a1<br />
            2　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a2<br />
            3　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a3<br />
            <br />
            <strong>表B记录如下:</strong><br />
            bID　　　　　bData<br />
            1　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b1<br />
            2　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b2<br />
            4　　　　　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b4</p>
            <p>--------------------------------------------------------------</p>
            <p><strong>Inner join</strong></p>
            <p>两个表a,b相连接,要取出id相同的字段 <br />
            select * from a inner join b on a.aid = b.bid这是仅取出匹配的数据. <br />
            此时的取出的是: <br />
            1 a1 b1 <br />
            2 a2 b2 </p>
            <p><br />
            那么<strong>left join </strong>指: <br />
            select * from a left join b on a.aid = b.bid <br />
            首先取出a表中所有数据,然后再加上与a,b匹配的的数据 <br />
            此时的取出的是: <br />
            1 a1 b1 <br />
            2 a2 b2 <br />
            3 a3 空字符 <br />
            </p>
            <p>同样的也有<strong>right join</strong><br />
            指的是首先取出b表中所有数据,然后再加上与a,b匹配的的数据 <br />
            此时的取出的是: <br />
            1 a1 b1 <br />
            2 a2 b2 <br />
            4 空字符 b4<br />
            </p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
          <br/>
          <span style="color:red;">
            <a href="http://younker.javaeye.com/blog/140130#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 13 Nov 2007 11:06:39 +0800</pubDate>
        <link>http://younker.javaeye.com/blog/140130</link>
        <guid>http://younker.javaeye.com/blog/140130</guid>
      </item>
      <item>
        <title>C语言面试题精萃</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/139293" style="color:red;">http://younker.javaeye.com/blog/139293</a>&nbsp;
          发表时间: 2007年11月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1）读文件file1.txt的内容（例如）：<br />
12<br />
34<br />
56<br />
输出到file2.txt：<br />
56<br />
34<br />
12<br />
（逆序）<br />
2）输出和为一个给定整数的所有组合<br />
例如n=5<br />
5=1+4；5=2+3（相加的数不能重复）<br />
则输出<br />
1，4；2，3。<br />
望高手赐教！！</p>
<p>第一题,注意可增长数组的应用.<br />
#include &lt;stdio.h&gt;<br />
#include &lt;stdlib.h&gt;</p>
<p>int main(void)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int MAX = 10;<br />
int *a = (int *)malloc(MAX * sizeof(int));<br />
int *b;<br />
&nbsp;&nbsp;&nbsp; <br />
FILE *fp1;<br />
FILE *fp2;</p>
<p>fp1 = fopen(&quot;a.txt&quot;,&quot;r&quot;);<br />
if(fp1 == NULL)<br />
{printf(&quot;error1&quot;);<br />
&nbsp;&nbsp;&nbsp; exit(-1);<br />
}</p>
<p>&nbsp;&nbsp;&nbsp; fp2 = fopen(&quot;b.txt&quot;,&quot;w&quot;);<br />
if(fp2 == NULL)<br />
{printf(&quot;error2&quot;);<br />
&nbsp;&nbsp;&nbsp; exit(-1);<br />
}</p>
<p>int i = 0;<br />
&nbsp;&nbsp;&nbsp; int j = 0;</p>
<p>while(fscanf(fp1,&quot;%d&quot;,&amp;a[i]) != EOF)<br />
{<br />
i++;<br />
j++;<br />
if(i &gt;= MAX)<br />
{<br />
MAX = 2 * MAX;<br />
b = (int*)realloc(a,MAX * sizeof(int));<br />
if(b == NULL)<br />
{<br />
printf(&quot;error3&quot;);<br />
exit(-1);<br />
}<br />
a = b;<br />
}<br />
}</p>
<p>for(;--j &gt;= 0;)<br />
&nbsp;&nbsp; fprintf(fp2,&quot;%d\n&quot;,a[j]);</p>
<p>fclose(fp1);<br />
fclose(fp2);</p>
<p>return 0;</p>
<p><br />
}</p>
<p>第二题.<br />
#include &lt;stdio.h&gt;</p>
<p>int main(void)<br />
{<br />
unsigned long int i,j,k;</p>
<p>printf(&quot;please input the number\n&quot;);<br />
scanf(&quot;%d&quot;,&amp;i);<br />
&nbsp;&nbsp;&nbsp; if( i % 2 == 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; j = i / 2;<br />
else<br />
j = i / 2 + 1;</p>
<p>printf(&quot;The result is \n&quot;);<br />
&nbsp;&nbsp;&nbsp; for(k = 0; k &lt; j; k++)<br />
&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;%d = %d + %d\n&quot;,i,k,i - k);<br />
return 0;<br />
}</p>
<p>#include &lt;stdio.h&gt;<br />
void main()<br />
{<br />
unsigned long int a,i=1;<br />
scanf(&quot;%d&quot;,&amp;a);<br />
if(a%2==0)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp; for(i=1;i&lt;a/2;i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;%d&quot;,a,a-i);<br />
}<br />
else<br />
for(i=1;i&lt;=a/2;i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot; %d, %d&quot;,i,a-i);<br />
}</p>
<p>兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程.</p>
<p>void inverse(char *p)<br />
{<br />
&nbsp;&nbsp;&nbsp; if( *p = = '\0' ) <br />
return;<br />
&nbsp;&nbsp;&nbsp; inverse( p+1 );<br />
&nbsp;&nbsp;&nbsp; printf( &quot;%c&quot;, *p );<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp; inverse(&quot;abc\0&quot;);</p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p>借签了楼上的&ldquo;递规反向输出&rdquo;<br />
#include &lt;stdio.h&gt;<br />
void test(FILE *fread, FILE *fwrite)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char buf[1024] = {0};<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!fgets(buf, sizeof(buf), fread))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test( fread, fwrite );<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fputs(buf, fwrite);<br />
}<br />
int main(int argc, char *argv[])<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE *fr = NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FILE *fw = NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fr = fopen(&quot;data&quot;, &quot;rb&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fw = fopen(&quot;dataout&quot;, &quot;wb&quot;);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; test(fr, fw);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(fr);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fclose(fw);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p>在对齐为4的情况下<br />
struct BBB<br />
{<br />
&nbsp;&nbsp; long num；<br />
&nbsp;&nbsp; char *name;<br />
&nbsp;&nbsp; short int data;<br />
&nbsp;&nbsp; char ha;<br />
&nbsp;&nbsp; short ba[5];<br />
}*p;<br />
p=0x1000000;<br />
p+0x200=____;<br />
(Ulong)p+0x200=____;<br />
(char*)p+0x200=____;<br />
希望各位达人给出答案和原因，谢谢拉<br />
解答：假设在32位CPU上，<br />
sizeof(long) = 4 bytes<br />
sizeof(char *) = 4 bytes<br />
sizeof(short int) = sizeof(short) = 2 bytes<br />
sizeof(char) = 1 bytes</p>
<p>由于是4字节对齐，<br />
sizeof(struct BBB) = sizeof(*p) <br />
= 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes&nbsp; (经Dev-C++验证)</p>
<p>p=0x1000000;<br />
p+0x200=____;<br />
&nbsp;&nbsp;&nbsp; = 0x1000000 + 0x200*24</p>
<p>(Ulong)p+0x200=____;<br />
&nbsp;&nbsp;&nbsp; = 0x1000000 + 0x200</p>
<p>(char*)p+0x200=____;<br />
&nbsp;&nbsp;&nbsp; = 0x1000000 + 0x200*4</p>
<p>你可以参考一下指针运算的细节</p>
<p><br />
写一段程序，找出数组中第k大小的数，输出数所在的位置。例如{2，4，3，4，7}中，第一大的数是7，位置在4。第二大、第三大的数都是4，位置在1、3随便输出哪一个均可。函数接口为：int find_orderk(const int* narry,const int n,const int k) <br />
要求算法复杂度不能是O(n^2）<br />
谢谢！<br />
可以先用快速排序进行排序，其中用另外一个进行地址查找<br />
代码如下，在VC++6.0运行通过。给分吧^-^</p>
<p>//快速排序</p>
<p>#include&lt;iostream&gt;</p>
<p>usingnamespacestd;</p>
<p>intPartition (int*L,intlow,int high)<br />
{<br />
inttemp = L[low];<br />
intpt = L[low];</p>
<p>while (low &lt; high)<br />
{<br />
while (low &lt; high &amp;&amp; L[high] &gt;= pt)<br />
--high;<br />
L[low] = L[high];<br />
while (low &lt; high &amp;&amp; L[low] &lt;= pt)<br />
++low;<br />
L[low] = temp;<br />
}<br />
L[low] = temp;</p>
<p>returnlow;<br />
}</p>
<p>voidQSort (int*L,intlow,int high)<br />
{<br />
if (low &lt; high)<br />
{<br />
intpl = Partition (L,low,high);</p>
<p>QSort (L,low,pl - 1);<br />
QSort (L,pl + 1,high);<br />
}<br />
}</p>
<p>intmain ()<br />
{<br />
intnarry[100],addr[100];<br />
intsum = 1,t;</p>
<p>cout &lt;&lt; &quot;Input number:&quot; &lt;&lt; endl;<br />
cin &gt;&gt; t;</p>
<p>while (t != -1)<br />
{<br />
narry[sum] = t;<br />
addr[sum - 1] = t;<br />
sum++;</p>
<p>cin &gt;&gt; t;<br />
}</p>
<p>sum -= 1;<br />
QSort (narry,1,sum);</p>
<p>for (int i = 1; i &lt;= sum;i++)<br />
cout &lt;&lt; narry[i] &lt;&lt; '\t';<br />
cout &lt;&lt; endl;</p>
<p>intk;<br />
cout &lt;&lt; &quot;Please input place you want:&quot; &lt;&lt; endl;<br />
cin &gt;&gt; k;</p>
<p>intaa = 1;<br />
intkk = 0;<br />
for (;;)<br />
{<br />
if (aa == k)<br />
break;<br />
if (narry[kk] != narry[kk + 1])<br />
{<br />
aa += 1;<br />
kk++;<br />
}</p>
<p>}</p>
<p>cout &lt;&lt; &quot;The NO.&quot; &lt;&lt; k &lt;&lt; &quot;number is:&quot; &lt;&lt; narry[sum - kk] &lt;&lt; endl;<br />
cout &lt;&lt; &quot;And it's place is:&quot; ;<br />
for (i = 0;i &lt; sum;i++)<br />
{<br />
if (addr[i] == narry[sum - kk])<br />
cout &lt;&lt; i &lt;&lt; '\t';<br />
}</p>
<p><br />
return0;<br />
}</p>
<p>1、找错<br />
Void test1()<br />
{<br />
char string[10];<br />
char* str1=&quot;0123456789&quot;;<br />
strcpy(string, str1);// 溢出，应该包括一个存放'\0'的字符string[11]<br />
}</p>
<p><br />
Void test2()<br />
{<br />
char string[10], str1[10];<br />
for(I=0; I&lt;10;I++)<br />
{<br />
str1[i] ='a';<br />
}<br />
strcpy(string, str1);// I，i没有声明。<br />
}</p>
<p>Void test3(char* str1)<br />
{<br />
char string[10];<br />
if(strlen(str1)&lt;=10)// 改成&lt;10,字符溢出，将strlen改为sizeof也可以<br />
{<br />
strcpy(string, str1);<br />
}<br />
}</p>
<p>2.<br />
void g(int**);<br />
int main()<br />
{<br />
int line[10],i;<br />
int *p=line; //p是地址的地址<br />
for (i=0;i&lt;10;i++)<br />
{<br />
*p=i;<br />
g(&amp;p);//数组对应的值加1<br />
}<br />
for(i=0;i&lt;10;i++)<br />
printf(&quot;%d\n&quot;,line[i]);<br />
return 0;<br />
}</p>
<p>void g(int**p)<br />
{<br />
(**p)++;<br />
(*p)++;// 无效<br />
}<br />
输出：<br />
1<br />
2 <br />
3 <br />
4 <br />
5 <br />
6 <br />
7 <br />
8 <br />
9 <br />
10<br />
3. 写出程序运行结果</p>
<p>int sum(int a)<br />
{<br />
auto int c=0;<br />
static int b=3;<br />
c+=1;<br />
b+=2;<br />
return(a+b+c);<br />
}</p>
<p>void main()<br />
{<br />
int I;<br />
int a=2;<br />
for(I=0;I&lt;5;I++)<br />
{<br />
printf(&quot;%d,&quot;, sum(a));<br />
}<br />
}<br />
// static会保存上次结果，记住这一点，剩下的自己写<br />
输出：8,10,12,14,16,</p>
<p><br />
4.</p>
<p>int func(int a)<br />
{<br />
int b;<br />
switch(a)<br />
{<br />
case 1: 30;<br />
case 2: 20;<br />
case 3: 16;<br />
default: 0<br />
}<br />
return b;<br />
}<br />
则func(1)=?<br />
// b定义后就没有赋值。</p>
<p>5:<br />
int a[3];<br />
a[0]=0; a[1]=1; a[2]=2;<br />
int *p, *q;<br />
p=a;<br />
q=&amp;a[2];<br />
则a[q-p]=a[2]<br />
解释：指针一次移动一个int但计数为1</p>
<p>今天早上的面试题9道，比较难，向牛人请教，国内的一牛公司，坐落在北京北四环某大厦：<br />
1、线形表a、b为两个有序升序的线形表，编写一程序，使两个有序线形表合并成一个有序升序线形表h；<br />
答案在 请化大学 严锐敏《数据结构第二版》第二章例题，数据结构当中，这个叫做：两路归并排序<br />
Linklist *unio(Linklist *p,Linklist *q){<br />
linklist *R,*pa,*qa,*ra;<br />
pa=p;<br />
qa=q;<br />
R=ra=p;<br />
while(pa-&gt;next!=NULL&amp;&amp;qa-&gt;next!=NULL){<br />
if(pa-&gt;data&gt;qa-&gt;data){<br />
ra-&gt;next=qa;<br />
qa=qa-&gt;next;<br />
}<br />
else{<br />
ra-&gt;next=pa;<br />
pa=pa-&gt;next;<br />
}<br />
}<br />
if(pa-&gt;next!=NULL)<br />
ra-&gt;next=pa;<br />
if(qa-&gt;next!=NULL)<br />
ra-&gt;next==qa;<br />
return R;<br />
}<br />
2、运用四色定理，为N个局域举行配色，颜色为1、2、3、4四种，另有数组adj[][N]，如adj[i][j]=1则表示i区域与j区域相邻，数组color[N]，如color[i]=1,表示i区域的颜色为1号颜色。<br />
四色填充<br />
3、用递归算法判断数组a[N]是否为一个递增数组。<br />
递归的方法，记录当前最大的，并且判断当前的是否比这个还大，大则继续，否则返回false结束：<br />
bool fun( int a[], int n )<br />
{<br />
if( n= =1 )<br />
return true;<br />
if( n= =2 )<br />
return a[n-1] &gt;= a[n-2];<br />
return fun( a,n-1) &amp;&amp; ( a[n-1] &gt;= a[n-2] );<br />
}<br />
4、编写算法，从10亿个浮点数当中，选出其中最大的10000个。<br />
用外部排序，在《数据结构》书上有<br />
《计算方法导论》在找到第n大的数的算法上加工<br />
5、编写一unix程序，防止僵尸进程的出现.<br />
同学的4道面试题，应聘的职位是搜索引擎工程师，后两道超级难，（希望大家多给一些算发）<br />
1.给两个数组和他们的大小，还有一动态开辟的内存，求交集，把交集放到动态内存dongtai，并且返回交集个数<br />
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])<br />
2.单连表的建立，把'a'--'z'26个字母插入到连表中，并且倒叙，还要打印！<br />
方法1：<br />
typedef struct val<br />
{&nbsp;&nbsp; int date_1;<br />
&nbsp;&nbsp;&nbsp; struct val *next;<br />
}*p;</p>
<p>void main(void)<br />
{&nbsp;&nbsp; char c;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; for(c=122;c&gt;=97;c--)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { p.date=c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p=p-&gt;next;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; p.next=NULL;<br />
} <br />
}<br />
方法2：<br />
node *p = NULL;<br />
node *q = NULL;</p>
<p>node *head = (node*)malloc(sizeof(node));<br />
head-&gt;data = ' ';head-&gt;next=NULL;</p>
<p>node *first = (node*)malloc(sizeof(node));<br />
first-&gt;data = 'a';first-&gt;next=NULL;head-&gt;next = first;<br />
p = first;</p>
<p>int longth = 'z' - 'b';<br />
int i=0;<br />
while ( i&lt;=longth )<br />
{<br />
node *temp = (node*)malloc(sizeof(node));<br />
temp-&gt;data = 'b'+i;temp-&gt;next=NULL;q=temp;</p>
<p>head-&gt;next = temp; temp-&gt;next=p;p=q;<br />
i++;<br />
}</p>
<p>print(head);</p>
<p>3.可怕的题目终于来了<br />
象搜索的输入信息是一个字符串，统计300万输入信息中的最热门的前十条，我们每次输入的一个字符串为不超过255byte,内存使用只有1G,<br />
请描述思想，写出算发（c语言），空间和时间复杂度，<br />
4.国内的一些帖吧，如baidu,有几十万个主题，假设每一个主题都有上亿的跟帖子，怎么样设计这个系统速度最好，请描述思想，写出算发（c语言），空间和时间复杂度，</p>
<p><br />
#include&nbsp;&nbsp; string.h<br />
main(void)<br />
{&nbsp;&nbsp; char&nbsp;&nbsp; *src=&quot;hello,world&quot;;<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *dest=NULL;<br />
&nbsp;&nbsp;&nbsp; dest=(char&nbsp;&nbsp; *)malloc(strlen(src));<br />
&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; len=strlen(str);<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *d=dest;<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *s=src[len];<br />
&nbsp;&nbsp;&nbsp; while(len--!=0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d++=s--;<br />
&nbsp;&nbsp;&nbsp; printf(&quot;%s&quot;,dest);<br />
}<br />
找出错误！！<br />
#include&nbsp;&nbsp; &quot;string.h&quot;<br />
#include &quot;stdio.h&quot;<br />
#include &quot;malloc.h&quot;<br />
main(void)<br />
{&nbsp;&nbsp; <br />
char&nbsp;&nbsp; *src=&quot;hello,world&quot;;<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *dest=NULL;<br />
&nbsp;&nbsp;&nbsp; dest=(char&nbsp;&nbsp; *)malloc(sizeof(char)*(strlen(src)+1));<br />
&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp; len=strlen(src);<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *d=dest;<br />
&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp; *s=src+len-1;<br />
&nbsp;&nbsp;&nbsp; while(len--!=0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *d++=*s--;<br />
*d='\0';<br />
&nbsp;&nbsp;&nbsp; printf(&quot;%s&quot;,dest);<br />
}</p>
<p>1.&nbsp;&nbsp;&nbsp; 简述一个Linux驱动程序的主要流程与功能。</p>
<p>2.&nbsp;&nbsp;&nbsp; 请列举一个软件中时间换空间或者空间换时间的例子。<br />
void swap(int a,int b)<br />
{<br />
int c; c=a;a=b;b=a;<br />
}<br />
---&gt;空优 <br />
void swap(int a,int b)<br />
{<br />
a=a+b;b=a-b;a=a-b;<br />
}<br />
6.&nbsp;&nbsp;&nbsp; 请问一下程序将输出什么结果？<br />
char *RetMenory(void)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char p[] = &ldquo;hellow world&rdquo;;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return p;<br />
}<br />
void Test(void)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *str = NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str = RetMemory();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(str);<br />
}<br />
RetMenory执行完毕，p资源被回收，指向未知地址。返回地址，str的内容应是不可预测的, 打印的应该是str的地址</p>
<p><br />
写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)<br />
功能：<br />
在字符串中找出连续最长的数字串，并把这个串的长度返回，并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如：&quot;abcd12345ed125ss123456789&quot;的首地址传给intputstr后，函数将返回<br />
9，outputstr所指的值为123456789<br />
int continumax(char *outputstr, char *inputstr)<br />
{<br />
char *in = inputstr, *out = outputstr, *temp, *final;<br />
int count = 0, maxlen = 0;</p>
<p>while( *in != '\0' )<br />
{<br />
if( *in &gt; 47 &amp;&amp; *in &lt; 58 )<br />
{<br />
for(temp = in; *in &gt; 47 &amp;&amp; *in &lt; 58 ; in++ )<br />
count++;<br />
}<br />
else<br />
in++;</p>
<p>if( maxlen &lt; count )<br />
{<br />
maxlen = count;<br />
count = 0;<br />
final = temp;<br />
}<br />
}<br />
for(int i = 0; i &lt; maxlen; i++)<br />
{<br />
*out = *final;<br />
out++;<br />
final++;<br />
}<br />
*out = '\0';<br />
return maxlen;<br />
}</p>
<p>不用库函数,用C语言实现将一整型数字转化为字符串<br />
方法1：<br />
int getlen(char *s){<br />
&nbsp;&nbsp;&nbsp; int n;<br />
&nbsp;&nbsp;&nbsp; for(n = 0; *s != '\0'; s++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n++;<br />
&nbsp;&nbsp;&nbsp; return n;<br />
}<br />
void reverse(char s[])<br />
{<br />
&nbsp;&nbsp; int c,i,j;<br />
&nbsp;&nbsp; for(i = 0,j = getlen(s) - 1; i &lt; j; i++,j--){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = s[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s[i] = s[j];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s[j] = c;<br />
&nbsp;&nbsp; }<br />
}<br />
void itoa(int n,char s[])<br />
{<br />
&nbsp;&nbsp; int i,sign;<br />
&nbsp;&nbsp; if((sign = n) &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = -n;<br />
&nbsp;&nbsp; i = 0;<br />
&nbsp;&nbsp; do{/*以反序生成数字*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s[i++] = n%10 + '0';/*get next number*/<br />
&nbsp;&nbsp; }while((n /= 10) &gt; 0);/*delete the number*/</p>
<p>&nbsp;&nbsp; if(sign &lt; 0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s[i++] = '-';</p>
<p>&nbsp;&nbsp; s[i] = '\0';<br />
&nbsp;&nbsp; reverse(s);<br />
}<br />
方法2:<br />
#include &lt;iostream&gt;<br />
using namespace std;</p>
<p>void itochar(int num);</p>
<p>void itochar(int num)<br />
{<br />
int i = 0;<br />
int j ;<br />
char stra[10];<br />
char strb[10];<br />
while ( num )<br />
{<br />
stra[i++]=num%10+48;<br />
num=num/10;<br />
}<br />
stra[i] = '\0';<br />
for( j=0; j &lt; i; j++)<br />
{<br />
strb[j] = stra[i-j-1];<br />
}<br />
strb[j] = '\0';<br />
cout&lt;&lt;strb&lt;&lt;endl;</p>
<p>}<br />
int main()<br />
{<br />
int num;<br />
cin&gt;&gt;num;<br />
itochar(num);<br />
return 0;<br />
}</p>
<p>前几天面试，有一题想不明白,请教大家！<br />
&nbsp; typedef struct <br />
&nbsp; { <br />
&nbsp;&nbsp;&nbsp;&nbsp; int a:2;<br />
&nbsp;&nbsp;&nbsp;&nbsp; int b:2;<br />
&nbsp;&nbsp;&nbsp;&nbsp; int c:1;<br />
&nbsp; }test;</p>
<p>&nbsp; test t;<br />
&nbsp; t.a = 1;<br />
&nbsp; t.b = 3;<br />
&nbsp; t.c = 1;</p>
<p>&nbsp; printf(&quot;%d&quot;,t.a);<br />
&nbsp; printf(&quot;%d&quot;,t.b);<br />
&nbsp; printf(&quot;%d&quot;,t.c);</p>
<p>&nbsp; 谢谢!<br />
t.a为01,输出就是1<br />
t.b为11，输出就是－1<br />
t.c为1，输出也是-1<br />
3个都是有符号数int嘛。<br />
这是位扩展问题 <br />
01<br />
11<br />
1<br />
编译器进行符号扩展</p>
<p><br />
求组合数： 求n个数（1....n）中k个数的组合....<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如：combination(5,3)<br />
&nbsp; 要求输出：543，542，541，532，531，521，432，431，421，321，<br />
#include&lt;stdio.h&gt;</p>
<p>int pop(int *);<br />
int push(int );<br />
void combination(int ,int );</p>
<p>int stack[3]={0};<br />
top=-1;</p>
<p>int main()<br />
{<br />
int n,m;<br />
printf(&quot;Input two numbers:\n&quot;);<br />
while( (2!=scanf(&quot;%d%*c%d&quot;,&amp;n,&amp;m)) )<br />
{<br />
fflush(stdin);<br />
printf(&quot;Input error! Again:\n&quot;);<br />
}<br />
combination(n,m);<br />
printf(&quot;\n&quot;);<br />
}<br />
void combination(int m,int n)<br />
{<br />
int temp=m;<br />
push(temp);<br />
while(1)<br />
{<br />
if(1==temp)<br />
{<br />
if(pop(&amp;temp)&amp;&amp;stack[0]==n) //当栈底元素弹出&amp;&amp;为可能取的最小值，循环退出<br />
break;<br />
}<br />
else if( push(--temp))<br />
{<br />
printf(&quot;%d%d%d&nbsp; &quot;,stack[0],stack[1],stack[2]);//&sect;&amp;auml;&uml;&igrave;&curren;@?<br />
pop(&amp;temp);<br />
}<br />
}<br />
}<br />
int push(int i)<br />
{<br />
stack[++top]=i;<br />
if(top&lt;2)<br />
return 0;<br />
else<br />
return 1;<br />
}<br />
int pop(int *i)<br />
{<br />
*i=stack[top--];<br />
if(top&gt;=0)<br />
return 0;<br />
else<br />
return 1;<br />
}</p>
<p>1、用指针的方法，将字符串&ldquo;ABCD1234efgh&rdquo;前后对调显示<br />
#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;dos.h&gt;<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; char str[] = &quot;ABCD1234efgh&quot;;<br />
&nbsp;&nbsp;&nbsp; int length = strlen(str);<br />
&nbsp;&nbsp;&nbsp; char * p1 = str;<br />
&nbsp;&nbsp;&nbsp; char * p2 = str + length - 1;<br />
&nbsp;&nbsp;&nbsp; while(p1 &lt; p2)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char c = *p1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p1 = *p2;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *p2 = c;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++p1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --p2;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; printf(&quot;str now is %s\n&quot;,str);<br />
&nbsp;&nbsp;&nbsp; system(&quot;pause&quot;);<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}<br />
2、有一分数序列：1/2,1/4,1/6,1/8&hellip;&hellip;，用函数调用的方法，求此数列前20项的和<br />
#include &lt;stdio.h&gt;<br />
double getValue()<br />
{<br />
&nbsp;&nbsp;&nbsp; double result = 0;<br />
&nbsp;&nbsp;&nbsp; int i = 2;<br />
&nbsp;&nbsp;&nbsp; while(i &lt; 42)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result += 1.0 / i;//一定要使用1.0做除数，不能用1，否则结果将自动转化成整数，即0.000000<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i += 2;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return result;<br />
}<br />
int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; printf(&quot;result is %f\n&quot;, getValue());<br />
&nbsp;&nbsp;&nbsp; system(&quot;pause&quot;);<br />
&nbsp;&nbsp;&nbsp; return 0;<br />
}<br />
有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数，到末尾时循环至开头继续进行，求最后一个被删掉的数的原始下标位置。<br />
以7个数为例：<br />
&nbsp;&nbsp; {0,1,2,3,4,5,6,7} 0--&gt;1--&gt;2（删除）--&gt;3--&gt;4--&gt;5(删除)--&gt;6--&gt;7--&gt;0（删除），如此循环直到最后一个数被删除。<br />
方法1：数组<br />
#include &lt;iostream&gt;<br />
using namespace std;<br />
#define null 1000</p>
<p>int main()<br />
{<br />
int arr[1000];<br />
for (int i=0;i&lt;1000;++i)<br />
arr[i]=i;<br />
int j=0;<br />
int count=0;<br />
while(count&lt;999)<br />
{<br />
while(arr[j%1000]==null)<br />
j=(++j)%1000;<br />
j=(++j)%1000;<br />
while(arr[j%1000]==null)<br />
j=(++j)%1000;<br />
j=(++j)%1000;<br />
while(arr[j%1000]==null)<br />
j=(++j)%1000;<br />
arr[j]=null;<br />
++count;<br />
}<br />
while(arr[j]==null)<br />
j=(++j)%1000;</p>
<p>cout&lt;&lt;j&lt;&lt;endl;<br />
return 0;<br />
}方法2：链表<br />
#include&lt;iostream&gt;<br />
using namespace std;<br />
#define null 0<br />
struct node<br />
{<br />
int data;<br />
node* next;<br />
};<br />
int main()<br />
{<br />
node* head=new node;<br />
head-&gt;data=0;<br />
head-&gt;next=null;<br />
node* p=head;<br />
for(int i=1;i&lt;1000;i++)<br />
{<br />
node* tmp=new node;<br />
tmp-&gt;data=i;<br />
tmp-&gt;next=null;<br />
head-&gt;next=tmp;<br />
head=head-&gt;next;<br />
}<br />
head-&gt;next=p;<br />
while(p!=p-&gt;next)<br />
{<br />
p-&gt;next-&gt;next=p-&gt;next-&gt;next-&gt;next;<br />
p=p-&gt;next-&gt;next;<br />
}<br />
cout&lt;&lt;p-&gt;data;<br />
return 0;<br />
}<br />
方法3：通用算法<br />
#include &lt;stdio.h&gt;<br />
#define MAXLINE 1000&nbsp;&nbsp; //元素个数<br />
/*<br />
MAXLINE&nbsp;&nbsp; 元素个数<br />
a[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 元素数组<br />
R[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 指针场<br />
suffix&nbsp;&nbsp;&nbsp; 下标<br />
index&nbsp;&nbsp;&nbsp;&nbsp; 返回最后的下标序号<br />
values&nbsp;&nbsp;&nbsp; 返回最后的下标对应的值<br />
start&nbsp;&nbsp;&nbsp;&nbsp; 从第几个开始<br />
K&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 间隔<br />
*/<br />
int find_n(int a[],int R[],int K,int&amp; index,int&amp; values,int s=0) {<br />
&nbsp;&nbsp; int suffix;<br />
&nbsp;&nbsp; int front_node,current_node;<br />
&nbsp;&nbsp; suffix=0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(s==0) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_node=0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; front_node=MAXLINE-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_node=s;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; front_node=s-1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(R[front_node]!=front_node) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf(&quot;%d\n&quot;,a[current_node]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; R[front_node]=R[current_node];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(K==1) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_node=R[front_node];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;K;i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; front_node=R[front_node];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; current_node=R[front_node];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;index=front_node;<br />
&nbsp;values=a[front_node];</p>
<p>&nbsp;return 0;<br />
}<br />
int main(void) {<br />
int a[MAXLINE],R[MAXLINE],suffix,index,values,start,i,K;<br />
suffix=index=values=start=0;<br />
K=2;</p>
<p>for(i=0;i&lt;MAXLINE;i++) {<br />
a[i]=i;<br />
R[i]=i+1;<br />
}<br />
R[i-1]=0;<br />
find_n(a,R,K,index,values,2);<br />
printf(&quot;the value is %d,%d\n&quot;,index,values);<br />
return 0;<br />
}</p>
<p>试题： <br />
void test2() <br />
{ <br />
&nbsp;&nbsp; char string[10], str1[10]; <br />
&nbsp;&nbsp; int i; <br />
&nbsp;&nbsp; for(i=0; i&lt;10; i++) <br />
&nbsp;&nbsp; { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str1[i] = 'a'; <br />
&nbsp;&nbsp; } <br />
&nbsp;&nbsp; strcpy( string, str1 ); <br />
} <br />
解答：对试题2，如果面试者指出字符数组str1不能在数组内结束可以给3分；如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分，在此基础上指出库函数strcpy工作方式的给10分；<br />
str1不能在数组内结束:因为str1的存储为：{a,a,a,a,a,a,a,a,a,a},没有'\0'(字符串结束符)，所以不能结束<br />
strcpy( char *s1,char *s2)他的工作原理是，扫描s2指向的内存，逐个字符付到s1所指向的内存，直到碰到'\0',因为str1结尾没有'\0'，所以具有不确定性，不知道他后面还会付什么东东。<br />
正确应如下<br />
void test2() <br />
{ <br />
&nbsp;&nbsp; char string[10], str1[10]; <br />
&nbsp;&nbsp; int i; <br />
&nbsp;&nbsp; for(i=0; i&lt;9; i++) <br />
&nbsp;&nbsp; { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str1[i] = 'a'+i; //把abcdefghi赋值给字符数组<br />
&nbsp;&nbsp; } <br />
&nbsp;&nbsp; str[i]='\0';//加上结束符<br />
&nbsp;&nbsp; strcpy( string, str1 ); <br />
}</p>
<p>第二个code题是实现strcmp<br />
int StrCmp(const char *str1, const char *str2)<br />
做是做对了，没有抄搞，比较乱<br />
int StrCmp(const char *str1, const char *str2)<br />
{<br />
&nbsp;&nbsp;&nbsp; assert(str1 &amp;&amp; srt2);<br />
&nbsp;&nbsp;&nbsp; while (*str1 &amp;&amp; *str2 &amp;&amp; *str1 == *str2) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str1++, str2++;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; if (*str1 &amp;&amp; *str2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (*str1-*str2);<br />
&nbsp;&nbsp;&nbsp; elseif (*str1 &amp;&amp; *str2==0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1;<br />
&nbsp;&nbsp;&nbsp; elseif (*str1 = = 0 &amp;&amp; *str2)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1;<br />
&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p>int StrCmp(const char *str1, const char *str2)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //省略判断空指针(自己保证)<br />
while(*str1 &amp;&amp; *str1++ = = *str2++);<br />
return *str1-*str2; <br />
}<br />
第三个code题是实现子串定位<br />
int FindSubStr(const char *MainStr, const char *SubStr)<br />
做是做对了，没有抄搞，比较乱<br />
int MyStrstr(const char* MainStr, const char* SubStr)<br />
{<br />
const char *p;<br />
const char *q;<br />
const char * u = MainStr;<br />
&nbsp;&nbsp;&nbsp; <br />
//assert((MainStr!=NULL)&amp;&amp;( SubStr!=NULL));//用断言对输入进行判断<br />
while(*MainStr) //内部进行递增<br />
{<br />
p = MainStr;<br />
q = SubStr;<br />
while(*q &amp;&amp; *p &amp;&amp; *p++ == *q++);<br />
if(!*q )<br />
{<br />
return MainStr - u +1 ;//MainStr指向当前起始位，u指向<br />
}<br />
MainStr ++;<br />
}<br />
return -1;<br />
}</p>
<p>分析：<br />
int arr[] = {6,7,8,9,10};<br />
int *ptr = arr;<br />
*(ptr++)+=123;<br />
printf(&ldquo; %d %d &rdquo;, *ptr, *(++ptr));<br />
输出：8 8<br />
过程：对于*(ptr++)+=123;先做加法6+123，然后++，指针指向7；对于printf(&ldquo; %d %d &rdquo;, *ptr, *(++ptr));从后往前执行，指针先++，指向8，然后输出8，紧接着再输出8</p>
<p>华为全套完整试题<br />
高级题<br />
6、已知一个单向链表的头，请写出删除其某一个结点的算法，要求，先找到此结点，然后删除。<br />
slnodetype *Delete(slnodetype *Head,int key){}中if(Head-&gt;number==key)<br />
{<br />
Head=Pointer-&gt;next;<br />
free(Pointer);<br />
break;<br />
}<br />
Back = Pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pointer=Pointer-&gt;next;<br />
if(Pointer-&gt;number==key)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Back-&gt;next=Pointer-&gt;next;<br />
free(Pointer);<br />
break;<br />
}<br />
void delete(Node* p)<br />
{<br />
&nbsp;&nbsp;&nbsp; if(Head = Node)</p>
<p>&nbsp;&nbsp;&nbsp; while(p)<br />
}</p>
<p>有一个16位的整数，每4位为一个数，写函数求他们的和。<br />
解释：<br />
整数1101010110110111<br />
和&nbsp; 1101+0101+1011+0111<br />
感觉应该不难，当时对题理解的不是很清楚，所以写了一个函数，也不知道对不对。<br />
疑问：<br />
&nbsp;&nbsp;&nbsp; 既然是16位的整数，1101010110110111是2进制的，那么函数参数怎么定义呢，请指教。<br />
答案：用十进制做参数，计算时按二进制考虑。<br />
/* n就是16位的数，函数返回它的四个部分之和 */<br />
char SumOfQuaters(unsigned short n)<br />
{<br />
&nbsp;&nbsp;&nbsp; char c = 0;<br />
&nbsp;&nbsp;&nbsp; int i = 4;<br />
&nbsp;&nbsp;&nbsp; do<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c += n &amp; 15;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = n &gt;&gt; 4;<br />
&nbsp;&nbsp;&nbsp; } while (--i);</p>
<p>&nbsp;&nbsp;&nbsp; return c;<br />
}</p>
<p>&nbsp;</p>
<p>有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.（华为）<br />
#include&lt;iostream.h&gt;</p>
<p>int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; int a[]&nbsp; = {10,6,9,5,2,8,4,7,1,3};<br />
&nbsp;&nbsp;&nbsp; int len = sizeof(a) / sizeof(int);<br />
&nbsp;&nbsp;&nbsp; int temp;</p>
<p>&nbsp;&nbsp;&nbsp; for(int i = 0; i &lt; len; )<br />
&nbsp;&nbsp;&nbsp; {<br />
temp = a[a[i] - 1];<br />
a[a[i] - 1] = a[i];<br />
a[i] = temp;</p>
<p>if ( a[i] == i + 1)<br />
&nbsp; i++;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; len; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt;&lt;a[j]&lt;&lt;&quot;,&quot;;</p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br />
}</p>
<p>（慧通）<br />
1 写出程序把一个链表中的接点顺序倒排<br />
typedef struct linknode<br />
{<br />
int data;<br />
struct linknode *next;<br />
}node;<br />
//将一个链表逆置<br />
node *reverse(node *head)<br />
{<br />
node *p,*q,*r;<br />
p=head;<br />
q=p-&gt;next;<br />
while(q!=NULL)<br />
{<br />
r=q-&gt;next;<br />
q-&gt;next=p;<br />
p=q;<br />
q=r;<br />
}</p>
<p>head-&gt;next=NULL;<br />
head=p;<br />
return head;<br />
}<br />
2 写出程序删除链表中的所有接点<br />
void del_all(node *head)<br />
{<br />
node *p;<br />
while(head!=NULL)<br />
{<br />
p=head-&gt;next;<br />
free(head);<br />
head=p;<br />
}<br />
cout&lt;&lt;&quot;释放空间成功!&quot;&lt;&lt;endl;<br />
}<br />
3两个字符串，s,t;把t字符串插入到s字符串中，s字符串有足够的空间存放t字符串<br />
void insert(char *s, char *t, int i)<br />
{<br />
char *q = t;<br />
char *p =s;<br />
if(q == NULL)return;<br />
while(*p!='\0')<br />
{<br />
p++;<br />
}<br />
while(*q!=0)<br />
{<br />
*p=*q;<br />
p++;<br />
q++;<br />
}<br />
*p = '\0';<br />
}</p>
<p><br />
分析下面的代码：<br />
char *a = &quot;hello&quot;;<br />
char *b = &quot;hello&quot;;<br />
if(a= =b)<br />
printf(&quot;YES&quot;);<br />
else<br />
printf(&quot;NO&quot;);<br />
这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO<br />
lz的呢，是一个常量字符串。位于静态存储区，它在程序生命期内恒定不变。如果编译器优化的话，会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化，那么就是两个不同的地址，则不同</p>
          <br/>
          <span style="color:red;">
            <a href="http://younker.javaeye.com/blog/139293#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 08 Nov 2007 18:55:12 +0800</pubDate>
        <link>http://younker.javaeye.com/blog/139293</link>
        <guid>http://younker.javaeye.com/blog/139293</guid>
      </item>
      <item>
        <title>C++笔试题</title>
        <author>younker</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://younker.javaeye.com">younker</a>&nbsp;
          链接：<a href="http://younker.javaeye.com/blog/139067" style="color:red;">http://younker.javaeye.com/blog/139067</a>&nbsp;
          发表时间: 2007年11月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          所有资源都来源于Internet..........，很多的问题答案给得太死，实际上可以有多种答案，有的非让你说出来2条<br />
可能说起来一条就能够表达的很清楚了，贴这些考试题目的目的是&ldquo;温故而知新！！&rdquo;<br />
<br />
文章来源于：<a href="http://www.itquan.com/user1/2059/subject/163.html">http://www.itquan.com/user1/2059/subject/163.html</a><br />
<span class="oblog_text">
<p>发布之前先申明两点：<br />
&nbsp;&nbsp;&nbsp; 1 所有资料来自网络(主要是CSDN)，本人只是收集和转发。<br />
&nbsp;&nbsp;&nbsp; 2 所有问题解答(尤其是代码)只是参考，不保证正确。</p>
<p>先发基本问题，再发编程问题..........<br />
4.&nbsp;&nbsp;&nbsp; static有什么用途？（请至少说明两种）<br />
1.限制变量的作用域<br />
2.设置变量的存储域<br />
7.&nbsp;&nbsp;&nbsp; 引用与指针有什么区别？<br />
1) 引用必须被初始化，指针不必。<br />
2) 引用初始化以后不能被改变，指针可以改变所指的对象。<br />
2) 不存在指向空值的引用，但是存在指向空值的指针。</p>
<p>8.&nbsp;&nbsp;&nbsp; 描述实时系统的基本特性<br />
在特定时间内完成特定的任务，实时性与可靠性<br />
9.&nbsp;&nbsp;&nbsp; 全局变量和局部变量在内存中是否有区别？如果有，是什么区别？<br />
全局变量储存在静态数据库，局部变量在堆栈<br />
10.&nbsp;&nbsp; 什么是平衡二叉树？<br />
左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1<br />
11.&nbsp;&nbsp; 堆栈溢出一般是由什么原因导致的？<br />
没有回收垃圾资源<br />
12.&nbsp;&nbsp; 什么函数不能声明为虚函数？<br />
constructor<br />
13.&nbsp;&nbsp; 冒泡排序算法的时间复杂度是什么？<br />
O(n^2)<br />
14.&nbsp;&nbsp; 写出float x 与&ldquo;零值&rdquo;比较的if语句。<br />
if(x&gt;0.000001&amp;&amp;x&lt;-0.000001)<br />
16.&nbsp;&nbsp; Internet采用哪种网络协议？该协议的主要层次结构？<br />
tcp/ip 应用层/传输层/网络层/数据链路层/物理层<br />
17.&nbsp;&nbsp; Internet物理地址和IP地址转换采用什么协议？<br />
ARP (Address Resolution Protocol)（地址解析協議）<br />
18.IP地址的编码分为哪俩部分？<br />
IP地址由两部分组成，网络号和主机号。不过是要和&ldquo;子网掩码&rdquo;按位与上之后才能区分哪些是网络位哪些是主机位。</p>
<p><br />
2.用户输入M,N值，从1至N开始顺序循环数数，每数到M输出该数值，直至全部输出。写出C程序。<br />
循环链表，用取余操作做<br />
3.不能做switch()的参数类型是：<br />
switch的参数不能为实型。<br />
===========================================================================<br />
<span class="oblog_text">&nbsp;</span></p>
<p>華為<br />
1、局部变量能否和全局变量重名？<br />
答：能，局部会屏蔽全局。要用全局变量，需要使用&quot;::&quot;<br />
局部变量可以与全局变量同名，在函数内引用这个变量时，会用到同名的局部变量，而不会用到全局变量。对于有些编译器而言，在同一个函数内可以定义多个同名的局部变量，比如在两个循环体内都定义一个同名的局部变量，而那个局部变量的作用域就在那个循环体内<br />
2、如何引用一个已经定义过的全局变量？<br />
答：extern<br />
可以用引用头文件的方式，也可以用extern关键字，如果用引用头文件方式来引用某个在头文件中声明的全局变理，假定你将那个变写错了，那么在编译期间会报错，如果你用extern方式引用时，假定你犯了同样的错误，那么在编译期间不会报错，而在连接期间报错<br />
3、全局变量可不可以定义在可被多个.C文件包含的头文件中？为什么？<br />
答：可以，在不同的C文件中以static形式来声明同名全局变量。<br />
可以在不同的C文件中声明同名的全局变量，前提是其中只能有一个C文件中对此变量赋初值，此时连接不会出错<br />
4、语句for( ；1 ；)有什么问题？它是什么意思？<br />
答：和while(1)相同。<br />
5、do&hellip;&hellip;while和while&hellip;&hellip;do有什么区别？<br />
答：前一个循环一遍再判断，后一个判断以后再循环<br />
6、请写出下列代码的输出内容<br />
＃i nclude<stdio.h></stdio.h><br />
main()<br />
{<br />
int a,b,c,d;<br />
a=10;<br />
b=a++;<br />
c=++a;<br />
d=10*a++;<br />
printf(&quot;b，c，d：%d，%d，%d&quot;，b，c，d）;<br />
return 0;<br />
} <br />
答：10，12，120</p>
<p>1、static全局变量与普通的全局变量有什么区别？static局部变量和普通局部变量有什么区别？static函数与普通函数有什么区别？<br />
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式， 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序， 当一个源程序由多个源文件组成时，非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域， 即只在定义该变量的源文件内有效， 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内，只能为该源文件内的函数公用， 因此可以避免在其它源文件中引起错误。<br />
从以上分析可以看出， 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域， 限制了它的使用范围。<br />
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)，内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数，应该在一个头文件中说明，要使用这些函数的源文件要包含这个头文件</p>
<p>static全局变量与普通的全局变量有什么区别：static全局变量只初使化一次，防止在其他文件单元中被引用;<br />
static局部变量和普通局部变量有什么区别：static局部变量只被初始化一次，下一次依据上一次结果值；<br />
static函数与普通函数有什么区别：static函数在内存中只有一份，普通函数在每个被调用中维持一份拷贝<br />
2、程序的局部变量存在于（堆栈）中，全局变量存在于（静态区 ）中，动态申请数据存在于（ 堆）中。<br />
3、设有以下说明和定义：<br />
typedef union {long i; int k[5]; char c;} DATE;<br />
struct data { int cat; DATE cow; double dog;} too;<br />
DATE max;<br />
则语句 printf(&quot;%d&quot;,sizeof(struct date)+sizeof(max));的执行结果是：___52____<br />
答：DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20<br />
data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32.<br />
所以结果是 20 + 32 = 52.<br />
当然...在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20<br />
4、队列和栈有什么区别？<br />
队列先进先出，栈后进先出<br />
5、写出下列代码的输出内容<br />
＃i nclude<stdio.h></stdio.h><br />
int inc(int a)<br />
{<br />
return(++a);<br />
}<br />
int multi(int*a,int*b,int*c)<br />
{<br />
return(*c=*a**b);<br />
}<br />
typedef int(FUNC1)(int in);<br />
typedef int(FUNC2) (int*,int*,int*);</p>
<p>void show(FUNC2 fun,int arg1, int*arg2)<br />
{<br />
INCp=&amp;inc;<br />
int temp =p(arg1);<br />
fun(&amp;temp,&amp;arg1, arg2);<br />
printf(&quot;%d\n&quot;,*arg2);<br />
}</p>
<p>main()<br />
{<br />
int a;<br />
show(multi,10,&amp;a);<br />
return 0;<br />
}<br />
答：110<br />
7、请找出下面代码中的所以错误<br />
说明：以下代码是把一个字符串倒序，如&ldquo;abcd&rdquo;倒序后变为&ldquo;dcba&rdquo;</p>
<p>1、＃i nclude&quot;string.h&quot;<br />
2、main()<br />
3、{<br />
4、 char*src=&quot;hello,world&quot;;<br />
5、 char* dest=NULL;<br />
6、 int len=strlen(src);<br />
7、 dest=(char*)malloc(len);<br />
8、 char* d=dest;<br />
9、 char* s=src[len];<br />
10、 while(len--!=0) <br />
11、 d++=s--;<br />
12、 printf(&quot;%s&quot;,dest);<br />
13、 return 0;<br />
14、} <br />
答：<br />
方法1：<br />
int main(){<br />
char* src = &quot;hello,world&quot;;<br />
int len = strlen(src);<br />
char* dest = (char*)malloc(len+1);//要为\0分配一个空间<br />
char* d = dest;<br />
char* s = &amp;src[len-1];//指向最后一个字符<br />
while( len-- != 0 )<br />
*d++=*s--;<br />
*d = 0;//尾部要加\0<br />
printf(&quot;%s\n&quot;,dest);<br />
free(dest);// 使用完，应当释放空间，以免造成内存汇泄露<br />
return 0;<br />
}<br />
方法2：<br />
＃i nclude <stdio.h></stdio.h><br />
＃i nclude <string.h></string.h><br />
main()<br />
{<br />
char str[]=&quot;hello,world&quot;;<br />
int len=strlen(str);<br />
char t;<br />
for(int i=0; i<len></len> {<br />
t=str[i]; <br />
str[i]=str[len-i-1]; str[len-i-1]=t;<br />
}<br />
printf(&quot;%s&quot;,str);<br />
return 0;<br />
}<br />
1.-1,2,7,28,,126请问28和126中间那个数是什么？为什么？<br />
第一题的答案应该是4^3-1=63<br />
规律是n^3-1(当n为偶数0，2，4)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n^3+1(当n为奇数1，3，5)<br />
答案：63<br />
2.用两个栈实现一个队列的功能？要求给出算法和思路！<br />
设2个栈为A,B, 一开始均为空.</p>
<p>入队:<br />
将新元素push入栈A;</p>
<p>出队:<br />
(1)判断栈B是否为空；<br />
(2)如果不为空，则将栈A中所有元素依次pop出并push到栈B；<br />
(3)将栈B的栈顶元素pop出；</p>
<p>这样实现的队列入队和出队的平摊复杂度都还是O(1), 比上面的几种方法要好。3.在c语言库函数中将一个字符转换成整型的函数是atool()吗，这个函数的原型是什么？<br />
函数名: atol <br />
功 能: 把字符串转换成长整型数 <br />
用 法: long atol(const char *nptr); <br />
程序例: <br />
＃i nclude <stdlib.h></stdlib.h><br />
＃i nclude <stdio.h></stdio.h><br />
int main(void) <br />
{ <br />
long l; <br />
char *str = &quot;98765432&quot;; </p>
<p>l = atol(lstr); <br />
printf(&quot;string = %s integer = %ld\n&quot;, str, l); <br />
return(0); <br />
}<br />
2.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?<br />
c用宏定义，c++用inline<br />
&nbsp; 3.直接链接两个信令点的一组链路称作什么?<br />
PPP点到点连接<br />
&nbsp; 4.接入网用的是什么接口?<br />
&nbsp; 5.voip都用了那些协议?<br />
&nbsp; 6.软件测试都有那些种类?<br />
黑盒：针对系统功能的测试&nbsp;&nbsp;&nbsp; 白合：测试函数功能，各函数接口<br />
&nbsp; 7.确定模块的功能和模块的接口是在软件设计的那个队段完成的?<br />
概要设计阶段<br />
&nbsp; 8.enum string<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp; x1,<br />
&nbsp;&nbsp;&nbsp; x2,<br />
&nbsp;&nbsp;&nbsp; x3=10,<br />
&nbsp;&nbsp;&nbsp; x4,<br />
&nbsp;&nbsp;&nbsp; x5,<br />
&nbsp;&nbsp;&nbsp; }x;<br />
&nbsp;&nbsp; 问x= 0x801005，0x8010f4&nbsp; ;<br />
&nbsp; 9.unsigned char *p1;<br />
&nbsp;&nbsp;&nbsp; unsigned long *p2;<br />
&nbsp;&nbsp;&nbsp; p1=(unsigned char *)0x801000;<br />
&nbsp;&nbsp;&nbsp; p2=(unsigned long *)0x810000;<br />
&nbsp;&nbsp;&nbsp; 请问p1+5=&nbsp; ;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p2+5=&nbsp; ;<br />
三.选择题:<br />
&nbsp; 1.Ethternet链接到Internet用到以下那个协议?<br />
&nbsp; A.HDLC;B.ARP;C.UDP;D.TCP;E.ID<br />
&nbsp; 2.属于网络层协议的是:<br />
&nbsp; A.TCP;B.IP;C.ICMP;D.X.25<br />
&nbsp; 3.Windows消息调度机制是:<br />
&nbsp; A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;<br />
&nbsp; 4.unsigned short hash(unsigned short key)<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (key&gt;&gt;)%256<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; 请问hash(16),hash(256)的值分别是:<br />
&nbsp; A.1.16;B.8.32;C.4.16;D.1.32<br />
四.找错题:<br />
&nbsp; 1.请问下面程序有什么错误?<br />
&nbsp;&nbsp; int a[60][250][1000],i,j,k;<br />
&nbsp;&nbsp; for(k=0;k&lt;=1000;k++)<br />
&nbsp;&nbsp;&nbsp; for(j=0;j&lt;250;j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp; for(i=0;i&lt;60;i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a[i][j][k]=0;<br />
把循环语句内外换一下<br />
&nbsp; 2.#define Max_CB 500<br />
&nbsp;&nbsp;&nbsp; void LmiQueryCSmd(Struct MSgCB * pmsg)<br />
&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp; unsigned char ucCmdNum;<br />
&nbsp;&nbsp;&nbsp;&nbsp; ......<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; for(ucCmdNum=0;ucCmdNum &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
死循环<br />
&nbsp;&nbsp; 3.以下是求一个数的平方的程序,请找出错误:<br />
&nbsp;&nbsp;&nbsp; #define SQUARE(a)((a)*(a))<br />
&nbsp;&nbsp;&nbsp; int a=5;<br />
&nbsp;&nbsp;&nbsp; int b;<br />
&nbsp;&nbsp;&nbsp; b=SQUARE(a++);<br />
&nbsp;&nbsp; 4.typedef unsigned char BYTE<br />
&nbsp;&nbsp;&nbsp;&nbsp; int examply_fun(BYTE gt_len; BYTE *gt_code)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BYTE *gt_buf;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gt_buf=(BYTE *)MALLOC(Max_GT_Length);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(gt_len&gt;Max_GT_Length)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return GT_Length_ERROR;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .......<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
五.问答题:<br />
&nbsp;&nbsp; 1.IP Phone的原理是什么?<br />
IPV6<br />
&nbsp;&nbsp; 2.TCP/IP通信建立的过程怎样，端口有什么作用？<br />
三次握手，确定是哪个应用程序使用该协议<br />
&nbsp;&nbsp; 3.1号信令和7号信令有什么区别，我国某前广泛使用的是那一种？<br />
&nbsp;&nbsp; 4.列举5种以上的电话新业务？</p>
<p><br />
高级题</p>
<p><br />
6、已知一个单向链表的头，请写出删除其某一个结点的算法，要求，先找到此结点，然后删除。<br />
slnodetype *Delete(slnodetype *Head,int key){}中if(Head-&gt;number==key)<br />
{<br />
Head=Pointer-&gt;next;<br />
free(Pointer);<br />
break;<br />
}<br />
Back = Pointer;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Pointer=Pointer-&gt;next;<br />
if(Pointer-&gt;number==key)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Back-&gt;next=Pointer-&gt;next;<br />
free(Pointer);<br />
break;<br />
}<br />
void delete(Node* p)<br />
{<br />
&nbsp;&nbsp;&nbsp; if(Head = Node)</p>
<p>&nbsp;&nbsp;&nbsp; while(p)<br />
}</p>
<p>有一个16位的整数，每4位为一个数，写函数求他们的和。<br />
解释：<br />
整数1101010110110111<br />
和&nbsp; 1101+0101+1011+0111<br />
感觉应该不难，当时对题理解的不是很清楚，所以写了一个函数，也不知道对不对。<br />
疑问：<br />
&nbsp;&nbsp;&nbsp; 既然是16位的整数，1101010110110111是2进制的，那么函数参数怎么定义呢，请指教。<br />
答案：用十进制做参数，计算时按二进制考虑。<br />
/* n就是16位的数，函数返回它的四个部分之和 */<br />
char SumOfQuaters(unsigned short n)<br />
{<br />
&nbsp;&nbsp;&nbsp; char c = 0;<br />
&nbsp;&nbsp;&nbsp; int i = 4;<br />
&nbsp;&nbsp;&nbsp; do<br />
&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c += n &amp; 15;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n = n &gt;&gt; 4;<br />
&nbsp;&nbsp;&nbsp; } while (--i);</p>
<p>&nbsp;&nbsp;&nbsp; return c;<br />
}</p>
<p>&nbsp;</p>
<p>有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.（华为）<br />
＃i nclude<iostream.h></iostream.h></p>
<p>int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; int a[]&nbsp; = {10,6,9,5,2,8,4,7,1,3};<br />
&nbsp;&nbsp;&nbsp; int len = sizeof(a) / sizeof(int);<br />
&nbsp;&nbsp;&nbsp; int temp;</p>
<p>&nbsp;&nbsp;&nbsp; for(int i = 0; i &lt; len; )<br />
&nbsp;&nbsp;&nbsp; {<br />
temp = a[a[i] - 1];<br />
a[a[i] - 1] = a[i];<br />
a[i] = temp;</p>
<p>if ( a[i] == i + 1)<br />
&nbsp; i++;<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; for (int j = 0; j &lt; len; j++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&lt; </p>
<p>&nbsp;&nbsp;&nbsp; return 0;<br />
}<br />
华为面试题：怎么判断链表中是否有环？<br />
bool CircleInList(Link* pHead)<br />
{<br />
if(pHead = = NULL || pHead-&gt;next = = NULL)//无节点或只有一个节点并且无自环<br />
return (false);<br />
if(pHead-&gt;next = = pHead)//自环<br />
return (true);<br />
Link *pTemp1 = pHead;//step 1<br />
Link *pTemp = pHead-&gt;next;//step 2<br />
while(pTemp != pTemp1 &amp;&amp; pTemp != NULL &amp;&amp; pTemp-&gt;next != NULL)<br />
{<br />
pTemp1 = pTemp1-&gt;next;<br />
pTemp = pTemp-&gt;next-&gt;next;<br />
}<br />
if(pTemp = = pTemp1)<br />
return (true);<br />
return (false);<br />
}</p>
<p>两个字符串，s,t;把t字符串插入到s字符串中，s字符串有足够的空间存放t字符串<br />
void insert(char *s, char *t, int i)<br />
{<br />
memcpy(&amp;s[strlen(t)+i],&amp;s[i],strlen(s)-i);<br />
memcpy(&amp;s[i],t,strlen(t));<br />
s[strlen(s)+strlen(t)]='\0';<br />
}</p>
<p>1。编写一个 C 函数，该函数在一个字符串中找到可能的最长的子字符串，且该字符串是由同一字符组成的。<br />
char * search(char *cpSource, char ch)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *cpTemp=NULL, *cpDest=NULL;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int iTemp, iCount=0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(*cpSource)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(*cpSource == ch)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iTemp = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cpTemp = cpSource;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(*cpSource == ch) <br />
++iTemp, ++cpSource;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(iTemp &gt; iCount) <br />
iCount = iTemp, cpDest = cpTemp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!*cpSource) <br />
break;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++cpSource;<br />
&nbsp;}<br />
&nbsp;return cpDest;<br />
}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
2。请编写一个 C 函数，该函数在给定的内存区域搜索给定的字符，并返回该字符所在位置索引值。<br />
int search(char *cpSource, int n, char ch)<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i=0; i<n></n> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return i;<br />
}</p>
<p>一个单向链表，不知道头节点,一个指针指向其中的一个节点，问如何删除这个指针指向的节点？<br />
将这个指针指向的next节点值copy到本节点，将next指向next-&gt;next,并随后删除原next指向的节点。</p>
<p><br />
＃i nclude <stdio.h></stdio.h><br />
void foo(int m, int n)<br />
{<br />
&nbsp;&nbsp;&nbsp; printf(&quot;m=%d, n=%d\n&quot;, m, n);<br />
}</p>
<p>int main()<br />
{<br />
&nbsp;&nbsp;&nbsp; int b = 3;<br />
&nbsp;&nbsp;&nbsp; foo(b+=3, ++b);<br />
&nbsp;&nbsp;&nbsp; printf(&quot;b=%d\n&quot;, b);<br />
return 0;<br />
}<br />
输出：m=7,n=4,b=7(VC6.0)<br />
这种方式和编译器中得函数调用关系相关即先后入栈顺序。不过不同<br />
编译器得处理不同。也是因为C标准中对这种方式说明为未定义，所以<br />
各个编译器厂商都有自己得理解，所以最后产生得结果完全不同。<br />
因为这样，所以遇见这种函数，我们首先要考虑我们得编译器会如何处理<br />
这样得函数，其次看函数得调用方式，不同得调用方式，可能产生不同得<br />
结果。最后是看编译器优化。</p>
<p><br />
2.写一函数，实现删除字符串str1中含有的字符串str2.<br />
第二个就是利用一个KMP匹配算法找到str2然后删除（用链表实现的话，便捷于数组）<br />
==============================================================================<br />
<span class="oblog_text">&nbsp;</span></p>
<p>微软亚洲技术中心的面试题！！！<br />
1．进程和线程的差别。<br />
线程是指进程内的一个执行单元,也是进程内的可调度实体.<br />
与进程的区别:<br />
(1)调度：线程作为调度和分配的基本单位，进程作为拥有资源的基本单位<br />
(2)并发性：不仅进程之间可以并发执行，同一个进程的多个线程之间也可并发执行<br />
(3)拥有资源：进程是拥有资源的一个独立单位，线程不拥有系统资源，但可以访问隶属于进程的资源. <br />
(4)系统开销：在创建或撤消进程时，由于系统都要为之分配和回收资源，导致系统的开销明显大于创建或撤消线程时的开销。<br />
2.测试方法 <br />
人工测试：个人复查、抽查和会审<br />
机器测试：黑盒测试和白盒测试</p>
<p>2．Heap与stack的差别。<br />
Heap是堆，stack是栈。<br />
Stack的空间由操作系统自动分配/释放，Heap上的空间手动分配/释放。<br />
Stack空间有限，Heap是很大的自由存储区<br />
C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。<br />
程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行<br />
3．Windows下的内存是如何管理的？<br />
4．介绍.Net和.Net的安全性。<br />
5．客户端如何访问.Net组件实现Web Service？<br />
6．C/C++编译器中虚表是如何完成的？<br />
7．谈谈COM的线程模型。然后讨论进程内/外组件的差别。<br />
8．谈谈IA32下的分页机制<br />
小页(4K)两级分页模式，大页(4M)一级<br />
9．给两个变量，如何找出一个带环单链表中是什么地方出现环的？<br />
一个递增一，一个递增二，他们指向同一个接点时就是环出现的地方<br />
10．在IA32中一共有多少种办法从用户态跳到内核态？<br />
通过调用门，从ring3到ring0，中断从ring3到ring0，进入vm86等等<br />
11．如果只想让程序有一个实例运行，不能运行两个。像winamp一样，只能开一个窗口，怎样实现？<br />
用内存映射或全局原子（互斥变量）、查找窗口句柄.. <br />
FindWindow，互斥，写标志到文件或注册表,共享内存。.　&nbsp; <br />
12．如何截取键盘的响应，让所有的&lsquo;a&rsquo;变成&lsquo;b&rsquo;？<br />
键盘钩子SetWindowsHookEx<br />
　13．Apartment在COM中有什么用？为什么要引入？<br />
　14．存储过程是什么？有什么用？有什么优点？<br />
我的理解就是一堆sql的集合，可以建立非常复杂的查询，编译运行，所以运行一次后，以后再运行速度比单独执行SQL快很多<br />
　15．Template有什么特点？什么时候用？<br />
16．谈谈Windows DNA结构的特点和优点。</p>
<p><br />
网络编程中设计并发服务器，使用多进程 与 多线程 ，请问有什么区别？<br />
1，进程：子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。<br />
2，线程：相对与进程而言，线程是一个更加接近与执行体的概念，它可以与同进程的其他线程共享数据，但拥有自己的栈空间，拥有独立的执行序列。<br />
两者都可以提高程序的并发度，提高程序运行效率和响应时间。<br />
线程和进程在使用上各有优缺点：线程执行开销小，但不利于资源管理和保护；而进程正相反。同时，线程适合于在SMP机器上运行，而进程则可以跨机器迁移。<br />
===============================================================================<br />
<span class="oblog_text">思科<br />
1. 用宏定义写出swap（x，y）<br />
#define swap(x, y)\<br />
x = x + y;\<br />
y = x - y;\<br />
x = x - y;<br />
2.数组a[N]，存放了1至N-1个数，其中某个数重复一次。写一个函数，找出被重复的数字.时间复杂度必须为o（N）函数原型：<br />
int do_dup(int a[],int N)<br />
3 一语句实现x是否为2的若干次幂的判断<br />
int i = 512;<br />
cout &lt;&lt; boolalpha &lt;&lt; ((i &amp; (i - 1)) ? false : true) &lt;&lt; endl;<br />
4.unsigned int intvert(unsigned int x,int p,int n)实现对x的进行转换,p为起始转化位,n为需要转换的长度,假设起始点在右边.如x=0b0001 0001,p=4,n=3转换后x=0b0110 0001<br />
unsigned int intvert(unsigned int x,int p,int n){<br />
unsigned int _t = 0;<br />
unsigned int _a = 1;<br />
for(int i = 0; i &lt; n; ++i){<br />
_t |= _a;<br />
_a = _a &lt;&lt; 1;<br />
}<br />
_t = _t &lt;&lt; p;<br />
x ^= _t;<br />
return x;<br />
}<br />
===============================================================================<br />
<span class="oblog_text">&nbsp;</span></span></p>
<p>慧通：<br />
什么是预编译<br />
何时需要预编译：<br />
１、总是使用不经常改动的大型代码体。 <br />
２、程序由多个模块组成，所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下，可以将所有包含文件预编译为一个预编译头。<br />
char * const p;<br />
char const * p<br />
const char *p</p>
<p>上述三个有什么区别？<br />
char * const p; //常量指针，p的值不可以修改<br />
char const * p；//指向常量的指针，指向的常量值不可以改<br />
const char *p； //和char const *p</p>
<p>char str1[] = &quot;abc&quot;;<br />
char str2[] = &quot;abc&quot;;</p>
<p>const char str3[] = &quot;abc&quot;;<br />
const char str4[] = &quot;abc&quot;;</p>
<p>const char *str5 = &quot;abc&quot;;<br />
const char *str6 = &quot;abc&quot;;</p>
<p>char *str7 = &quot;abc&quot;;<br />
char *str8 = &quot;abc&quot;;</p>
<p><br />
cout &lt;&lt; ( str1 == str2 ) &lt;&lt; endl;<br />
cout &lt;&lt; ( str3 == str4 ) &lt;&lt; endl;<br />
cout &lt;&lt; ( str5 == str6 ) &lt;&lt; endl;<br />
cout &lt;&lt; ( str7 == str8 ) &lt;&lt; endl;</p>
<p>结果是：0 0 1 1<br />
解答：str1,str2,str3,str4是数组变量，它们有各自的内存空间；<br />
而str5,str6,str7,str8是指针，它们指向相同的常量区域。</p>
<p><br />
12. 以下代码中的两个sizeof用法有问题吗？[C易]<br />
void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母<br />
{<br />
&nbsp;&nbsp;&nbsp; for( size_t i=0; i &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( 'a'&lt;=str[i] &amp;&amp; str[i]&lt;='z' )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; str[i] -= ('a'-'A' );<br />
}<br />
char str[] = &quot;aBcDe&quot;;<br />
cout &lt;&lt; &quot;str字符长度为: &quot; &lt;&lt; sizeof(str)/sizeof(str[0]) &lt;&lt; endl;<br />
UpperCase( str );<br />
cout &lt;&lt; str &lt;&lt; endl;</p>
<p>答：函数内的sizeof有问题。根据语法，sizeof如用于数组，只能测出静态数组的大小，无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组，因此其大小为6，函数内的str实际只是一个指向字符串的指针，没有任何额外的与数组相关的信息，因此sizeof作用于上只将其当指针看，一个指针为4个字节，因此返回4。</p>
<p>一个32位的机器,该机器的指针是多少位<br />
指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。</p>
<p>main()<br />
{<br />
&nbsp; int a[5]={1,2,3,4,5};<br />
&nbsp;&nbsp; int *ptr=(int *)(&amp;a+1);</p>
<p>&nbsp;&nbsp; printf(&quot;%d,%d&quot;,*(a+1),*(ptr-1));<br />
}<br />
输出：2,5<br />
*(a+1）就是a[1]，*(ptr-1)就是a[4],执行结果是2，5<br />
&amp;a+1不是首地址+1，系统会认为加一个a数组的偏移，是偏移了一个数组的大小（本例是5个int）<br />
int *ptr=(int *)(&amp;a+1); <br />
则ptr实际是&amp;(a[5]),也就是a+5<br />
原因如下：<br />
&amp;a是数组指针，其类型为 int (*)[5];<br />
而指针加1要根据指针类型加上一定的值，<br />
不同类型的指针+1之后增加的大小不同<br />
a是长度为5的int数组指针，所以要加 5*sizeof(int)<br />
所以ptr实际是a[5]<br />
但是prt与(&amp;a+1)类型是不一样的(这点很重要)<br />
所以prt-1只会减去sizeof(int*)<br />
a,&amp;a的地址是一样的，但意思不一样，a是数组首地址，也就是a[0]的地址，&amp;a是对象（数组）首地址，a+1是数组下一元素的地址，即a[1],&amp;a+1是下一个对象的地址，即a[5].</p>
<p><br />
1.请问以下代码有什么问题：<br />
int&nbsp; main()<br />
{<br />
char a;<br />
char *str=&amp;a;<br />
strcpy(str,&quot;hello&quot;);<br />
printf(str);<br />
return 0;<br />
}<br />
没有为str分配内存空间，将会发生异常<br />
问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果，但因为越界进行内在读写而导致程序崩溃。</p>
<p>char* s=&quot;AAA&quot;;<br />
printf(&quot;%s&quot;,s);<br />
s[0]='B';<br />
printf(&quot;%s&quot;,s);<br />
有什么错？<br />
&quot;AAA&quot;是字符串常量。s是指针，指向这个字符串常量，所以声明s的时候就有问题。<br />
cosnt char* s=&quot;AAA&quot;;<br />
然后又因为是常量，所以对是s[0]的赋值操作是不合法的。<br />
1、写一个&ldquo;标准&rdquo;宏，这个