﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-HyJune的专栏-文章分类-6. 面试题集锦</title><link>http://www.cppblog.com/hyjune/category/7383.html</link><description>Linux From Scratch</description><language>zh-cn</language><lastBuildDate>Tue, 17 Jun 2008 13:11:29 GMT</lastBuildDate><pubDate>Tue, 17 Jun 2008 13:11:29 GMT</pubDate><ttl>60</ttl><item><title>[转] 文思创新”一次电话面试</title><link>http://www.cppblog.com/hyjune/articles/53735.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:39:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53735.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53735.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53735.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53735.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53735.html</trackback:ping><description><![CDATA[from: <a  href="http://topic.csdn.net/u/20080609/10/20f0b843-791c-424b-87fb-be1182afde2f.html">http://topic.csdn.net/u/20080609/10/20f0b843-791c-424b-87fb-be1182afde2f.html</a><br><br>问题还真多，简单答一下： <br> 1. 深COPY与浅COPY  <br> 深COPY是把对象中的数据以及对象中指针指向的数据都COPY；浅COPY是只COPY对象中的数据。 <br> 2. NEW与MALLOC区别  <br> NEW是C++中特有的，分配对象时会自动调用构造函数，MALLOC只分配内存。 <br> 3. 构造函数可不可以是虚函数：  <br> 不能，因为虚函数表是构造时建立的。 <br> 4. 谈一谈多态的理解  <br> 多态这个词用的地方很多，在类的成员函数方面，同名函数可以定义多种形式，在类的继承方面，同一个函数可以被子类重载，具有多种形态。 <br> 5. 聚合与耦合  <br> 聚合是模块内部的关联，耦合是模块之间的关联，提倡高聚合、低耦合。 <br> 6. 页表的理解，虚表  <br> 貌似数据库中的概念，不懂。 <br> 7. 怎么读写一个文件  <br> 先打开或创建，根据需要调整文件指针，读和写，关闭文件。 <br> 8. 什么情况会造成内存泄漏  <br> 分配内存没有释放；打开对象没有关闭。 <br> 9. 项目开发过程中最重要的是什么  <br> 不理解这个问题是问什么，随便答一个：代码的可读性。 <br> 10. 对加班有什么看法  <br> 加班要自愿；加班是对公司的额外服务，应得到额外的报酬。 <br> 11. 期望的薪水  <br> 因人而异，一般会以现有工资水平做参照；薪水应随着公司效益、个人价值、社会经济水平而变化。 <br> 12. 怎么分析规化一个项目  <br> 这话题太大了。 <br> 13. 定义一个空类CLASS TMP;SIZEOF(TMP) = ?;  <br> =1。 <br> 14. CONST指针  <br> 不可修改指针指向的数据。 <br> 15.dll与lib相关知识点  <br> 都是代码库文件，DLL是动态链接，可以单独更新；LIB是生成程序时连接，连接时只提取用到的obj模块。 <br> 16.指针与引用相关  <br> 引用就是传递对象的指针，但必须是变量，指针可以是常量。 <br> 17.面向对象设计思想  <br> 把一类相关的数据和方法封装为一个类，尽量高聚合、低耦合。 <br> 18.进程与线程的理解  <br> 进程是一个应用程序实例，可以有多个线程，每个线程相当于一个任务，多个线程同时在运行，进程内的资源是所有线程共享。 <br> 19.内存地址的分配与管理  <br> 内存可以分为很多种，有物理内存、全局内存、局部内存，分配和管理的方法更多。通常所说的应该是进程内的虚拟地址，每个进程有2GB地址空间，常用new来分配、delete释放。 <br> 20.结构体与类的区别与联系  <br> 结构体中的成员默认为public，类中的成员默认为private，其它都相同。 <br> 21.#DEFINE 与COSNT  <br> #DEFINE是定义宏，编译时展开；const是定义常量（数据类型是确定的）。 <br> 22.虚函数与抽像函数  <br> 虚函数是在构造类时把函数指针储存在虚函数表里面，定义虚函数时指定其=NULL称为纯虚函数，包含纯虚函数的类称为抽象类，不能直接实例化，必须派生子类，在子类中实现该虚函数后才能实例化。<br><br>注：答案不一定正确<br><br><img src ="http://www.cppblog.com/hyjune/aggbug/53735.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:39 <a href="http://www.cppblog.com/hyjune/articles/53735.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] 总结面试时没有回答上的设置内存对齐方式问题</title><link>http://www.cppblog.com/hyjune/articles/53733.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:36:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53733.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53733.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53733.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53733.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53733.html</trackback:ping><description><![CDATA[from: <a  href="http://blog.csdn.net/happyhippy/archive/2006/11/09/1375768.aspx">http://blog.csdn.net/happyhippy/archive/2006/11/09/1375768.aspx</a><br><br>
<p>前两天面试某公司时，没有回答上的一个问题，总结如下，以供参考。<br><br>问：下面这个结构类型的实例变量占用多少内存：<br>struct struct1<br>{<br>&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp; short j;<br>&nbsp;&nbsp;&nbsp; char c;<br>};<br>我反问：是啥语言啥机器啥编译环境？<br>他回答说：VC6.0下。<br>我：内存对齐后占8byte。<br>他又继续问：如何让它只占7byte？<br>我的第一反应是使用位段，正准备回答，又感觉不对，位段不能让它不对齐啊。又想了几秒钟，还是不会，只好回他说没玩过&#8230;&#8230;<br><br><br>今天下午去图书馆翻了下《代码优化：有效使用内存》，发现里面提到了两种方法：<br><font style="font-weight: bold;" size="3">法1：</font><br>#pragma pack(push)<br>#pragma pack(1)<br>struct struct1<br>{<br>&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp; short j;<br>&nbsp;&nbsp;&nbsp; char c;<br>};<br>#pragma pack(pop)<br><br><br><font size="3"><span style="font-weight: bold;" twffan="done">法2：</span></font><br>修改编译指令的参数，来禁止内存对齐：<br><font size="2">VC++&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; ：/Zn1</font>(VS2005下，右击项目-属性-配置属性-C/C++-代码生成-结构成员对齐-选&#8220;1字节(/Zn1):&#8221;(即禁止内存对齐),默认是使用默认值，即按照结构中占用空间最大的成员进行对齐。的size进行对齐。<br><font size="2">Borland C++ ： /-a1</font><br><br><br><font style="font-style: italic; font-family: tahoma;" size="3">法2是对整个项目禁用内存对齐,而法1可以针对特定的结构禁用内存对齐,其提供了更大的灵活性.</font><br><br><br><br>另外，该书中还提到：<br>char不对齐；<br>short沿偶地址对齐；<br>int/float沿取值为4的倍数的地址对齐。<br>double沿取值为8的倍数的地址对齐。<br><br><br>VS2005下，默认是使用默认值，即按照结构中占用空间最大的成员进行对齐，我们可以测试下面这个结构：<br>struct struct2<br>{<br>&nbsp;&nbsp;&nbsp; char i;<br>&nbsp;&nbsp;&nbsp; short d;<br>&nbsp;&nbsp;&nbsp; double c;<br>&nbsp;&nbsp;&nbsp; short j;<br>};<br><br>//保持为默认值或修改编译参数/Zn?，猜下sizeof结果为多少？:)<br>printf("struct2:%d\n",sizeof(struct2));<br>struct2 st;<br>printf("%p\n",&amp;st.i);<br>printf("%p\n",&amp;st.d);<br>printf("%p\n",&amp;st.c);<br>printf("%p\n",&amp;st.j);</p>
<p>&nbsp;</p>
<p>补充：数据的手工对齐：</p>
<p>char *p;<br>int temp = align_power-1;<br>p=(char*)malloc(need_size +&nbsp;temp;<br>p=(char*)malloc(((int)p+temp)&amp;temp);//修改了p，所以释放p前记得要归位<br>注：align_power是所需要的对齐幂，char*（也可以为int*）是指针类型。另外，释放p之前记得让其指向所申请的内存的首地址上。</p>
<br><br><img src ="http://www.cppblog.com/hyjune/aggbug/53733.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:36 <a href="http://www.cppblog.com/hyjune/articles/53733.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] C/C++面试经验总结</title><link>http://www.cppblog.com/hyjune/articles/53731.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:32:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53731.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53731.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53731.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53731.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53731.html</trackback:ping><description><![CDATA[from: <a  href="http://hi.baidu.com/liutingrex/blog/item/bf206e099a368eaa2eddd4b1.html">http://hi.baidu.com/liutingrex/blog/item/bf206e099a368eaa2eddd4b1.html</a><br><br>
<p>1、要把c语言的基础打实</p>
<p>2、理解c＋＋语言中一些概念以及它们之间的区别（需要深刻理解）：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （1）局部变量 全局变量 静态变量 const常量 寄存器变量 宏定义的常量 static变量</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  注：包括它们的内存分配区域，作用域，初始化等等</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （2）理解malloc与new之间的区别，以及free与delete之间区别</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （3）内联函数与宏定义的区别，它们各有什么优点</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （4）内存分配有哪几种形式？分别为何？区别是什么？对编译速度影响是何？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （4）理解什么是重载、覆盖、隐藏，区别是何？可否举例？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （5）什么是多态？举个例子试试</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （6）struct 和class有什么区别？c语言中的struct 和c＋＋中的struct一样么？有什么区别？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （7）说说什么是野指针？野指针什么情况下出现？（没有初始化，delete后没有赋值为NULL）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （8）你熟悉预编译指令么？条件编译是用来做什么的？你会写么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （9）sizeof（）这个函数你理解么？你能说出各种变量类型在win 32 下的值么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （10）关于string这个类你理解么？会写它的构造函数，析构函数，拷贝构造函数，赋值函数么？会写strcpy吗？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （11）知道断言ASSERT（）怎么样么？一定要常用。它是函数还是宏？为什么不能是函数？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （12）懂什么是链表么？会链表的一些基本操作么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （13）明白队列，双链表，循环链表，栈是怎么回事？会写这些类。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （14）一定要知道二叉树的遍历有几种，一定要会写用递归的方式来遍历它们。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （15）在一个字符串中，你能计算里边&#8220;数字字符&#8221;的个数么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （16）知道sizeof(Type*)=4吗？注：win32下</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （17）int array[5]= {}; sizeof(array)=?</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  int Fuction(int a[])</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  return sizeof(a);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  Fuction(array)=?</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （18）你知道函数不能返回栈指针么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （19）知道局部变量为什么比全局变量快么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （20）知道为什么要人为写拷贝构造函数么？</p>
<p>&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;&#215;</p>
<p>从21条开始属于难点</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （21）会用c语言实现重载与继承么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （22）能说出几种排序方法？它们的区别和各自的优点是什么？知道什么是内排序什么是外排序么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （23）知道什么是struct中的对齐么？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  （24）extern c&#8216; 是干什么的？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （25）内存管理你懂多少？（包括内存泄漏，野指针知识，非法调用，内存溢出等）</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （26）malloc返回什么？怎么用？</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; （27）待续&#8230;&#8230;</p>
<p>上次说了说关于c、c＋＋的一些重点，现在说一些关于MFC中经常考的东西（有些也不是专属于MFC，但我们现在经常在MFC中用到，像
ActiveX ，COM，动态链接库的东西），其实在笔试考试中，MFC的东西考的很少，单位都注重c的基础是否扎实，面向对象思想是否理解的深刻。</p>
<p>1）说说mfc中的类继承图的基本框架，这个题我被考过。</p>
<p>2）说说CView类的子类都有什么。</p>
<p>3）DLL的三种调用形式。</p>
<p>4）说说onpaint（）和ondraw（）的关系。</p>
<p>5）说说CView类与CDocument的关系（重要）。</p>
<p>6）说SendMessage（）与PostMessage（）的区别。</p>
<p>7）简述COM技术。</p>
<p>8）说说读写一个文件怎么来完成，分别用c，c＋＋，MFC三种库函数来编写代码。</p>
<p>9）说说二进制文件和文本文件之间区别，举例子，会吗？</p>
<p>10）.net的技术优点是何？</p>
<br><br><img src ="http://www.cppblog.com/hyjune/aggbug/53731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:32 <a href="http://www.cppblog.com/hyjune/articles/53731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] C/C++面试题六（经典）</title><link>http://www.cppblog.com/hyjune/articles/53730.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:30:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53730.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53730.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53730.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53730.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53730.html</trackback:ping><description><![CDATA[from: <a  href="http://blog.chinaunix.net/u2/71471/showart.php?id=1002251">http://blog.chinaunix.net/u2/71471/showart.php?id=1002251</a><br><br>1.求下面函数的返回值（微软）<br>int func(x)<br>{<br>&nbsp;&nbsp;&nbsp; int countx = 0;<br>&nbsp;&nbsp;&nbsp; while(x)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; countx ++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x&amp;(x-1);<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return countx;<br>} <br>假定x = 9999。 答案：8<br>思路：将x转化为2进制，看含有的1的个数。<br>2. 什么是&#8220;引用&#8221;？申明和使用&#8220;引用&#8221;要注意哪些问题？<br>答：
引用就是某个目标变量的&#8220;别名&#8221;(alias)，对应用的操作与对变量直接操作效果完全相同。申明一个引用的时候，切记要对其进行初始化。引用声明完毕
后，相当于目标变量名有两个名称，即该目标原名称和引用名，不能再把该引用名作为其他变量名的别名。声明一个引用，不是新定义了一个变量，它只表示该引用
名是目标变量名的一个别名，它本身不是一种数据类型，因此引用本身不占存储单元，系统也不给引用分配存储单元。不能建立数组的引用。<br>3. 将&#8220;引用&#8221;作为函数参数有哪些特点？<br>（1）传递引用给函数与传递指针的效果是一样的。这时，被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用，所以在被调函数中对形参变量的操作就是对其相应的目标对象（在主调函数中）的操作。<br>（2）
使用引用传递函数的参数，在内存中并没有产生实参的副本，它是直接对实参操作；而使用一般变量传递函数的参数，当发生函数调用时，需要给形参分配存储单
元，形参变量是实参变量的副本；如果传递的是对象，还将调用拷贝构造函数。因此，当参数传递的数据较大时，用引用比用一般变量传递参数的效率和所占空间都
好。<br>（3）使用指针作为函数的参数虽然也能达到与使用引用的效果，但是，在被调函数中同样要给形参分配存储单元，且需要重复使用"*指针变量名"
的形式进行运算，这很容易产生错误且程序的阅读性较差；另一方面，在主调函数的调用点处，必须用变量的地址作为实参。而引用更容易使用，更清晰。<br>4. 在什么时候需要使用&#8220;常引用&#8221;？　<br>如果既要利用引用提高程序的效率，又要保护传递给函数的数据不在函数中被改变，就应使用常引用。常引用声明方式：const 类型标识符 &amp;引用名=目标变量名；<br>例1<br>int a ;<br>const int &amp;ra=a;<br>ra=1; //错误<br>a=1; //正确<br>例2<br>string foo( );<br>void bar(string &amp; s);<br>那么下面的表达式将是非法的：<br>bar(foo( ));<br>bar("hello world");<br>原因在于foo( )和"hello world"串都会产生一个临时对象，而在C++中，这些临时对象都是const类型的。因此上面的表达式就是试图将一个const类型的对象转换为非const类型，这是非法的。<br>引用型参数应该在能被定义为const的情况下，尽量定义为const 。<br>5. 将&#8220;引用&#8221;作为函数返回值类型的格式、好处和需要遵守的规则?<br>格式：类型标识符 &amp;函数名（形参列表及类型说明）{ //函数体 }<br>好处：在内存中不产生被返回值的副本；（注意：正是因为这点原因，所以返回一个局部变量的引用是不可取的。因为随着该局部变量生存期的结束，相应的引用也会失效，产生runtime error!<br>注意事项：<br>（1）不能返回局部变量的引用。这条可以参照Effective C++[1]的Item 31。主要原因是局部变量会在函数返回后被销毁，因此被返回的引用就成为了"无所指"的引用，程序会进入未知状态。<br>（2）
不能返回函数内部new分配的内存的引用。这条可以参照Effective C++[1]的Item
31。虽然不存在局部变量的被动销毁问题，可对于这种情况（返回函数内部new分配内存的引用），又面临其它尴尬局面。例如，被函数返回的引用只是作为一
个临时变量出现，而没有被赋予一个实际的变量，那么这个引用所指向的空间（由new分配）就无法释放，造成memory leak。<br>（3）可以返
回类成员的引用，但最好是const。这条原则可以参照Effective C++[1]的Item
30。主要原因是当对象的属性是与某种业务规则（business
rule）相关联的时候，其赋值常常与某些其它属性或者对象的状态有关，因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常
量引用（或指针），那么对该属性的单纯赋值就会破坏业务规则的完整性。<br>（4）流操作符重载返回值申明为&#8220;引用&#8221;的作用：<br>流操作
符&lt;&lt;和&gt;&gt;，这两个操作符常常希望被连续使用，例如：cout &lt;&lt; "hello" &lt;&lt;
endl;　因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括：返回一个流对象和返回一个流对象指针。但是对于返回
一个流对象，程序必须重新（拷贝）构造一个新的流对象，也就是说，连续的两个&lt;&lt;操作符实际上是针对不同对象的！这无法让人接受。对于返回一
个流指针则不能连续使用&lt;&lt;操作符。因此，返回一个流对象引用是惟一选择。这个唯一选择很关键，它说明了引用的重要性以及无可替代性，也许这
就是C++语言中引入引用这个概念的原因吧。赋值操作符=。这个操作符象流操作符一样，是可以连续使用的，例如：x = j =
10;或者(x=10)=100;赋值操作符的返回值必须是一个左值，以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。<br>例3<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;"subscript error"; return error; }<br>}<br>（5）
在另外的一些操作符中，却千万不能返回引用：+-*/ 四则运算符。它们不能返回引用，Effective
C++[1]的Item23详细的讨论了这个问题。主要原因是这四个操作符没有side
effect，因此，它们必须构造一个对象作为返回值，可选的方案包括：返回一个对象、返回一个局部变量的引用，返回一个new分配的对象的引用、返回一
个静态对象引用。根据前面提到的引用作为返回值的三个规则，第2、3两个方案都被否决了。静态对象的引用又因为((a+b) ==
(c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。<br>6. &#8220;引用&#8221;与多态的关系？<br>引用是除指针外另一个可以产生多态效果的手段。这意味着，一个基类的引用可以指向它的派生类实例。<br>例4<br>Class A; Class B : Class A{...};&nbsp; B b; A&amp; ref = b;<br>7. &#8220;引用&#8221;与指针的区别是什么？<br>指针通过某个指针变量指向一个对象后，对它所指向的变量间接操作。程序中使用指针，程序的可读性差；而引用本身就是目标变量的别名，对引用的操作就是对目标变量的操作。此外，就是上面提到的对函数传ref和pointer的区别。<br>8. 什么时候需要&#8220;引用&#8221;？<br>流操作符&lt;&lt;和&gt;&gt;、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。<br>以上 2-8 参考：<a  href="http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx"><font color="#0000ff">http://blog.csdn.net/wfwd/archive/2006/05/30/763551.aspx</font></a><br>9. 结构与联合有和区别？<br>1. 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员（所有成员共用一块地址空间）, 而结构的所有成员都存在（不同成员的存放地址不同）。<br>&nbsp;2. 对于联合的不同成员赋值, 将会对其它成员重写,&nbsp; 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。<br>10. 下面关于&#8220;联合&#8221;的题目的输出？<br>a)<br>＃i nclude &lt;stdio.h&gt;<br>union<br>{<br>int i;<br>char x[2];<br>}a;<br>void main()<br>{<br>a.x[0] = 10;<br>a.x[1] = 1;<br>printf("%d",a.i);<br>}<br>答案：266 (低位低地址，高位高地址，内存占用情况是Ox010A）<br>b)<br>&nbsp;&nbsp;&nbsp;&nbsp; main()<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*定义一个联合*/<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct{&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; char first;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char second;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }half;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }number;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; number.i=0x4241;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*联合成员赋值*/<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%c%c\n", number.half.first, mumber.half.second);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; number.half.first='a';&nbsp;&nbsp; /*联合中结构成员赋值*/<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; number.half.second='b';<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("%x\n", number.i);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getch();<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>答案： AB&nbsp;&nbsp; (0x41对应'A',是低位；Ox42对应'B',是高位）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6261 (number.i和number.half共用一块地址空间）<br>11. 已知strcpy的函数原型：char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串，strSrc 是源字符串。不调用C++/C 的字符串库函数，请编写函数 strcpy。<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++) != &#8216;\0&#8217;)<br>;<br>return tempptr ;<br>}<br>12. 已知String类定义如下：<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>String::String(const char *str)<br>{<br>&nbsp;&nbsp; if ( str == NULL ) //strlen在参数为NULL时会抛异常才会有这步判断<br>&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_data = new char[1] ;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_data[0] = '\0' ;<br>&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_data = new char[strlen(str) + 1];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strcpy(m_data,str);<br>&nbsp;&nbsp;&nbsp; }<br>}<br>String::String(const String &amp;another)<br>{<br>&nbsp;&nbsp;&nbsp; m_data = new char[strlen(another.m_data) + 1];<br>&nbsp;&nbsp;&nbsp; strcpy(m_data,other.m_data);<br>}<br>String&amp; String::operator =(const String &amp;rhs)<br>{<br>&nbsp;&nbsp;&nbsp; if ( this == &amp;rhs)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this ;<br>&nbsp;&nbsp;&nbsp; delete []m_data; //删除原来的数据，新开一块内存<br>&nbsp;&nbsp;&nbsp; m_data = new char[strlen(rhs.m_data) + 1];<br>&nbsp;&nbsp;&nbsp; strcpy(m_data,rhs.m_data);<br>&nbsp;&nbsp;&nbsp; return *this ;<br>}<br>String::~String()<br>{<br>&nbsp;&nbsp;&nbsp; delete []m_data ;<br>}<br>13. .h头文件中的ifndef/define/endif 的作用？<br>答：防止该头文件被重复引用。<br>14. ＃i nclude&lt;file.h&gt; 与 ＃i nclude "file.h"的区别？<br>答：前者是从Standard Library的路径寻找和引用file.h，而后者是从当前工作路径搜寻并引用file.h。<br>15.在C++ 程序中调用被C 编译器编译后的函数，为什么要加extern &#8220;C&#8221;？<br>首先，作为extern是C/C++语言中表明函数和全局变量作用范围（可见性）的关键字，该关键字告诉编译器，其声明的函数和变量可以在本模块或其它模块中使用。<br>通
常，在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如，如果模块B欲引用该模块A中定义的全局变量和函数时只
需包含模块A的头文件即可。这样，模块B中调用模块A中的函数时，在编译阶段，模块B虽然找不到该函数，但是并不会报错；它会在连接阶段中从模块A编译生
成的目标代码中找到此函数<br>extern "C"是连接申明(linkage declaration),被extern "C"修饰的变量和函数是按照C语言方式编译和连接的,来看看C++中对类似C的函数是怎样编译的：<br>作为一种面向对象的语言，C++支持函数重载，而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如，假设某个函数的原型为：<br>void foo( int x, int y );<br>　　<br>该函数被C编译器编译后在符号库中的名字为_foo，而C++编译器则会产生像_foo_int_int之类的名字（不同的编译器可能生成的名字不同，但是都采用了相同的机制，生成的新名字称为&#8220;mangled name&#8221;）。<br>_foo_int_int
这样的名字包含了函数名、函数参数数量及类型信息，C++就是靠这种机制来实现函数重载的。例如，在C++中，函数void foo( int x,
int y )与void foo( int x, float y )编译生成的符号是不相同的，后者为_foo_int_float。<br>同样
地，C++中的变量除支持局部变量外，还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名，我们以"."来区分。而本质上，编译
器在进行编译时，与函数的处理相似，也为类中的变量取了一个独一无二的名字，这个名字与用户程序中同名的全局变量名字不同。<br>未加extern "C"声明时的连接方式<br>假设在C++中，模块A的头文件如下：<br>// 模块A头文件　moduleA.h<br>#ifndef MODULE_A_H<br>#define MODULE_A_H<br>int foo( int x, int y );<br>#endif　　<br>在模块B中引用该函数：<br>// 模块B实现文件　moduleB.cpp<br>＃i nclude "moduleA.h"<br>foo(2,3);<br>　　<br>实际上，在连接阶段，连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号！<br>加extern "C"声明后的编译和连接方式<br>加extern "C"声明后，模块A的头文件变为：<br>// 模块A头文件　moduleA.h<br>#ifndef MODULE_A_H<br>#define MODULE_A_H<br>extern "C" int foo( int x, int y );<br>#endif　　<br>在模块B的实现文件中仍然调用foo( 2,3 )，其结果是：<br>（1）模块A编译生成foo的目标代码时，没有对其名字进行特殊处理，采用了C语言的方式；<br>（2）连接器在为模块B的目标代码寻找foo(2,3)调用时，寻找的是未经修改的符号名_foo。<br>如果在模块A中函数声明了foo为extern "C"类型，而模块B中包含的是extern int foo( int x, int y ) ，则模块B找不到模块A中的函数；反之亦然。<br>所
以，可以用一句话概括extern
&#8220;C&#8221;这个声明的真实目的（任何语言中的任何语法特性的诞生都不是随意而为的，来源于真实世界的需求驱动。我们在思考问题时，不能只停留在这个语言是怎么
做的，还要问一问它为什么要这么做，动机是什么，这样我们可以更深入地理解许多问题）：实现C++与C及其它语言的混合编程。　　<br>明白了C++中extern "C"的设立动机，我们下面来具体分析extern "C"通常的使用技巧：<br>extern "C"的惯用法<br>（1）在C++中引用C语言中的函数和变量，在包含C语言头文件（假设为cExample.h）时，需进行下列处理：<br>extern "C"<br>{<br>＃i nclude "cExample.h"<br>}<br>而在C语言的头文件中，对其外部函数只能指定为extern类型，C语言中不支持extern "C"声明，在.c文件中包含了extern "C"时会出现编译语法错误。<br>C++引用C函数例子工程中包含的三个文件的源代码如下：<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>/* c语言实现文件：cExample.c */<br>＃i nclude "cExample.h"<br>int add( int x, int y )<br>{<br>return x + y;<br>}<br>// c++实现文件，调用add：cppFile.cpp<br>extern "C"<br>{<br>＃i nclude "cExample.h"<br>}<br>int main(int argc, char* argv[])<br>{<br>add(2,3);<br>return 0;<br>}<br>如果C++调用一个C语言编写的.DLL时，当包括.DLL的头文件或声明接口函数时，应加extern "C" {　}。<br>（2）在C中引用C++语言中的函数和变量时，C++的头文件需添加extern "C"，但是在C语言中不能直接引用声明了extern "C"的该头文件，应该仅将C文件中将C++中定义的extern "C"函数声明为extern类型。<br>C引用C++函数例子工程中包含的三个文件的源代码如下：<br>//C++头文件 cppExample.h<br>#ifndef CPP_EXAMPLE_H<br>#define CPP_EXAMPLE_H<br>extern "C" int add( int x, int y );<br>#endif<br>//C++实现文件 cppExample.cpp<br>＃i nclude "cppExample.h"<br>int add( int x, int y )<br>{<br>return x + y;<br>}<br>/* C实现文件 cFile.c<br>/* 这样会编译出错：＃i nclude "cExample.h" */<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>15题目的解答请参考《C++中extern &#8220;C&#8221;含义深层探索》注解：<br>16. 关联、聚合(Aggregation)以及组合(Composition)的区别？<br>涉及到UML中的一些概念：关联是表示两个类的一般性联系，比如&#8220;学生&#8221;和&#8220;老师&#8221;就是一种关联关系；聚合表示has-a的关系，是一种相对松散的关系，聚合类不需要对被聚合类负责，如下图所示，用空的菱形表示聚合关系：<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;&nbsp; <br>从实现的角度讲，聚合可以表示为:<br>class A {...}&nbsp; class B { A* a; .....}<br>而组合表示contains-a的关系，关联性强于聚合：组合类与被组合类有相同的生命周期，组合类要对被组合类负责，采用实心的菱形表示组合关系：<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;&nbsp;&nbsp; <br>实现的形式是:<br>class A{...} class B{ A a; ...}<br>参考文章：<a  href="http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx"><font color="#0000ff">http://blog.csdn.net/wfwd/archive/2006/05/30/763753.aspx</font></a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a  href="http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx"><font color="#0000ff">http://blog.csdn.net/wfwd/archive/2006/05/30/763760.aspx</font></a><br>17.面向对象的三个基本特征，并简单叙述之？<br>1. 封装：将客观事物抽象成类，每个类对自身的数据和方法实行protection(private, protected,public)<br>2.
继承：广义的继承有三种实现形式：实现继承（指使用基类的属性和方法而无需额外编码的能力）、可视继承（子窗体使用父窗体的外观和实现代码）、接口继承
（仅使用属性和方法，实现滞后到子类实现）。前两种（类继承）和后一种（对象组合=&gt;接口继承以及纯虚函数）构成了功能复用的两种方式。<br>3. 多态：是将父对象设置成为和一个或更多的他的子对象相等的技术，赋值之后，父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说，就是一句话：允许将子类类型的指针赋值给父类类型的指针。<br>18. 重载（overload)和重写(overried，有的书也叫做&#8220;覆盖&#8221;）的区别？<br>常考的题目。从定义上来说：<br>重载：是指允许存在多个同名函数，而这些函数的参数表不同（或许参数个数不同，或许参数类型不同，或许两者都不同）。<br>重写：是指子类重新定义复类虚函数的方法。<br>从实现原理上来说：<br>重
载：编译器根据函数不同的参数表，对同名函数的名称做修饰，然后这些同名函数就成了不同的函数（至少对于编译器来说是这样的）。如，有两个同名函
数：function func(p:integer):integer;和function
func(p:string):integer;。那么编译器做过修饰后的函数名称可能是这样的：int_func、str_func。对于这两个函数的
调用，在编译器间就已经确定了，是静态的。也就是说，它们的地址在编译期就绑定了（早绑定），因此，重载和多态无关！<br>重写：和多态真正相关。当子类重新定义了父类的虚函数后，父类指针根据赋给它的不同的子类指针，动态的调用属于子类的该函数，这样的函数调用在编译期间是无法确定的（调用的子类的虚函数的地址无法给出）。因此，这样的函数地址是在运行期绑定的（晚绑定）。<br>19. 多态的作用？<br>主要是两个：1. 隐藏实现细节，使得代码能够模块化；扩展代码模块，实现代码重用；2. 接口重用：为了类在继承和派生的时候，保证使用家族中任一类的实例的某一属性时的正确调用。<br>20. Ado与Ado.net的相同与不同？<br>除
了&#8220;能够让应用程序处理存储于DBMS 中的数据&#8220;这一基本相似点外，两者没有太多共同之处。但是Ado使用OLE DB 接口并基于微软的COM
技术，而ADO.NET 拥有自己的ADO.NET 接口并且基于微软的.NET 体系架构。众所周知.NET 体系不同于COM
体系，ADO.NET 接口也就完全不同于ADO和OLE DB 接口，这也就是说ADO.NET 和ADO是两种数据访问方式。ADO.net
提供对XML 的支持。<br>21. New delete 与malloc free 的联系与区别?<br>答案：都是在堆(heap)上进行动态的内存操作。用malloc函数需要指定内存分配的字节数并且不能初始化对象，new 会自动调用对象的构造函数。delete 会调用对象的destructor，而free 不会调用对象的destructor.<br>22. #define DOUBLE(x) x+x ，i = 5*DOUBLE(5)； i 是多少？<br>答案：i 为30。<br>23. 有哪几种情况只能用intialization list 而不能用assignment?<br>答案：当类中含有const、reference 成员变量；基类的构造函数都需要初始化表。<br>24. C++是不是类型安全的？<br>答案：不是。两个不同类型的指针之间可以强制转换（用reinterpret cast)。C#是类型安全的。<br>25. main 函数执行以前，还会执行什么代码？<br>答案：全局对象的构造函数会在main 函数之前执行。<br>26. 描述内存分配方式以及它们的区别?<br>1）从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的整个运行期间都存在。例如全局变量，static 变量。<br>2）在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。<br>3） 从堆上分配，亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存，程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由程序员决定，使用非常灵活，但问题也最多。
27.struct 和 class 的区别<br>答案：struct 的成员默认是公有的，而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。<br>从
感情上讲，大多数的开发者感到类和结构有很大的差别。感觉上结构仅仅象一堆缺乏封装和功能的开放的内存位，而类就象活的并且可靠的社会成员，它有智能服
务，有牢固的封装屏障和一个良好定义的接口。既然大多数人都这么认为，那么只有在你的类有很少的方法并且有公有数据（这种事情在良好设计的系统中是存在
的!）时，你也许应该使用 struct 关键字，否则，你应该使用 class 关键字。 <br>28.当一个类A 中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少，如果不是零，请解释一下编译器为什么没有让它为零。（Autodesk）<br>答案：肯定不是零。举个反例，如果是零的话，声明一个class A[10]对象数组，而每一个对象占用的空间是零，这时就没办法区分A[0],A[1]&#8230;了。<br>29. 在8086 汇编下，逻辑地址和物理地址是怎样转换的？（Intel）<br>答案：通用寄存器给出的地址，是段内偏移地址，相应段寄存器地址*10H+通用寄存器内地址，就得到了真正要访问的地址。<br>30. 比较C++中的4种类型转换方式？<br>请参考：<a  href="http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspx"><font color="#0000ff">http://blog.csdn.net/wfwd/archive/2006/05/30/763785.aspx</font></a>，重点是static_cast, dynamic_cast和reinterpret_cast的区别和应用。<br>31.分别写出BOOL,int,float,指针类型的变量a 与&#8220;零&#8221;的比较语句。<br>答案：<br>BOOL :&nbsp;&nbsp;&nbsp; if ( !a ) or if(a)<br>int :&nbsp;&nbsp;&nbsp;&nbsp; if ( a == 0)<br>float :&nbsp;&nbsp; const EXPRESSION EXP = 0.000001<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( a &lt; EXP &amp;&amp; a &gt;-EXP)<br>pointer : if ( a != NULL) or if(a == NULL)<br>&nbsp;<br>32.请说出const与#define 相比，有何优点？<br>答案：1） const 常量有数据类型，而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换，没有类型安全检查，并且在字符替换可能会产生意料不到的错误。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2） 有些集成化的调试工具可以对const 常量进行调试，但是不能对宏常量进行调试。<br>33.简述数组与指针的区别？<br>数组要么在静态存储区被创建（如全局数组），要么在栈上被创建。指针可以随时指向任意类型的内存块。<br>(1)修改内容上的差别<br>char a[] = &#8220;hello&#8221;;<br>a[0] = &#8216;X&#8217;;<br>char *p = &#8220;world&#8221;; // 注意p 指向常量字符串<br>p[0] = &#8216;X&#8217;; // 编译器不能发现该错误，运行时错误<br>(2)
用运算符sizeof 可以计算出数组的容量（字节数）。sizeof(p),p 为指针得到的是一个指针变量的字节数，而不是p
所指的内存容量。C++/C
语言没有办法知道指针所指的内存容量，除非在申请内存时记住它。注意当数组作为函数的参数进行传递时，该数组自动退化为同类型的指针。<br>char a[] = "hello world";<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>34.类成员函数的重载、覆盖和隐藏区别？<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.&#8220;隐藏&#8221;是指派生类的函数屏蔽了与其同名的基类函数，规则如下：<br>（1）如果派生类的函数与基类的函数同名，但是参数不同。此时，不论有无virtual关键字，基类的函数将被隐藏（注意别与重载混淆）。<br>（2）如果派生类的函数与基类的函数同名，并且参数也相同，但是基类函数没有virtual 关键字。此时，基类的函数被隐藏（注意别与覆盖混淆）<br>35.
There are two int variables: a and b, don&#8217;t use &#8220;if&#8221;, &#8220;? :&#8221;, &#8220;switch&#8221;or
other judgement statements, find out the biggest one of the two numbers.<br>答案：( ( a + b ) + abs( a - b ) ) / 2<br>36. 如何打印出当前源文件的文件名以及源文件的当前行号？<br>答案：<br>cout &lt;&lt; __FILE__ ;<br>cout&lt;&lt;__LINE__ ;<br>__FILE__和__LINE__是系统预定义宏，这种宏并不是在某个文件中定义的，而是由编译器定义的。<br>37. main 主函数执行完毕后，是否可能会再执行一段代码，给出说明？<br>答案：可以，可以用_onexit 注册一个函数，它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void);<br>void main( void )<br>{<br>String str("zhanglin");<br>_onexit( fn1 );<br>_onexit( fn2 );<br>_onexit( fn3 );<br>_onexit( fn4 );<br>printf( "This is executed first.\n" );<br>}<br>int fn1()<br>{<br>printf( "next.\n" );<br>return 0;<br>}<br>int fn2()<br>{<br>printf( "executed " );<br>return 0;<br>}<br>int fn3()<br>{<br>printf( "is " );<br>return 0;<br>}<br>int fn4()<br>{<br>printf( "This " );<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>38. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的？<br>答案：<br>#ifdef __cplusplus<br>cout&lt;&lt;"c++";<br>#else<br>cout&lt;&lt;"c";<br>#endif<br>39.文件中有一组整数，要求排序后输出到另一个文件中<br>答案：<br>＃i nclude&lt;iostream&gt;<br>＃i nclude&lt;fstream&gt;<br>using namespace std;<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>void main( void )<br>{<br>vector&lt;int&gt;data;<br>ifstream in("c:\\data.txt");<br>if ( !in)<br>{<br>cout&lt;&lt;"file error!";<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("c:\\result.txt");<br>if ( !out)<br>{<br>cout&lt;&lt;"file error!";<br>exit(1);<br>}<br>for ( i = 0 ; i &lt; data.size() ; i++)<br>out&lt;&lt;data&lt;&lt;" ";<br>out.close(); //关闭输出文件流<br>}<br>&nbsp;<br>40. 链表题：一个链表的结点结构<br>struct Node<br>{<br>int data ;<br>Node *next ;<br>};<br>typedef struct Node Node ;<br>(1)已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)<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>41. 分析一下这段程序的输出 (Autodesk)<br>class B<br>{<br>public:<br>B()<br>{<br>cout&lt;&lt;"default constructor"&lt;&lt;endl;<br>}<br>~B()<br>{<br>cout&lt;&lt;"destructed"&lt;&lt;endl;<br>}<br>B(int i):data(i)&nbsp;&nbsp;&nbsp; //B(int) works as a converter ( int -&gt; instance of&nbsp; B)<br>{<br>cout&lt;&lt;"constructed by parameter " &lt;&lt; data &lt;&lt;endl;<br>}<br>private:<br>int data;<br>};<br>B Play( B b)<br>{<br>return b ;<br>}<br>(1)&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;&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; &nbsp;results:<br>int main(int argc, char* argv[])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constructed by parameter 5<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;&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;&nbsp;&nbsp;&nbsp; destructed&nbsp; B(5)形参析构<br>B t1 = Play(5); B t2 = Play(t1);&nbsp;&nbsp; 　&nbsp;&nbsp; destructed&nbsp; t1形参析构<br>return 0;　　　　　　　　　　　　 destructed&nbsp; t2　注意顺序！<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;&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;&nbsp;&nbsp; &nbsp; destructed&nbsp; t1<br>(2)&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;&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; results:<br>int main(int argc, char* argv[])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; constructed by parameter 5<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;&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;&nbsp;&nbsp;&nbsp; &nbsp;destructed&nbsp; B(5)形参析构<br>B t1 = Play(5); B t2 = Play(10);&nbsp;&nbsp; 　 &nbsp;constructed by parameter 10<br>return 0;　　　　　　　　　　　　&nbsp; destructed&nbsp; B(10)形参析构<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;&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;&nbsp;&nbsp;&nbsp; &nbsp; destructed&nbsp; t2　注意顺序！<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;&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;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; destructed&nbsp; t1<br>42. 写一个函数找出一个整数数组中，第二大的数 （microsoft）<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 &gt; maxnumber )<br>{<br>sec_max = maxnumber ;<br>maxnumber = data ;<br>}<br>else<br>{<br>if ( data &gt; sec_max )<br>sec_max = data ;<br>}<br>}<br>return sec_max ;<br>}<br>43. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。<br>KMP算法效率最好，时间复杂度是Ｏ(n+m)。<br>44. 多重继承的内存分配问题：<br>&nbsp;&nbsp; 比如有class A : public class B, public class C {}<br>&nbsp;&nbsp; 那么A的内存结构大致是怎么样的？<br>这个是compiler-dependent的, 不同的实现其细节可能不同。<br>如果不考虑有虚函数、虚继承的话就相当简单；否则的话，相当复杂。<br>可以参考《深入探索C++对象模型》，或者：<br><a  href="http://blog.csdn.net/wfwd/archive/2006/05/30/763797.aspx"><font color="#0000ff">http://blog.csdn.net/wfwd/archive/2006/05/30/763797.aspx</font></a><br>45. 如何判断一个单链表是有环的？（注意不能用标志位，最多只能用两个额外指针）<br>&nbsp;&nbsp; struct node { char val; node* next;}<br>&nbsp;&nbsp; bool check(const node* head) {} //return false : 无环；true: 有环<br>一种O（n）的办法就是（搞两个指针，一个每次递增一步，一个每次递增两步，如果有环的话两者必然重合，反之亦然）：<br>bool check(const node* head)<br>{<br>&nbsp;&nbsp;&nbsp; if(head==NULL)&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; node *low=head, *fast=head-&gt;next;<br>&nbsp;&nbsp;&nbsp; while(fast!=NULL &amp;&amp; fast-&gt;next!=NULL)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; low=low-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fast=fast-&gt;next-&gt;next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(low==fast) return true;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return false;<br>}<br><br><img src ="http://www.cppblog.com/hyjune/aggbug/53730.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:30 <a href="http://www.cppblog.com/hyjune/articles/53730.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] C面试总结(二)</title><link>http://www.cppblog.com/hyjune/articles/53727.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:11:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53727.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53727.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53727.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53727.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53727.html</trackback:ping><description><![CDATA[from: <a  href="http://blog.csdn.net/fansnaf/archive/2006/11/03/1364447.aspx" target="_blank">http://blog.csdn.net/fansnaf/archive/2006/11/03/1364447.aspx</a><br><br>本人很弱，这几个题也搞不定，特来求救：<br>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>望高手赐教！！<br><br>第一题,注意可增长数组的应用.<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br><br>int main(void)<br>{<br>int MAX = 10;<br>int *a = (int *)malloc(MAX * sizeof(int));<br>int *b;<br><br>FILE *fp1;<br>FILE *fp2;<br><br>fp1 = fopen("a.txt","r");<br>if(fp1 == NULL)<br>{printf("error1");<br>exit(-1);<br>}<br><br>fp2 = fopen("b.txt","w");<br>if(fp2 == NULL)<br>{printf("error2");<br>exit(-1);<br>}<br><br>int i = 0;<br>int j = 0;<br><br>while(fscanf(fp1,"%d",&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("error3");<br>exit(-1);<br>}<br>a = b;<br>}<br>}<br><br>for(;--j &gt;= 0;)<br>fprintf(fp2,"%d\n",a[j]);<br><br>fclose(fp1);<br>fclose(fp2);<br><br>return 0;<br><br><br>}<br><br>第二题.<br>#include &lt;stdio.h&gt;<br><br>int main(void)<br>{<br>unsigned long int i,j,k;<br><br>printf("please input the number\n");<br>scanf("%d",&amp;i);<br>if( i % 2 == 0)<br>j = i / 2;<br>else<br>j = i / 2 + 1;<br><br>printf("The result is \n");<br>for(k = 0; k &lt; j; k++)<br>printf("%d = %d + %d\n",i,k,i - k);<br>return 0;<br>}<br><br>#include &lt;stdio.h&gt;<br>void main()<br>{<br>unsigned long int a,i=1;<br>scanf("%d",&amp;a);<br>if(a%2==0)<br>{<br>for(i=1;i&lt;a/2;i++)<br>printf("%d",a,a-i);<br>}<br>else<br>for(i=1;i&lt;=a/2;i++)<br>printf(" %d, %d",i,a-i);<br>}<br><br>兄弟,这样的题目若是做不出来实在是有些不应该, 给你一个递规反向输出字符串的例子,可谓是反序的经典例程.<br><br>void inverse(char *p)<br>{<br>if( *p = = '\0' ) <br>return;<br>inverse( p+1 );<br>printf( "%c", *p );<br>}<br><br>int main(int argc, char *argv[])<br>{<br>inverse("abc\0");<br><br>return 0;<br>}<br><br>借签了楼上的&#8220;递规反向输出&#8221;<br>#include &lt;stdio.h&gt;<br>void test(FILE *fread, FILE *fwrite)<br>{<br>char buf[1024] = {0};<br>if (!fgets(buf, sizeof(buf), fread))<br>return;<br>test( fread, fwrite );<br>fputs(buf, fwrite);<br>}<br>int main(int argc, char *argv[])<br>{<br>FILE *fr = NULL;<br>FILE *fw = NULL;<br>fr = fopen("data", "rb");<br>fw = fopen("dataout", "wb");<br>test(fr, fw);<br>fclose(fr);<br>fclose(fw);<br>return 0;<br>}<br><br>在对齐为4的情况下<br>struct BBB<br>{<br>long num；<br>char *name;<br>short int data;<br>char ha;<br>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<br><br>由于是4字节对齐，<br>sizeof(struct BBB) = sizeof(*p) <br>= 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes (经Dev-C++验证)<br><br>p=0x1000000;<br>p+0x200=____;<br>= 0x1000000 + 0x200*24<br><br>(Ulong)p+0x200=____;<br>= 0x1000000 + 0x200<br><br>(char*)p+0x200=____;<br>= 0x1000000 + 0x200*4<br><br>你可以参考一下指针运算的细节<br><br><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运行通过。给分吧^-^<br><br>//快速排序<br><br>#include&lt;iostream&gt;<br><br>usingnamespacestd;<br><br>intPartition (int*L,intlow,int high)<br>{<br>inttemp = L[low];<br>intpt = L[low];<br><br>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;<br><br>returnlow;<br>}<br><br>voidQSort (int*L,intlow,int high)<br>{<br>if (low &lt; high)<br>{<br>intpl = Partition (L,low,high);<br><br>QSort (L,low,pl - 1);<br>QSort (L,pl + 1,high);<br>}<br>}<br><br>intmain ()<br>{<br>intnarry[100],addr[100];<br>intsum = 1,t;<br><br>cout &lt;&lt; "Input number:" &lt;&lt; endl;<br>cin &gt;&gt; t;<br><br>while (t != -1)<br>{<br>narry[sum] = t;<br>addr[sum - 1] = t;<br>sum++;<br><br>cin &gt;&gt; t;<br>}<br><br>sum -= 1;<br>QSort (narry,1,sum);<br><br>for (int i = 1; i &lt;= sum;i++)<br>cout &lt;&lt; narry[i] &lt;&lt; '\t';<br>cout &lt;&lt; endl;<br><br>intk;<br>cout &lt;&lt; "Please input place you want:" &lt;&lt; endl;<br>cin &gt;&gt; k;<br><br>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>}<br><br>}<br><br>cout &lt;&lt; "The NO." &lt;&lt; k &lt;&lt; "number is:" &lt;&lt; narry[sum - kk] &lt;&lt; endl;<br>cout &lt;&lt; "And it's place is:" ;<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>}<br><br><br>return0;<br>}<br><br>1、找错<br>Void test1()<br>{<br>char string[10];<br>char* str1="0123456789";<br>strcpy(string, str1);// 溢出，应该包括一个存放'\0'的字符string[11]<br>}<br><br><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>}<br><br>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>}<br><br>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("%d\n",line[i]);<br>return 0;<br>}<br><br>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. 写出程序运行结果<br><br>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>}<br><br>void main()<br>{<br>int I;<br>int a=2;<br>for(I=0;I&lt;5;I++)<br>{<br>printf("%d,", sum(a));<br>}<br>}<br>// static会保存上次结果，记住这一点，剩下的自己写<br>输出：8,10,12,14,16,<br><br><br>4.<br><br>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定义后就没有赋值。<br><br>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<br><br>今天早上的面试题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程序，防止僵尸进程的出现.
<p>同学的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>{ int date_1;<br>struct val *next;<br>}*p;<br><br>void main(void)<br>{ char c;<br><br>for(c=122;c&gt;=97;c--)<br>{ p.date=c;<br>p=p-&gt;next;<br>}<br><br>p.next=NULL;<br>} <br>}<br>方法2：<br>node *p = NULL;<br>node *q = NULL;<br><br>node *head = (node*)malloc(sizeof(node));<br>head-&gt;data = ' ';head-&gt;next=NULL;<br><br>node *first = (node*)malloc(sizeof(node));<br>first-&gt;data = 'a';first-&gt;next=NULL;head-&gt;next = first;<br>p = first;<br><br>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;<br><br>head-&gt;next = temp; temp-&gt;next=p;p=q;<br>i++;<br>}<br><br>print(head);<br><br>3.可怕的题目终于来了<br>象搜索的输入信息是一个字符串，统计300万输入信息中的最热门的前十条，我们每次输入的一个字符串为不超过255byte,内存使用只有1G,<br>请描述思想，写出算发（c语言），空间和时间复杂度，<br>4.国内的一些帖吧，如baidu,有几十万个主题，假设每一个主题都有上亿的跟帖子，怎么样设计这个系统速度最好，请描述思想，写出算发（c语言），空间和时间复杂度，<br><br><br>#include string.h<br>main(void)<br>{ char *src="hello,world";<br>char *dest=NULL;<br>dest=(char *)malloc(strlen(src));<br>int len=strlen(str);<br>char *d=dest;<br>char *s=src[len];<br>while(len--!=0)<br>d++=s--;<br>printf("%s",dest);<br>}<br>找出错误！！<br>#include "string.h"<br>#include "stdio.h"<br>#include "malloc.h"<br>main(void)<br>{ <br>char *src="hello,world";<br>char *dest=NULL;<br>dest=(char *)malloc(sizeof(char)*(strlen(src)+1));<br>int len=strlen(src);<br>char *d=dest;<br>char *s=src+len-1;<br>while(len--!=0)<br>*d++=*s--;<br>*d='\0';<br>printf("%s",dest);<br>}<br><br>1. 简述一个Linux驱动程序的主要流程与功能。<br><br>2. 请列举一个软件中时间换空间或者空间换时间的例子。<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. 请问一下程序将输出什么结果？<br>char *RetMenory(void)<br>{<br>char p[] = &#8220;hellow world&#8221;;<br>return p;<br>}<br>void Test(void)<br>{<br>char *str = NULL;<br>str = RetMemory();<br>printf(str);<br>}<br>RetMenory执行完毕，p资源被回收，指向未知地址。返回地址，str的内容应是不可预测的, 打印的应该是str的地址<br><br><br>写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)<br>功能：<br>在字符串中找出连续最长的数字串，并把这个串的长度返回，并把这个最长数字串付给其中一个函数参数outputstr所指内存。例如："abcd12345ed125ss123456789"的首地址传给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;<br><br>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++;<br><br>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>}<br><br>不用库函数,用C语言实现将一整型数字转化为字符串<br>方法1：<br>int getlen(char *s){<br>int n;<br>for(n = 0; *s != '\0'; s++)<br>n++;<br>return n;<br>}<br>void reverse(char s[])<br>{<br>int c,i,j;<br>for(i = 0,j = getlen(s) - 1; i &lt; j; i++,j--){<br>c = s[i];<br>s[i] = s[j];<br>s[j] = c;<br>}<br>}<br>void itoa(int n,char s[])<br>{<br>int i,sign;<br>if((sign = n) &lt; 0)<br>n = -n;<br>i = 0;<br>do{/*以反序生成数字*/<br>s[i++] = n%10 + '0';/*get next number*/<br>}while((n /= 10) &gt; 0);/*delete the number*/<br><br>if(sign &lt; 0)<br>s[i++] = '-';<br><br>s[i] = '\0';<br>reverse(s);<br>}<br>方法2:<br>#include &lt;iostream&gt;<br>using namespace std;<br><br>void itochar(int num);<br><br>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;<br><br>}<br>int main()<br>{<br>int num;<br>cin&gt;&gt;num;<br>itochar(num);<br>return 0;<br>}<br><br>前几天面试，有一题想不明白,请教大家！<br>typedef struct <br>{ <br>int a:2;<br>int b:2;<br>int c:1;<br>}test;<br><br>test t;<br>t.a = 1;<br>t.b = 3;<br>t.c = 1;<br><br>printf("%d",t.a);<br>printf("%d",t.b);<br>printf("%d",t.c);<br><br>谢谢!<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>编译器进行符号扩展<br><br><br>求组合数： 求n个数（1....n）中k个数的组合....<br>如：combination(5,3)<br>要求输出：543，542，541，532，531，521，432，431，421，321，<br>#include&lt;stdio.h&gt;<br><br>int pop(int *);<br>int push(int );<br>void combination(int ,int );<br><br>int stack[3]={0};<br>top=-1;<br><br>int main()<br>{<br>int n,m;<br>printf("Input two numbers:\n");<br>while( (2!=scanf("%d%*c%d",&amp;n,&amp;m)) )<br>{<br>fflush(stdin);<br>printf("Input error! Again:\n");<br>}<br>combination(n,m);<br>printf("\n");<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("%d%d%d ",stack[0],stack[1],stack[2]);//&#167;&amp;auml;&#168;&#236;&#164;@?<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>}<br><br>1、用指针的方法，将字符串&#8220;ABCD1234efgh&#8221;前后对调显示<br>#include &lt;stdio.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;dos.h&gt;<br>int main()<br>{<br>char str[] = "ABCD1234efgh";<br>int length = strlen(str);<br>char * p1 = str;<br>char * p2 = str + length - 1;<br>while(p1 &lt; p2)<br>{<br>char c = *p1;<br>*p1 = *p2;<br>*p2 = c;<br>++p1;<br>--p2;<br>}<br>printf("str now is %s\n",str);<br>system("pause");<br>return 0;<br>}<br>2、有一分数序列：1/2,1/4,1/6,1/8&#8230;&#8230;，用函数调用的方法，求此数列前20项的和<br>#include &lt;stdio.h&gt;<br>double getValue()<br>{<br>double result = 0;<br>int i = 2;<br>while(i &lt; 42)<br>{<br>result += 1.0 / i;//一定要使用1.0做除数，不能用1，否则结果将自动转化成整数，即0.000000<br>i += 2;<br>}<br>return result;<br>}<br>int main()<br>{<br>printf("result is %f\n", getValue());<br>system("pause");<br>return 0;<br>}<br></p>
有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数，到末尾时循环至开头继续进行，求最后一个被删掉的数的原始下标位置。<br>以7个数为例：<br>{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<br><br>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;<br><br>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 //元素个数<br>/*<br>MAXLINE 元素个数<br>a[] 元素数组<br>R[] 指针场<br>suffix 下标<br>index 返回最后的下标序号<br>values 返回最后的下标对应的值<br>start 从第几个开始<br>K 间隔<br>*/<br>int find_n(int a[],int R[],int K,int&amp; index,int&amp; values,int s=0) {<br>int suffix;<br>int front_node,current_node;<br>suffix=0;<br>if(s==0) {<br>current_node=0;<br>front_node=MAXLINE-1;<br>}<br>else {<br>current_node=s;<br>front_node=s-1;<br>}<br>while(R[front_node]!=front_node) {<br>printf("%d\n",a[current_node]);<br>R[front_node]=R[current_node];<br>if(K==1) {<br>current_node=R[front_node];<br>continue;<br>}<br>for(int i=0;i&lt;K;i++){<br>front_node=R[front_node];<br>}<br>current_node=R[front_node];<br>}<br>index=front_node;<br>values=a[front_node];<br><br>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;<br><br>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("the value is %d,%d\n",index,values);<br>return 0;<br>}<br><br>试题： <br>void test2() <br>{ <br>char string[10], str1[10]; <br>int i; <br>for(i=0; i&lt;10; i++) <br>{ <br>str1[i] = 'a'; <br>} <br>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>char string[10], str1[10]; <br>int i; <br>for(i=0; i&lt;9; i++) <br>{ <br>str1[i] = 'a'+i; //把abcdefghi赋值给字符数组<br>} <br>str[i]='\0';//加上结束符<br>strcpy( string, str1 ); <br>}<br><br>第二个code题是实现strcmp<br>int StrCmp(const char *str1, const char *str2)<br>做是做对了，没有抄搞，比较乱<br>int StrCmp(const char *str1, const char *str2)<br>{<br>assert(str1 &amp;&amp; srt2);<br>while (*str1 &amp;&amp; *str2 &amp;&amp; *str1 == *str2) {<br>str1++, str2++;<br>}<br>if (*str1 &amp;&amp; *str2)<br>return (*str1-*str2);<br>elseif (*str1 &amp;&amp; *str2==0)<br>return 1;<br>elseif (*str1 = = 0 &amp;&amp; *str2)<br>return -1;<br>else<br>return 0;<br>}<br><br>int StrCmp(const char *str1, const char *str2)<br>{<br>//省略判断空指针(自己保证)<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><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>}<br><br>分析：<br>int arr[] = {6,7,8,9,10};<br>int *ptr = arr;<br>*(ptr++)+=123;<br>printf(&#8220; %d %d &#8221;, *ptr, *(++ptr));<br>输出：8 8<br>过程：对于*(ptr++)+=123;先做加法6+123，然后++，指针指向7；对于printf(&#8220; %d %d &#8221;, *ptr, *(++ptr));从后往前执行，指针先++，指向8，然后输出8，紧接着再输出8<br><br>华为全套完整试题<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>Pointer=Pointer-&gt;next;<br>if(Pointer-&gt;number==key)<br>{<br>Back-&gt;next=Pointer-&gt;next;<br>free(Pointer);<br>break;<br>}<br>void delete(Node* p)<br>{<br>if(Head = Node)<br><br>while(p)<br>}<br><br>有一个16位的整数，每4位为一个数，写函数求他们的和。<br>解释：<br>整数1101010110110111<br>和 1101+0101+1011+0111<br>感觉应该不难，当时对题理解的不是很清楚，所以写了一个函数，也不知道对不对。<br>疑问：<br>既然是16位的整数，1101010110110111是2进制的，那么函数参数怎么定义呢，请大虾指教。<br>答案：用十进制做参数，计算时按二进制考虑。<br>/* n就是16位的数，函数返回它的四个部分之和 */<br>char SumOfQuaters(unsigned short n)<br>{<br>char c = 0;<br>int i = 4;<br>do<br>{<br>c += n &amp; 15;<br>n = n &gt;&gt; 4;<br>} while (--i);<br><br>return c;<br>}<br><br><br><br>有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.（华为）<br>#include&lt;iostream.h&gt;<br><br>int main()<br>{<br>int a[] = {10,6,9,5,2,8,4,7,1,3};<br>int len = sizeof(a) / sizeof(int);<br>int temp;<br><br>for(int i = 0; i &lt; len; )<br>{<br>temp = a[a[i] - 1];<br>a[a[i] - 1] = a[i];<br>a[i] = temp;<br><br>if ( a[i] == i + 1)<br>i++;<br>}<br>for (int j = 0; j &lt; len; j++)<br>cout&lt;&lt;a[j]&lt;&lt;",";<br><br>return 0;<br>}<br><br>（慧通）<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>}<br><br>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;"释放空间成功!"&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>}<br><br><br>分析下面的代码：<br>char *a = "hello";<br>char *b = "hello";<br>if(a= =b)<br>printf("YES");<br>else<br>printf("NO");<br>这个简单的面试题目,我选输出 no(对比的应该是指针地址吧),可在VC是YES 在C是NO<br>lz的呢，是一个常量字符串。位于静态存储区，它在程序生命期内恒定不变。如果编译器优化的话，会有可能a和b同时指向同一个hello的。则地址相同。如果编译器没有优化，那么就是两个不同的地址，则不同<br><br><img src ="http://www.cppblog.com/hyjune/aggbug/53727.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:11 <a href="http://www.cppblog.com/hyjune/articles/53727.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] C面试总结(一)</title><link>http://www.cppblog.com/hyjune/articles/53726.html</link><dc:creator>martin0501</dc:creator><author>martin0501</author><pubDate>Tue, 17 Jun 2008 09:04:00 GMT</pubDate><guid>http://www.cppblog.com/hyjune/articles/53726.html</guid><wfw:comment>http://www.cppblog.com/hyjune/comments/53726.html</wfw:comment><comments>http://www.cppblog.com/hyjune/articles/53726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hyjune/comments/commentRss/53726.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hyjune/services/trackbacks/53726.html</trackback:ping><description><![CDATA[from: <a href="http://blog.chinaunix.net/u/22968/showart_426807.html">http://blog.chinaunix.net/u/22968/showart_426807.html</a><br><br>
<div>
<p>&nbsp;4. static有什么用途？（请至少说明两种）<br>1.限制变量的作用域<br>2.设置变量的存储域<br>7. 引用与指针有什么区别？<br>1) 引用必须被初始化，指针不必。<br>2) 引用初始化以后不能被改变，指针可以改变所指的对象。<br>2) 不存在指向空值的引用，但是存在指向空值的指针。<br><br>8. 描述实时系统的基本特性<br>在特定时间内完成特定的任务，实时性与可靠性<br>9. 全局变量和局部变量在内存中是否有区别？如果有，是什么区别？<br>全局变量储存在静态数据库，局部变量在堆栈<br>10. 什么是平衡二叉树？<br>左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1<br>11. 堆栈溢出一般是由什么原因导致的？<br>没有回收垃圾资源<br>12. 什么函数不能声明为虚函数？<br>constructor<br>13. 冒泡排序算法的时间复杂度是什么？<br>O(n^2)<br>14. 写出float x 与&#8220;零值&#8221;比较的if语句。<br>if(x&gt;0.000001&amp;&amp;x&lt;-0.000001)<br>16. Internet采用哪种网络协议？该协议的主要层次结构？<br>tcp/ip 应用层/传输层/网络层/数据链路层/物理层<br>17. Internet物理地址和IP地址转换采用什么协议？<br>ARP (Address Resolution Protocol)（地址解析協議）<br>18.IP地址的编码分为哪俩部分？<br>IP地址由两部分组成，网络号和主机号。不过是要和&#8220;子网掩码&#8221;按位与上之后才能区分哪些是网络位哪些是主机位。<br><br><br>2.用户输入M,N值，从1至N开始顺序循环数数，每数到M输出该数值，直至全部输出。写出C程序。<br>循环链表，用取余操作做<br>3.不能做switch()的参数类型是：<br>switch的参数不能为实型。<br><br>華為<br>1、局部变量能否和全局变量重名？<br>答：能，局部会屏蔽全局。要用全局变量，需要使用"::"<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&#8230;&#8230;while和while&#8230;&#8230;do有什么区别？<br>答：前一个循环一遍再判断，后一个判断以后再循环<br>6、请写出下列代码的输出内容<br>#include&lt;stdio.h&gt;<br>main()<br>{<br>int a,b,c,d;<br>a=10;<br>b=a++;<br>c=++a;<br>d=10*a++;<br>printf("b，c，d：%d，%d，%d"，b，c，d）;<br>return 0;<br>} <br>答：10，12，120<br><br>1、static全局变量与普通的全局变量有什么区别？static局部变量和普通局部变量有什么区别？static函数与普通函数有什么区别？<br>全
局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式， 静态全局变量当然也是静态存储方式。
这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序，
当一个源程序由多个源文件组成时，非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域， 即只在定义该变量的源文件内有效，
在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内，只能为该源文件内的函数公用，
因此可以避免在其它源文件中引起错误。<br>从以上分析可以看出， 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域， 限制了它的使用范围。<br>static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static)，内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数，应该在一个头文件中说明，要使用这些函数的源文件要包含这个头文件<br><br>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("%d",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>队列先进先出，栈后进先出</p>
<p>5、写出下列代码的输出内容<br>#include&lt;stdio.h&gt;<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*);<br><br>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("%d\n",*arg2);<br>}<br><br>main()<br>{<br>int a;<br>show(multi,10,&amp;a);<br>return 0;<br>}<br>答：110<br>7、请找出下面代码中的所以错误<br>说明：以下代码是把一个字符串倒序，如&#8220;abcd&#8221;倒序后变为&#8220;dcba&#8221;<br><br>1、#include"string.h"<br>2、main()<br>3、{<br>4、 char*src="hello,world";<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("%s",dest);<br>13、 return 0;<br>14、} <br>答：<br>方法1：<br>int main(){<br>char* src = "hello,world";<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("%s\n",dest);<br>free(dest);// 使用完，应当释放空间，以免造成内存汇泄露<br>return 0;<br>}<br>方法2：<br>#include &lt;stdio.h&gt;<br>#include &lt;string.h&gt;<br>main()<br>{<br>char str[]="hello,world";<br>int len=strlen(str);<br>char t;<br>for(int i=0; i&lt;len/2; i++)<br>{<br>t=str[i]; <br>str[i]=str[len-i-1]; str[len-i-1]=t;<br>}<br>printf("%s",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>n^3+1(当n为奇数1，3，5)<br>答案：63<br>2.用两个栈实现一个队列的功能？要求给出算法和思路！<br>设2个栈为A,B, 一开始均为空.<br><br>入队:<br>将新元素push入栈A;<br><br>出队:<br>(1)判断栈B是否为空；<br>(2)如果不为空，则将栈A中所有元素依次pop出并push到栈B；<br>(3)将栈B的栈顶元素pop出；<br><br>这样实现的队列入队和出队的平摊复杂度都还是O(1), 比上面的几种方法要好。3.在c语言库函数中将一个字符转换成整型的函数是atool()吗，这个函数的原型是什么？<br>函数名: atol <br>功 能: 把字符串转换成长整型数 <br>用 法: long atol(const char *nptr); <br>程序例: <br>#include &lt;stdlib.h&gt; <br>#include &lt;stdio.h&gt; <br>int main(void) <br>{ <br>long l; <br>char *str = "98765432"; <br><br>l = atol(lstr); <br>printf("string = %s integer = %ld\n", str, l); <br>return(0); <br>}<br><br></p>
<p>2.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?<br>c用宏定义，c++用inline<br>3.直接链接两个信令点的一组链路称作什么?<br>PPP点到点连接<br>4.接入网用的是什么接口?<br>5.voip都用了那些协议?<br>6.软件测试都有那些种类?<br>黑盒：针对系统功能的测试 白合：测试函数功能，各函数接口<br>7.确定模块的功能和模块的接口是在软件设计的那个队段完成的?<br>概要设计阶段<br>8.enum string<br>{<br>x1,<br>x2,<br>x3=10,<br>x4,<br>x5,<br>}x;<br>问x= 0x801005，0x8010f4 ;<br>9.unsigned char *p1;<br>unsigned long *p2;<br>p1=(unsigned char *)0x801000;<br>p2=(unsigned long *)0x810000;<br>请问p1+5= ;<br>p2+5= ;<br>三.选择题:<br>1.Ethternet链接到Internet用到以下那个协议?<br>A.HDLC;B.ARP;C.UDP;D.TCP;E.ID<br>2.属于网络层协议的是:<br>A.TCP;B.IP;C.ICMP;D.X.25<br>3.Windows消息调度机制是:<br>A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;<br>4.unsigned short hash(unsigned short key)<br>{<br>return (key&gt;&gt;)%256<br>}<br>请问hash(16),hash(256)的值分别是:<br>A.1.16;B.8.32;C.4.16;D.1.32<br>四.找错题:<br>1.请问下面程序有什么错误?<br>int a[60][250][1000],i,j,k;<br>for(k=0;k&lt;=1000;k++)<br>for(j=0;j&lt;250;j++)<br>for(i=0;i&lt;60;i++)<br>a[i][j][k]=0;<br>把循环语句内外换一下<br>2.#define Max_CB 500<br>void LmiQueryCSmd(Struct MSgCB * pmsg)<br>{<br>unsigned char ucCmdNum;<br>......<br><br>for(ucCmdNum=0;ucCmdNum&lt;Max_CB;ucCmdNum++)<br>{<br>......;<br>}<br>死循环<br>3.以下是求一个数的平方的程序,请找出错误:<br>#define SQUARE(a)((a)*(a))<br>int a=5;<br>int b;<br>b=SQUARE(a++);<br>4.typedef unsigned char BYTE<br>int examply_fun(BYTE gt_len; BYTE *gt_code)<br>{ <br>BYTE *gt_buf;<br>gt_buf=(BYTE *)MALLOC(Max_GT_Length);<br>......<br>if(gt_len&gt;Max_GT_Length)<br>{<br>return GT_Length_ERROR; <br>}<br>.......<br>}<br>五.问答题:<br>1.IP Phone的原理是什么?<br>IPV6<br>2.TCP/IP通信建立的过程怎样，端口有什么作用？<br>三次握手，确定是哪个应用程序使用该协议<br>3.1号信令和7号信令有什么区别，我国某前广泛使用的是那一种？<br>4.列举5种以上的电话新业务？<br><br>微软亚洲技术中心的面试题！！！<br>1．进程和线程的差别。<br>线程是指进程内的一个执行单元,也是进程内的可调度实体.<br>与进程的区别:<br>(1)调度：线程作为调度和分配的基本单位，进程作为拥有资源的基本单位<br>(2)并发性：不仅进程之间可以并发执行，同一个进程的多个线程之间也可并发执行<br>(3)拥有资源：进程是拥有资源的一个独立单位，线程不拥有系统资源，但可以访问隶属于进程的资源. <br>(4)系统开销：在创建或撤消进程时，由于系统都要为之分配和回收资源，导致系统的开销明显大于创建或撤消线程时的开销。<br>2.测试方法 <br>人工测试：个人复查、抽查和会审<br>机器测试：黑盒测试和白盒测试<br><br>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，互斥，写标志到文件或注册表,共享内存。.　 <br>12．如何截取键盘的响应，让所有的&#8216;a&#8217;变成&#8216;b&#8217;？<br>键盘钩子SetWindowsHookEx<br>　13．Apartment在COM中有什么用？为什么要引入？<br>　14．存储过程是什么？有什么用？有什么优点？<br>我的理解就是一堆sql的集合，可以建立非常复杂的查询，编译运行，所以运行一次后，以后再运行速度比单独执行SQL快很多<br>　15．Template有什么特点？什么时候用？<br>16．谈谈Windows DNA结构的特点和优点。<br><br><br>网络编程中设计并发服务器，使用多进程 与 多线程 ，请问有什么区别？<br>1，进程：子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。<br>2，线程：相对与进程而言，线程是一个更加接近与执行体的概念，它可以与同进程的其他线程共享数据，但拥有自己的栈空间，拥有独立的执行序列。<br>两者都可以提高程序的并发度，提高程序运行效率和响应时间。<br>线程和进程在使用上各有优缺点：线程执行开销小，但不利于资源管理和保护；而进程正相反。同时，线程适合于在SMP机器上运行，而进程则可以跨机器迁移。<br><br>思科<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></p>
<p>慧通：<br>什么是预编译<br>何时需要预编译：<br>１、总是使用不经常改动的大型代码体。 <br>２、程序由多个模块组成，所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下，可以将所有包含文件预编译为一个预编译头。<br>char * const p;<br>char const * p<br>const char *p<br><br>上述三个有什么区别？<br>char * const p; //常量指针，p的值不可以修改<br>char const * p；//指向常量的指针，指向的常量值不可以改<br>const char *p； //和char const *p<br><br>char str1[] = "abc";<br>char str2[] = "abc";<br><br>const char str3[] = "abc";<br>const char str4[] = "abc";<br><br>const char *str5 = "abc";<br>const char *str6 = "abc";<br><br>char *str7 = "abc";<br>char *str8 = "abc";<br><br><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;<br><br>结果是：0 0 1 1<br>解答：str1,str2,str3,str4是数组变量，它们有各自的内存空间；<br>而str5,str6,str7,str8是指针，它们指向相同的常量区域。<br><br><br>12. 以下代码中的两个sizeof用法有问题吗？[C易]<br>void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母<br>{<br>for( size_t i=0; i&lt;sizeof(str)/sizeof(str[0]); ++i )<br>if( 'a'&lt;=str[i] &amp;&amp; str[i]&lt;='z' )<br>str[i] -= ('a'-'A' );<br>}<br>char str[] = "aBcDe";<br>cout &lt;&lt; "str字符长度为: " &lt;&lt; sizeof(str)/sizeof(str[0]) &lt;&lt; endl;<br>UpperCase( str );<br>cout &lt;&lt; str &lt;&lt; endl;<br><br>答：
函数内的sizeof有问题。根据语法，sizeof如用于数组，只能测出静态数组的大小，无法检测动态分配的或外部数组大小。函数外的str是一个静态
定义的数组，因此其大小为6，函数内的str实际只是一个指向字符串的指针，没有任何额外的与数组相关的信息，因此sizeof作用于上只将其当指针看，
一个指针为4个字节，因此返回4。<br><br>一个32位的机器,该机器的指针是多少位<br>指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。<br><br>main()<br>{<br>int a[5]={1,2,3,4,5};<br>int *ptr=(int *)(&amp;a+1);<br><br>printf("%d,%d",*(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].<br><br><br>1.请问以下代码有什么问题：<br>int main()<br>{<br>char a;<br>char *str=&amp;a;<br>strcpy(str,"hello");<br>printf(str);<br>return 0;<br>}<br>没有为str分配内存空间，将会发生异常<br>问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果，但因为越界进行内在读写而导致程序崩溃。<br><br>char* s="AAA";<br>printf("%s",s);<br>s[0]='B';<br>printf("%s",s);<br>有什么错？<br>"AAA"是字符串常量。s是指针，指向这个字符串常量，所以声明s的时候就有问题。<br>cosnt char* s="AAA";<br>然后又因为是常量，所以对是s[0]的赋值操作是不合法的。</p>
<p>1、写一个&#8220;标准&#8221;宏，这个宏输入两个参数并返回较小的一个。<br>.#define Min(X, Y) ((X)&gt;(Y)?(Y):(X))//结尾没有;<br>2、嵌入式系统中经常要用到无限循环，你怎么用C编写死循环。<br>while(1){}或者for(;;)<br>3、关键字static的作用是什么？<br>定义静态变量<br>4、关键字const有什么含意？<br>表示常量不可以修改的变量。<br>5、关键字volatile有什么含意？并举出三个不同的例子？<br>提示编译器对象的值可能在编译器未监测到的情况下改变。<br><br><br>int (*s[10])(int) 表示的是什么啊<br>int (*s[10])(int) 函数指针数组，每个指针指向一个int func(int param)的函数。<br><br><br>1.有以下表达式：<br>int a=248; b=4;int const c=21;const int *d=&amp;a;<br>int *const e=&amp;b;int const *f const =&amp;a;<br>请问下列表达式哪些会被编译器禁止？为什么？<br>*c=32;d=&amp;b;*d=43;e=34;e=&amp;a;f=0x321f;<br>*c 这是个什么东东，禁止<br>*d 说了是const， 禁止<br>e = &amp;a 说了是const 禁止<br>const *f const =&amp;a; 禁止<br>2.交换两个变量的值，不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;<br>有两种解法, 一种用算术算法, 一种用^(异或)<br>a = a + b;<br>b = a - b;<br>a = a - b; <br>or<br>a = a^b;// 只能对int,char..<br>b = a^b;<br>a = a^b;<br>or<br>a ^= b ^= a;<br>3.c和c++中的struct有什么不同？<br>c和c++中struct的主要区别是c中的struct不可以含有成员函数，而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同，struct默认为public，而class默认为private<br>4.#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>void getmemory(char *p)<br>{<br>p=(char *) malloc(100);<br>strcpy(p,"hello world");<br>}<br>int main( )<br>{<br>char *str=NULL;<br>getmemory(str);<br>printf("%s/n",str);<br>free(str);<br>return 0;<br>}<br>程序崩溃，getmemory中的malloc 不能返回动态内存， free（）对str操作很危险<br>5.char szstr[10];<br>strcpy(szstr,"0123456789");<br>产生什么结果？为什么？<br>长度不一样，会造成非法的OS<br>6.列举几种进程的同步机制，并比较其优缺点。<br>原子操作 <br>信号量机制<br>自旋锁<br>管程，会合，分布式系统<br><br>7.进程之间通信的途径<br>共享存储系统<br>消息传递系统<br>管道：以文件系统为基础<br>11.进程死锁的原因<br>资源竞争及进程推进顺序非法<br>12.死锁的4个必要条件<br>互斥、请求保持、不可剥夺、环路<br>13.死锁的处理<br>鸵鸟策略、预防策略、避免策略、检测与解除死锁<br>15. 操作系统中进程调度策略有哪几种？<br>FCFS(先来先服务)，优先级，时间片轮转，多级反馈<br>8.类的静态成员和非静态成员有何区别？<br>类的静态成员每个类只有一个，非静态成员每个对象一个<br>9.纯虚函数如何定义？使用时应注意什么？<br>virtual void f()=0;<br>是接口，子类必须要实现<br>10.数组和链表的区别<br>数组：数据顺序存储，固定大小<br>连表：数据可以随机存储，大小可动态改变<br><br>12.ISO的七层模型是什么？tcp/udp是属于哪一层？tcp/udp有何优缺点？<br>应用层<br>表示层<br>会话层<br>运输层<br>网络层<br>物理链路层<br>物理层<br>tcp /udp属于运输层<br>TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。<br>与 TCP 不同， UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单， UDP 头包含很少的字节，比 TCP 负载消耗少。<br>tcp: 提供稳定的传输服务，有流量控制，缺点是包头大，冗余性不好<br>udp: 不提供稳定的服务，包头小，开销小 <br><br><br>1：(void *)ptr 和 (*(void**))ptr的结果是否相同？其中ptr为同一个指针<br>.(void *)ptr 和 (*(void**))ptr值是相同的<br>2：int main()<br>{<br>int x=3;<br>printf("%d",x);<br>return 1;<br><br>}<br>问函数既然不会被其它函数调用，为什么要返回1？<br>mian中，c标准认为0表示成功，非0表示错误。具体的值是某中具体出错信息<br><br><br>1，要对绝对地址0x100000赋值，我们可以用<br>(unsigned int*)0x100000 = 1234;<br>那么要是想让程序跳转到绝对地址是0x100000去执行，应该怎么做？<br>*((void (*)( ))0x100000 ) ( );<br>首先要将0x100000强制转换成函数指针,即:<br>(void (*)())0x100000<br>然后再调用它:<br>*((void (*)())0x100000)();<br>用typedef可以看得更直观些:<br>typedef void(*)() voidFuncPtr;<br>*((voidFuncPtr)0x100000)();<br>2，已知一个数组table，用一个宏定义，求出数据的元素个数<br>#define NTBL<br>#define NTBL (sizeof(table)/sizeof(table[0]))<br><br>面试题: 线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈?<br>进程是死的，只是一些资源的集合，真正的程序执行都是线程来完成的，程序启动的时候操作系统就帮你创建了一个主线程。<br><br>每个线程有自己的堆栈。<br>DLL
中有没有独立的堆栈，这个问题不好回答，或者说这个问题本身是否有问题。因为DLL中的代码是被某些线程所执行，只有线程拥有堆栈，如果DLL中的代码是
EXE中的线程所调用，那么这个时候是不是说这个DLL没有自己独立的堆栈？如果DLL中的代码是由DLL自己创建的线程所执行，那么是不是说DLL有独
立的堆栈？<br><br>以上讲的是堆栈，如果对于堆来说，每个DLL有自己的堆，所以如果是从DLL中动态分配的内存，最好是从DLL中删除，如果你从DLL中分配内存，然后在EXE中，或者另外一个DLL中删除，很有可能导致程序崩溃<br><br><br>unsigned short A = 10;<br>printf("~A = %u\n", ~A);<br><br>char c=128; <br>printf("c=%d\n",c);<br><br>输出多少？并分析过程<br>第一题，～A ＝0xfffffff5,int值 为－11，但输出的是uint。所以输出4294967285<br>第二题，c＝0x10,输出的是int，最高位为1，是负数，所以它的值就是0x00的补码就是128，所以输出－128。<br>这两道题都是在考察二进制向int或uint转换时的最高位处理。<br><br>分析下面的程序：<br>void GetMemory(char **p,int num)<br>{<br>*p=(char *)malloc(num);<br><br>} <br>int main()<br>{<br>char *str=NULL;<br><br>GetMemory(&amp;str,100);<br><br>strcpy(str,"hello");<br><br>free(str);<br><br>if(str!=NULL)<br>{<br>strcpy(str,"world");<br>} <br><br>printf("\n str is %s",str);<br>getchar();<br>} <br>问输出结果是什么？希望大家能说说原因，先谢谢了<br>输出str is world。<br>free 只是释放的str指向的内存空间,它本身的值还是存在的.<br>所以free之后，有一个好的习惯就是将str=NULL.<br>此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,<br>尽管这段程序确实是存在大大的问题（上面各位已经说得很清楚了），但是通常会打印出world来。<br>这是因为，进程中的内存管理一般不是由操作系统完成的，而是由库函数自己完成的。<br>当
你malloc一块内存的时候，管理库向操作系统申请一块空间（可能会比你申请的大一些），然后在这块空间中记录一些管理信息（一般是在你申请的内存前面
一点），并将可用内存的地址返回。但是释放内存的时候，管理库通常都不会将内存还给操作系统，因此你是可以继续访问这块地址的，只不过。。。。。。。。楼
上都说过了，最好别这么干。<br><br>char a[10],strlen(a)为什么等于15？运行的结果<br><br>#include "stdio.h"<br>#include "string.h"<br><br>void main()<br>{<br><br>char aa[10];<br>printf("%d",strlen(aa));<br>}<br><br>sizeof()和初不初始化，没有关系；<br>strlen()和初始化有关。<br><br><br>char (*str)[20];/*str是一个数组指针，即指向数组的指针．*/<br>char *str[20];/*str是一个指针数组，其元素为指针型数据．*/<br><br>long a=0x801010;<br>a+5=?<br>0x801010用二进制表示为：&#8220;1000 0000 0001 0000 0001 0000&#8221;，十进制的值为8392720，再加上5就是8392725罗<br><br>1)给定结构struct A <br>{<br>char t:4;<br>char k:4;<br>unsigned short i:8;<br>unsigned long m;<br>};问sizeof(A) = ?<br>给定结构struct A <br>{<br>char t:4; 4位<br>char k:4; 4位<br>unsigned short i:8; 8位 <br>unsigned long m; // 偏移2字节保证4字节对齐<br>}; // 共8字节<br>2)下面的函数实现在一个数上加一个数，有什么错误？请改正。<br>int add_n ( int n )<br>{<br>static int i = 100;<br>i += n;<br>return i;<br>}<br>当你第二次调用时得不到正确的结果，难道你写个函数就是为了调用一次？问题就出在 static上？<br><br><br>// 帮忙分析一下<br>#include&lt;iostream.h&gt;<br>#include &lt;string.h&gt;<br>#include &lt;malloc.h&gt;<br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;memory.h&gt;<br>typedef struct AA<br>{<br>int b1:5;<br>int b2:2;<br>}AA;<br>void main()<br>{<br>AA aa;<br>char cc[100];<br>strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");<br>memcpy(&amp;aa,cc,sizeof(AA));<br>cout &lt;&lt; aa.b1 &lt;&lt;endl;<br>cout &lt;&lt; aa.b2 &lt;&lt;endl;<br>}<br>答案是 -16和１<br>首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.<br>经过strcpy和memcpy后,aa的4个字节所存放的值是:<br>0,1,2,3的ASC码，即00110000,00110001,00110010,00110011<br>所以，最后一步：显示的是这４个字节的前５位，和之后的２位<br>分别为：10000,和01<br>因为int是有正负之分　　所以：答案是-16和１<br><br>求函数返回值，输入x=9999; <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>知道了这是统计9999的二进制数值中有多少个1的函数，且有<br>9999＝9&#215;1024＋512＋256＋15<br><br>9&#215;1024中含有1的个数为2；<br>512中含有1的个数为1；<br>256中含有1的个数为1；<br>15中含有1的个数为4；<br>故共有1的个数为8，结果为8。<br>1000 - 1 = 0111，正好是原数取反。这就是原理。<br>用这种方法来求1的个数是很效率很高的。<br>不必去一个一个地移位。循环次数最少。<br><br>int a,b,c 请写函数实现C=a+b ,不可以改变数据类型,如将c改为long int,关键是如何处理溢出问题<br>bool add (int a, int b,int *c)<br>{<br>*c=a+b;<br>return (a&gt;0 &amp;&amp; b&gt;0 &amp;&amp;(*c&lt;a || *c&lt;b) || (a&lt;0 &amp;&amp; b&lt;0 &amp;&amp;(*c&gt;a || *c&gt;b)));<br>}<br><br><br>分析：<br>struct bit <br>{ int a:3; <br>int b:2; <br>int c:3; <br>}; <br>int main() <br>{ <br>bit s; <br>char *c=(char*)&amp;s; <br>cout&lt;&lt;sizeof(bit)&lt;&lt;endl;<br>*c=0x99;<br>cout &lt;&lt; s.a &lt;&lt;endl &lt;&lt;s.b&lt;&lt;endl&lt;&lt;s.c&lt;&lt;endl; <br>int a=-1;<br>printf("%x",a);<br>return 0; <br>} <br>输出为什么是<br>4<br>1<br>-1<br>-4<br>ffffffff<br>因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100<br>当c为有符合数时, c = 100, 最高1为表示c为负数，负数在计算机用补码表示，所以c = -4;同理 <br>b = -1;<br>当c为有符合数时, c = 100,即 c = 4,同理 b = 3<br><br><br>位域 ： <br>有
些信息在存储时，并不需要占用一个完整的字节， 而只需占几个或一个二进制位。例如在存放一个开关量时，只有0和1 两种状态，
用一位二进位即可。为了节省存储空间，并使处理简便，Ｃ语言又提供了一种数据结构，称为&#8220;位域&#8221;或&#8220;位段&#8221;。所谓&#8220;位域&#8221;是把一个字节中的二进位划分为几
个不同的区域， 并说明每个区域的位数。每个域有一个域名，允许在程序中按域名进行操作。
这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿，其形式为： <br>struct 位域结构名 <br>{ 位域列表 }; <br>其中位域列表的形式为： 类型说明符 位域名：位域长度 <br>例如： <br>struct bs <br>{ <br>int a:8; <br>int b:2; <br>int c:6; <br>}; <br>位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明，同时定义说明或者直接说明这三种方式。例如： <br>struct bs <br>{ <br>int a:8; <br>int b:2; <br>int c:6; <br>}data; <br>说明data为bs变量，共占两个字节。其中位域a占8位，位域b占2位，位域c占6位。对于位域的定义尚有以下几点说明： <br><br>1. 一个位域必须存储在同一个字节中，不能跨两个字节。如一个字节所剩空间不够存放另一位域时，应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如： <br>struct bs <br>{ <br>unsigned a:4 <br>unsigned :0 /*空域*/ <br>unsigned b:4 /*从下一单元开始存放*/ <br>unsigned c:4 <br>} <br>在这个位域定义中，a占第一字节的4位，后4位填0表示不使用，b从第二字节开始，占用4位，c占用4位。 <br><br>2. 由于位域不允许跨两个字节，因此位域的长度不能大于一个字节的长度，也就是说不能超过8位二进位。 <br><br>3. 位域可以无位域名，这时它只用来作填充或调整位置。无名的位域是不能使用的。例如： <br>struct k <br>{ <br>int a:1 <br>int :2 /*该2位不能使用*/ <br>int b:3 <br>int c:2 <br>}; <br>从以上分析可以看出，位域在本质上就是一种结构类型， 不过其成员是按二进位分配的。 <br><br>二、位域的使用位域的使用和结构成员的使用相同，其一般形式为： 位域变量名&#8226;位域名 位域允许用各种格式输出。 <br>main(){ <br>struct bs <br>{ <br>unsigned a:1; <br>unsigned b:3; <br>unsigned c:4; <br>} bit,*pbit; <br>bit.a=1; <br>bit.b=7; <br>bit.c=15; <br>pri<br><br>改错：<br>#include &lt;stdio.h&gt;<br><br>int main(void) {<br><br>int **p;<br>int arr[100];<br><br>p = &amp;arr;<br><br>return 0;<br>}<br>解答：<br>搞错了,是指针类型不同,<br>int **p; //二级指针<br>&amp;arr; //得到的是指向第一维为100的数组的指针<br>#include &lt;stdio.h&gt;<br>int main(void) {<br>int **p, *q;<br>int arr[100];<br>q = arr;<br>p = &amp;q;<br>return 0;<br>}<br><br><br>下面这个程序执行后会有什么错误或者效果:<br>#define MAX 255<br>int main()<br>{<br>unsigned char A[MAX],i;//i被定义为unsigned char<br>for (i=0;i&lt;=MAX;i++)<br>A[i]=i;<br>}<br>解答：死循环加数组越界访问（C/C++不进行数组越界检查）<br>MAX=255 <br>数组A的下标范围为:0..MAX-1,这是其一..<br>其二.当i循环到255时,循环内执行:<br>A[255]=255;<br>这句本身没有问题..但是返回for (i=0;i&lt;=MAX;i++)语句时,<br>由于unsigned char的取值范围在(0..255),i++以后i又为0了..无限循环下去.<br><br>struct name1{<br>char str;<br>short x;<br>int num;<br>}<br><br>struct name2{<br>char str;<br>int num;<br>short x;<br>}<br><br>sizeof(struct name1)=8,sizeof(struct name2)=12<br>在第二个结构中，为保证num按四个字节对齐，char后必须留出3字节的空间；同时为保证整个结构的自然对齐（这里是4字节对齐），在x后还要补齐2个字节，这样就是12字节。<br><br>intel：<br>A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里（栈还是堆或者其他的）?<br>static的全局变量，表明这个变量仅在本模块中有意义，不会影响其他模块。<br>他们都放在数据区，但是编译器对他们的命名是不同的。<br>如果要使变量在其他模块也有意义的话，需要使用extern关键字。<br><br>struct s1<br>{<br>int i: 8;<br>int j: 4;<br>int a: 3;<br>double b;<br>};<br><br>struct s2<br>{<br>int i: 8;<br>int j: 4;<br>double b;<br>int a:3;<br>};<br><br>printf("sizeof(s1)= %d\n", sizeof(s1));<br>printf("sizeof(s2)= %d\n", sizeof(s2));<br>result: 16, 24<br>第一个struct s1<br>{<br>int i: 8;<br>int j: 4;<br>int a: 3;<br>double b;<br>};<br>理
论上是这样的，首先是i在相对0的位置，占8位一个字节，然后，j就在相对一个字节的位置，由于一个位置的字节数是4位的倍数，因此不用对齐，就放在那里
了，然后是a，要在3位的倍数关系的位置上，因此要移一位，在15位的位置上放下，目前总共是18位，折算过来是2字节2位的样子，由于double是8
字节的，因此要在相对0要是8个字节的位置上放下，因此从18位开始到8个字节之间的位置被忽略，直接放在8字节的位置了，因此，总共是16字节。<br><br>第二个最后会对照是不是结构体内最大数据的倍数，不是的话，会补成是最大数据的倍数</p>
</div>
<br><br> <img src ="http://www.cppblog.com/hyjune/aggbug/53726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hyjune/" target="_blank">martin0501</a> 2008-06-17 17:04 <a href="http://www.cppblog.com/hyjune/articles/53726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>