资源描述
4.技巧题
试题2:写一个函数返回1+2+3+…+n的值(假定成果不会超出长整型变量的范围)
解答:
int Sum( int n )
{
return ( (long)1 + n) * n / 2; //或return (1l + n) * n / 2;
}
剖析:
对于这个题,只能说,也许最简单的答案就是最佳的答案。下面的解答,或者基于下面的解答思绪去优化,无论怎么“折腾”,其效率也不也许与直接return ( 1 l + n ) * n / 2相比!
int Sum( int n )
{
long sum = 0;
for( int i=1; i<=n; i++ )
{
sum += i;
}
return sum;
}
一、请写出
BOOL flag 与“零值”比较的 if 语句。(3分)
标准答案:
if ( flag )
if ( !flag )
如下写法均属不良格调,不得分。
if (flag == TRUE)
if (flag == 1 )
if (flag == FALSE)
if (flag == 0)
请写出
float x 与“零值”比较的 if 语句。(4分)
标准答案示例:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
不可将浮点变量用“==”或“!=”与数字比较,应当设法转化成“>=”或“<=”此类形式。
如下是错误的写法,不得分。
if (x == 0.0)
if (x != 0.0)
请写出
char *p 与“零值”比较的 if 语句。(3分)
标准答案:
if
(p == NULL)
if
(p != NULL)
如下写法均属不良格调,不得分。
if (p == 0)
if (p != 0)
if (p)
if (!)
二、如下为
Windows NT下的32位C++程序,请计算sizeof的值(10分)
char *p = str ;
int n = 10;
char str[] = “Hello” ;
请计算
sizeof (str ) = 6
sizeof ( p ) = 4
(2分) (2分)
sizeof ( n ) = 4
(2分)
void Func ( char str[100])
{
请计算
sizeof( str ) = 4
}
(2分)
void *p = malloc( 100 );
请计算
sizeof ( p ) = 4
(2分)
三、简答题(
25分)
1、头文献中的 ifndef/define/endif 干什么用?(5分)
答:预防该头文献被重复引用。
#include ,编译器从标准库途径开始搜索 filename.h对于#include “filename.h” ,编译器从用户的工作途径开始搜索 filename.h
3.const 有什么用途?(请最少阐明两种)(5分)
答:
4.在C++ 程序中调用被 C编译器编译后的函数,为何要加 extern “C”? (5分)
答:
5.请简述如下两个for循环的优缺陷(5分)
for (i=0; i
{
if (condition)
DoSomething();
else
DoOtherthing();
}
if (condition)
{
for (i=0; i
DoSomething();
}
else
{
for (i=0; i
DoOtherthing();
}
优点:程序简洁
缺陷:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,减少了效率。
优点:循环的效率高
缺陷:程序不简洁
5分,共20分)
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
请问运行Test函数会有什么样的成果?
答:程序瓦解。
因为
Test函数中的 str一直都是 NULL。
strcpy(str, "hello world");将使程序瓦解。
GetMemory并不能传递动态内存,
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
请问运行Test函数会有什么样的成果?
答:也许是乱码。
因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行Test函数会有什么样的成果?
答:
(
(
1)能够输出hello2)内存泄漏
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str,
free(str);
if(str != NULL)
{
strcpy(str,
printf(str);
}
}
请问运行Test函数会有什么样的成果?
答:篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str);之后,str成为野指针,
if(str != NULL)语句不起作用。
“hello”);“world”);
strcpy函数(10分)strcpy函数的原型是char *strcpy(char *strDest, const char *strSrc);其中strDest是目标字符串,strSrc是源字符串。1)不调用C++/C的字符串库函数,请编写函数 strcpystrDest!=NULL) && (strSrc !=NULL)); // 2分strDest; // 2分strDest++ = * strSrc++) != ‘\0’ ) // 2分2)strcpy能把strSrc的内容复制到strDest,为何还要char * 类型的返回值?int length = strlen( strcpy( strDest, “hello world”) ); String的结构函数、析构函数和赋值函数(25分)String的原型为:String::~String(void) // 3分String::String(const char *str) // 6分‘\0’;
-------------起源为林锐博士的 << 高质量c\c++编程
五、编写
已知
(
char *strcpy(char *strDest, const char *strSrc);
(
答:为了实现链式体现式。 // 2分
例如
{
assert((
char *address =
while( (*
NULL ;
return address ; // 2分
}
六、编写类
已知类
class String
{
public:
String(const char *str = NULL); // 一般结构函数
String(const String &other); // 拷贝结构函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
请编写String的上述4个函数。
标准答案:
// String的析构函数
{
delete [] m_data;
// 因为m_data是内部数据类型,也能够写成 delete m_data;
}
// String的一般结构函数
{
if(str==NULL)
{
m_data = new char[1]; // 若能加 NULL 判断则愈加好
*m_data =
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 NULL 判断则愈加好
strcpy(m_data, str);
}
}
// 拷贝结构函数
String::String(const String &other) // 3分
{
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则愈加好
strcpy(m_data, other.m_data);
}
// 赋值函数
String & String::operate =(const String &other) // 13分
{
// (1) 检查自赋值 // 4分
if(this == &other)
return *this;
// (2) 释放原有的内存资源 // 3分
delete [] m_data;
// (3)分派新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则愈加好
strcpy(m_data, other.m_data);
// (4)返回本对象的引用 // 3分
return *this;
}
C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不一样。假设某个函数的原型为: void foo(int x, int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接互换指定符号extern“C”来处理名字匹配问题。1)能够定义 const 常量2)const能够修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,能够预防意外的变动,能提升程序的健壮性。2、#include 和 #include “filename.h” 有什么区分?(5分) >>
已知
六、编写类
已知类
class String
{
public:
String(const char *str = NULL); // 一般结构函数
String(const String &other); // 拷贝结构函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
请编写String的上述4个函数。
(二)
void * ( * (*fp1)(int))[10];
float (*(* fp2)(int,int,int))(int);
int (* ( * fp3)())[10]();
分别表示什么意思?
答:
1.void * ( * (*fp1)(int))[10];
fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。
2.float (*(* fp2)(int,int,int))(int);
fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。
3.int (* ( * fp3)())[10]();
fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型。
1.简介一下STL,详细阐明STL怎样实现vector。
Answer:
STL (标准模版库,Standard Template Library.它由容器算法迭代器组成。
STL有如下的某些优点:
能够以便轻易地实现搜索数据或对数据排序等一系列的算法;
调试程序时愈加安全和以便;
虽然是人们用STL在UNIX平台下写的代码你也能够很轻易地了解(因为STL是跨平台的)。
vector实质上就是一个动态数组,会依照数据的增加,动态的增加数组空间。
2.假如用VC开发程序,常见这么几个错误,C,c,c,这些错误的原因是什么。
Answer:
在学习VC++的过程中,遇到的LNK错误的错误消息重要为:
unresolved external symbol “symbol”(不确定的外部“符号”)。
假如连接程序不能在所有的库和目标文献内找到所引用的函数、变量或标签,将产生此错误消息。
一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在、拼写不正确或者使用错误;其次也许使用了不一样版本的连接库。
编程中常常能遇到LNK错误——重复定义错误,其实LNK错误并不是一个极难处理的错误.
3.继承和委派有什么分别,在决定使用继承或者委派的时候需要考虑什么。
在OOD,OOP中,组合优于继承.
当然多态的基础是继承,没有继承多态无从谈起。
当对象的类型不影响类中函数的行为时,就要使用模板来生成这么一组类。
当对象的类型影响类中函数的行为时,就要使用继承来得到这么一组类.
4.指针和引用有什么分别;假如传引用比传指针安全,为何?假如我使用常量指针难道不行吗?
(1) 引用在创建的同时必须初始化,即引用到一个有效的对象;而指针在定义的时候无须初始化,能够在定义背面的任何地方重新赋值.
(2) 不存在NULL引用,引用必须与合法的存储单元关联;而指针则能够是NULL.
(3) 引用一旦被初始化为指向一个对象,它就不能被变化为另一个对象的引用;而指针在任何时候都能够变化为指向另一个对象.给引用赋值并不是变化它和原始对象的绑定关系.
(4) 引用的创建和销毁并不会调用类的拷贝结构函数
(5) 语言层面,引用的使用方法和对象同样;在二进制层面,引用一般都是通过指针来实现的,只不过编译器帮我们完成了转换.
不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被变化为另一个对象的引用,显得很安全。
const 指针仍然存在空指针,并且有也许产生野指针.
总的来说:引用既具备指针的效率,又具备变量使用的以便性和直观性.
5.参数传递有几个方式;实现多态参数传递采取什么方式,假如没有使用某种方式原因是什么;
传值,传指针或者引用
6.结合一个项目阐明你怎样应用设计模式的理念。
设计模式更多考虑是扩展和重用,而这两方面诸多情况下,往往会被忽视。
不过,我不提议滥用设计模式,以为它有也许使得简单问题复杂化.
7.简介一下你对设计模式的了解。(这个过程中有诸多很细节的问题随机问的)
设计模式概念是由建筑设计师Christopher Alexander提出:"每一个模式描述了一个在我们周围不停重复发生的问题,以及该问题的处理方案的核心.这么,你就能一次又一次地使用该方案而无须做重复劳动."上述定义是对设计模式的广义定义.将其应用到面对对象软件的领域内,就形成了对设计模式的狭义定义.
能够简单的以为:设计模式就是处理某个特定的面对对象软件问题的特定措施, 并且已经上升到理论程度。
展开阅读全文