试题7:编写类String的构造函数、析构函数和赋值函数,已知类String的原型为: Code
#include
String(const char *str = NULL);//默认构造函数 String(const String &str);//复制构造函数 ~String();//析构函数
String operator+(const String & str);//字符串连接 String & operator=(const String &str);//字符串赋值
bool operator==(const String &str);//判断是否字符串相等 int Length();//获取字符串长度
friend ostream & operator<<(ostream &o,const String &str);//重载输出 String SubStr(int start, int end);//求子字符串(start ... end-1) private:
char * charArray; };
String::String(const char *str) {
if(str == NULL){
charArray=new char[1]; charArray[0]='\\0'; }else{
charArray=new char[strlen(str)+1]; strcpy(charArray,str); } }
String::String(const String &str) {
charArray = new char[strlen(str.charArray)+1]; strcpy(charArray,str.charArray); }
String::~String() {
delete [] charArray; }
String String::operator+(const String &str) {
String res;
delete [] res.charArray;//释放原有空间
res.charArray = new char[strlen(charArray)+strlen(str.charArray)+1]; strcpy(res.charArray,charArray);
strcpy(res.charArray+strlen(charArray),str.charArray); return res; }
String & String::operator=(const String &str) {
if(charArray == str.charArray) return *this; delete [] charArray;
charArray = new char[strlen(str.charArray)+1]; strcpy(charArray,str.charArray); return *this; }
bool String::operator==(const String &str) {
return strcmp(charArray,str.charArray) == 0;
}
int String::Length() {
return strlen(charArray); }
ostream & operator<<(ostream &o, const String &str) {
o< String String::SubStr(int start, int end) { String res; delete [] res.charArray;//释放原有内存 res.charArray = new char[end-start+1];//重新申请内存 for(int i=0; i+start res.charArray[i]=charArray[start+i]; } res.charArray[end-start] = '\\0'; return res; } void main() { String s = \ String t = \ cout< String s2 = \ String s3 = \ cout< cout<<(s2+s3).SubStr(0,s2.Length()+s3.Length())< 能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上! 在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。仔细学习这个类,特别注意加注释的得分点和加分点的意义,这样就具备了60%以上的C++基本功! 试题8:请说出static和const关键字尽可能多的作用 解答: static关键字至少有下列n个作用: (1) 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; (2) 在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; (3) 在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内; (4) 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; (5) 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。 const关键字至少有下列n个作用: (1) 欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了 (2) 对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const; (3) 在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; (4) 对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量; (5) 对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如: const classA operator*(const classA& a1,const classA& a2); operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错: classA a, b, c; (a * b) = c; // 对a*b的结果赋值 操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。 东软经典笔试及参考答案 1.static有什么用途?(请至少说明两种) 1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。 2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。 3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用 2.引用与指针有什么区别? 1) 引用必须被初始化,指针不必。 2) 引用初始化以后不能被改变,指针可以改变所指的对象。 3) 不存在指向空值的引用,但是存在指向空值的指针。 3.描述实时系统的基本特性 在特定时间内完成特定的任务,实时性与可靠性。 4.全局变量和局部变量在内存中是否有区别?如果有,是什么区别? 全局变量储存在静态数据库,局部变量在堆栈。 5.什么是平衡二叉树? 左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1。 6.堆栈溢出一般是由什么原因导致的? 没有回收垃圾资源。 7.什么函数不能声明为虚函数? constructor函数不能声明为虚函数。 8.冒泡排序算法的时间复杂度是什么? 时间复杂度是O(n^2)。 9.写出float x 与“零值”比较的if语句。 if(x>0.000001&&x<-0.000001) 10.Internet采用哪种网络协议?该协议的主要层次结构? Tcp/Ip协议 主要层次结构为: 应用层/传输层/网络层/数据链路层/物理层。 11.Internet物理地址和IP地址转换采用什么协议? ARP (Address Resolution Protocol)(地址解析協議) 12.IP地址的编码分为哪俩部分? IP地址由两部分组成,网络号和主机号。不过是要和“子网掩码”按位与上之后才能区分哪些是网络位哪些是主机位。 13.用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。写出C程序。 循环链表,用取余操作做 14.不能做switch()的参数类型是: switch的参数不能为实型。 1.写出判断ABCD四个表达式的是否正确, 若正确, 写出经过表达式中 a的值(3分) int a = 4; (A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++); a = ? 答:C错误,左侧不是一个有效变量,不能赋值,可改为(++a) += a; 改后答案依次为9,10,10,11 2.某32位系统下, C++程序,请计算sizeof 的值(5分). char str[] = “http://www.ibegroup.com/” char *p = str ; int n = 10; 请计算 sizeof (str ) = ?(1) sizeof ( p ) = ?(2) sizeof ( n ) = ?(3) void Foo ( char str[100]){ 请计算 sizeof( str ) = ?(4) } void *p = malloc( 100 ); 请计算 sizeof ( p ) = ?(5) 答:(1)17 (2)4 (3) 4 (4)4 (5)4 3. 回答下面的问题. (4分) (1).头文件中的 ifndef/define/endif 干什么用?预处理 答:防止头文件被重复引用 (2). #i nclude 和 #i nclude “filename.h” 有什么区别? 答:前者用来包含开发环境提供的库头文件,后者用来包含自己编写的头文件。 (3).在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明? 答:函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern \修饰的变 量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调 用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。 (4). switch()中不允许的数据类型是? 答:实型 4. 回答下面的问题(6分) (1).Void GetMemory(char **p, int num){ *p = (char *)malloc(num); } void Test(void){ char *str = NULL; GetMemory(&str, 100); strcpy(str, \printf(str); } 请问运行Test 函数会有什么样的结果? 答:输出“hello” (2). void Test(void){ char *str = (char *) malloc(100); strcpy(str, “hello”); free(str); if(str != NULL){ strcpy(str, “world”); printf(str); } } 请问运行Test 函数会有什么样的结果? 答:输出“world” (3). char *GetMemory(void){ char p[] = \return p; } void Test(void){ char *str = NULL; str = GetMemory(); printf(str); } 请问运行Test 函数会有什么样的结果? 答:无效的指针,输出不确定 5. 编写strcat函数(6分) 已知strcat函数的原型是char *strcat (char *strDest, const char *strSrc); 其中strDest 是目的字符串,strSrc 是源字符串。 (1)不调用C++/C 的字符串库函数,请编写函数 strcat 答: VC源码: char * __cdecl strcat (char * dst, const char * src) { char * cp = dst; while( *cp )