📄 c-c++ 笔试、面试题目大汇总.htm
字号:
}half; <BR>
}number; <BR>
number.i=0x4241;
/*联合成员赋值*/
<BR>
printf("%c%c\n", number.half.first, mumber.half.second);
<BR>
number.half.first='a'; /*联合中结构成员赋值*/
<BR>
number.half.second='b';
<BR>
printf("%x\n", number.i);
<BR> getch();
<BR> } <BR>答案: AB
(0x41对应'A',是低位;Ox42对应'B',是高位)</FONT></DIV>
<DIV><FONT size=2> 6261
(number.i和number.half共用一块地址空间)</FONT></DIV>
<DIV><FONT size=2><STRONG>11. 已知strcpy的函数原型:<EM>char *strcpy(char
*strDest, const char *strSrc)</EM>其中strDest 是目的字符串,strSrc
是源字符串。不调用C++/C 的字符串库函数,请编写函数 strcpy。</STRONG></FONT></DIV>
<DIV><BR><FONT size=2>答案:<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++) !=
‘\0’)<BR>;<BR>return tempptr ;<BR>}</FONT></DIV>
<DIV><FONT size=2><STRONG>12. 已知String类定义如下:</STRONG></FONT></DIV>
<DIV><FONT size=2><STRONG>class
String<BR>{<BR>public:<BR>String(const char *str = NULL); //
通用构造函数<BR>String(const String &another); // 拷贝构造函数<BR>~
String(); // 析构函数<BR>String & operater =(const String &rhs);
// 赋值函数<BR>private:<BR>char *m_data; //
用于保存字符串<BR>};</STRONG></FONT></DIV>
<DIV><FONT size=2><STRONG>尝试写出类的成员函数实现。</STRONG></FONT></DIV>
<DIV><FONT size=2>答案:</FONT></DIV>
<DIV><FONT size=2>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> }</FONT></DIV>
<DIV><FONT size=2>} </FONT></DIV>
<DIV><FONT size=2>String::String(const String
&another)<BR>{<BR> m_data = new
char[strlen(another.m_data) + 1];<BR>
strcpy(m_data,other.m_data);<BR>}</FONT></DIV>
<DIV><BR><FONT size=2>String& String::operator =(const String
&rhs)<BR>{<BR> if ( this ==
&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>}</FONT></DIV>
<DIV><BR><FONT size=2>String::~String()<BR>{<BR>
delete []m_data ;<BR>}</FONT></DIV>
<DIV><FONT size=2><STRONG>13. .h头文件中的ifndef/define/endif
的作用?</STRONG></FONT></DIV>
<DIV><FONT size=2>答:防止该头文件被重复引用。</FONT></DIV>
<DIV><FONT size=2><STRONG>14. #i nclude<file.h> 与 #i nclude
"file.h"的区别?</STRONG></FONT></DIV>
<DIV><FONT size=2>答:前者是从Standard
Library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h。</FONT></DIV>
<DIV><FONT size=2><STRONG>15.在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern
“C”?</STRONG></FONT></DIV>
<DIV><FONT
size=2>首先,作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,<STRONG>其声明的函数和变量可以在本模块或其它模块中使用</STRONG>。</FONT></DIV>
<DIV><FONT
size=2>通常,<STRONG>在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。</STRONG>例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在连接阶段中从模块A编译生成的目标代码中找到此函数</FONT></DIV>
<DIV><FONT size=2>extern "C"是连接申明(linkage declaration),被extern
"C"修饰的变量和函数是按照C语言方式编译和连接的,来看看C++中对类似C的函数是怎样编译的:<BR><BR>作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为:
</FONT></DIV>
<DIV><FONT size=2>void foo( int x, int y );<BR> </FONT></DIV>
<DIV><FONT
size=2>该函数被C编译器编译后在符号库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“<STRONG>mangled
name</STRONG>”)。<BR><BR>_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。例如,在C++中,函数void
foo( int x, int y )与void foo( int x, float y
)编译生成的符号是不相同的,后者为_foo_int_float。</FONT></DIV>
<DIV><FONT
size=2>同样地,C++中的变量除支持局部变量外,还支持类成员变量和全局变量。用户所编写程序的类成员变量可能与全局变量同名,我们以"."来区分。而本质上,编译器在进行编译时,与函数的处理相似,也为类中的变量取了一个独一无二的名字,这个名字与用户程序中同名的全局变量名字不同。<BR><BR><STRONG>未加extern
"C"声明时的连接方式</STRONG></FONT></DIV>
<DIV><FONT size=2>假设在C++中,模块A的头文件如下:</FONT></DIV>
<DIV><FONT size=2>// 模块A头文件 moduleA.h<BR>#ifndef
MODULE_A_H<BR>#define MODULE_A_H<BR>int foo( int x, int y
);<BR>#endif </FONT></DIV>
<DIV><FONT size=2>在模块B中引用该函数:</FONT></DIV>
<DIV><FONT size=2>// 模块B实现文件 moduleB.cpp<BR>#i nclude
"moduleA.h"<BR>foo(2,3);<BR> </FONT></DIV>
<DIV><FONT
size=2>实际上,在连接阶段,连接器会从模块A生成的目标文件moduleA.obj中寻找_foo_int_int这样的符号!<BR><BR><STRONG>加extern
"C"声明后的编译和连接方式</STRONG><BR><BR>加extern
"C"声明后,模块A的头文件变为:</FONT></DIV>
<DIV><FONT size=2>// 模块A头文件 moduleA.h<BR>#ifndef
MODULE_A_H<BR>#define MODULE_A_H<BR>extern "C" int foo( int x, int y
);<BR>#endif </FONT></DIV>
<DIV><FONT size=2>在模块B的实现文件中仍然调用foo( 2,3
),其结果是:<BR>(1)模块A编译生成foo的目标代码时,没有对其名字进行特殊处理,采用了C语言的方式;</FONT></DIV>
<DIV><FONT
size=2>(2)连接器在为模块B的目标代码寻找foo(2,3)调用时,寻找的是未经修改的符号名_foo。<BR><BR>如果在模块A中函数声明了foo为extern
"C"类型,而模块B中包含的是extern int foo( int x, int y )
,则模块B找不到模块A中的函数;反之亦然。<BR><BR>所以,可以用一句话概括extern
“C”这个声明的真实目的(任何语言中的任何语法特性的诞生都不是随意而为的,来源于真实世界的需求驱动。我们在思考问题时,不能只停留在这个语言是怎么做的,还要问一问它为什么要这么做,动机是什么,这样我们可以更深入地理解许多问题):<STRONG>实现C++与C及其它语言的混合编程</STRONG>。 </FONT></DIV>
<DIV><FONT size=2>明白了C++中extern "C"的设立动机,我们下面来具体分析extern
"C"通常的使用技巧:</FONT></DIV>
<DIV><FONT size=2><STRONG>extern
"C"的惯用法<BR><BR></STRONG>(1)<STRONG>在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)</STRONG>时,需进行下列处理:</FONT></DIV>
<DIV><FONT size=2>extern "C"<BR>{<BR>#i nclude
"cExample.h"<BR>}</FONT></DIV>
<DIV><FONT
size=2>而在C语言的头文件中,<STRONG>对其外部函数只能指定为extern类型</STRONG>,<STRONG>C语言中不支持extern
"C"声明</STRONG>,在.c文件中包含了extern
"C"时会出现编译语法错误。<BR><BR>C++引用C函数例子工程中包含的三个文件的源代码如下:</FONT></DIV>
<DIV><FONT size=2>/* <STRONG>c语言头文件</STRONG>:cExample.h
*/<BR>#ifndef C_EXAMPLE_H<BR>#define
C_EXAMPLE_H<BR><STRONG>extern</STRONG> int add(int x,int
y);<BR>#endif</FONT></DIV>
<DIV><BR><FONT size=2>/* <STRONG>c语言实现文件</STRONG>:cExample.c
*/<BR>#i nclude "cExample.h"<BR>int add( int x, int y
)<BR>{<BR>return x + y;<BR>}</FONT></DIV>
<DIV><BR><FONT size=2><STRONG>//
c++实现文件,调用add:cppFile.cpp</STRONG><BR></FONT><FONT
size=2><STRONG>extern "C" <BR></STRONG>{<BR>#i nclude
"cExample.h"<BR>}<BR>int main(int argc, char*
argv[])<BR>{<BR>add(2,3); <BR>return 0;<BR>}</FONT></DIV>
<DIV><FONT size=2>如果C++调用一个C语言编写的.DLL时,当包括.DLL的头文件或声明接口函数时,应加extern
"C" { }。<BR></FONT></DIV>
<DIV><FONT size=2>(2)<STRONG>在C中引用C++语言中的函数和变量时,C++的头文件需添加extern
"C",但是在C语言中不能直接引用声明了extern "C"的该头文件,应该仅将C文件中将C++中定义的extern
"C"函数声明为extern类型。</STRONG></FONT></DIV>
<DIV><FONT size=2>C引用C++函数例子工程中包含的三个文件的源代码如下:</FONT></DIV>
<DIV><FONT size=2>//<STRONG>C++头文件</STRONG> cppExample.h<BR>#ifndef
CPP_EXAMPLE_H<BR>#define CPP_EXAMPLE_H<BR>extern "C" int add( int x,
int y );<BR>#endif</FONT></DIV>
<DIV><BR><FONT size=2>//<STRONG>C++实现文件</STRONG>
cppExample.cpp<BR>#i nclude "cppExample.h"<BR>int add( int x, int y
)<BR>{<BR>return x + y;<BR>}</FONT></DIV>
<DIV><BR><FONT size=2>/* <STRONG>C实现文件 cFile.c</STRONG><BR>/*
<STRONG>这样会编译出错:#i nclude "cExample.h"
</STRONG>*/<BR><STRONG>extern</STRONG> int add( int x, int y
);<BR>int main( int argc, char* argv[] )<BR>{<BR>add( 2, 3 );
<BR>return 0;<BR>}</FONT></DIV>
<DIV><FONT size=2>15题目的解答请参考</FONT><A
href="http://blog.csdn.net/wfwd/archive/2006/05/30/763734.aspx"><FONT
size=2>《<STRONG><FONT color=#339900>C++中extern
“C”含义深层探索</FONT></STRONG>》</FONT></A><FONT size=2>注解:</FONT></DIV>
<DIV><FONT size=2><STRONG>16.
关联、聚合(Aggregation)以及组合(Composition)的区别?</STRONG></FONT></DIV>
<DIV><FONT
size=2>涉及到UML中的一些概念:<STRONG>关联</STRONG>是表示两个类的一般性联系,比如“学生”和“老师”就是一种关联关系;<STRONG>聚合</STRONG>表示has-a的关系,是一种相对松散的关系,聚合类不需要对被聚合类负责,如下图所示,用空的菱形表示聚合关系:</FONT></DIV>
<DIV><FONT
size=2> <IMG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -