一.请填写BOOL ,float, 指针变量与 “零值”比较的if 语句。
提示:这里“零值”可以是 0 ,0 .0 ,FALSE或者“空指针”。例如 int 变量 n 与 “零值”比较的if 语句为: if (n ==0)
if (n!=0)
以次类推:
请写出BOOL flag与”零值” 比较的 if 语句:if(flag)
请写出 float x 与”零值” 比较的 if 语句:
const float ESPON=0.000001;
if( ( x =< ESPON)&& ( x >= - ESPON) );
请写出char *p 与”零值” 比较的 if 语句:if( p==NULL )
二.以下为WINDOWS NT 下的32位 C++程序 ,请计算 sizeof 的值。
char str[] = “Hello”;
char *p = str;
int n = 10;
请计算
sizeof (str) = 6
sizeof (p) = 4
sizeof (n) = 4
void Fun (char str[100])
{ //请计算
sizeof (str) = 4
}
void *p = mallo(100);
//请计算
sizeof(p) = 4
三.简答题
1. 头文件中的ifndef/define/endif 干什么用?
答: 防止该头文件被重复引用.
2. #include <filename.h> and #include “filename.h”有什么区别?
答: 对于#include <filename.h>,编译器从标准库开始查找filename.h
对于#include “filename.h” ,编译器是从用户的工作路径开始查找filename.h
3. const 有什么用途 ?(请至少说明两种)
答: 1.可以定义const常量.
2.const可以修饰函数的参数,返回值,甚至函数的定义体.被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.
4. 在C++ 程序中调用被C 编译器编译后的函数 ,为什么要加 extern “C” ?
答: C++语言支持函数重载,C不支持函数重载.函数被C++编译后在库在的名字与C语言不同.例如:void foo(int a,int b);该函数被C编译器编译后在库中为_foo,而C++编译器则会产生像_foo_int_int之类的名字.
C++提供了C连接交换指定符号 extern “C”来解决名字匹配问题.
5. 请简述以下两个 for 循环的优缺点
//第一个
for ( I = 0 ; I< N ; I ++)
{
if (condition)
DoSomething();
else
DoOtherthing();
}
优点:程序简洁
缺点:多执行了N-1次逻辑判断,
并且打断了循环”流水线”作业,使得编译器不能对循环进行优化处理,降低
了效率.
|
第二个
if (condition)
{
for (I = 0 ; I < N ; I++ )
DoSomething();
}
else {
for (I =0 ; I < N ; I ++)
DoOtherthing();}
优点:循环的效率高
缺点:程序不简洁
|
四.有关内存的思考题
void GetMemory (char * p)
{
p = (char * ) malloc (100);
}
void Test (void)
{
char * str = NULL ;
GetMemory (str );
strcpy (str, “hello word” );
printf (str );
}
请问运行Text 函数会有什么样的结果?
答:程序崩溃
因为GetMemory并不能传递动态内存,
Test函数中的str一直是NULL,
strcpy(str,”hello world”)将使程序崩溃
|
void * GetMemory ( )
{
char p[] = “hello word”;
return p;
}
void Test (void)
{
char * str = NULL ;
str = GetMemory ( );
printf (str );
}
请问运行Text 函数会有什么样的结果?
答: 可能是乱码.
因为GetMemory返回的是指向”栈内存”的
指针,该指针的地址不是NULL,但其有原先
的内容已被清除,新内容不可知.
|
void GetMemory(char * p , int num)
{
* p = (char * ) malloc ( num);
}
void Test (void)
{
char * str = NULL ;
GetMemory ( &str ,100 );
strcpy (str, “hello word” );
printf (str );
}
请问运行Text 函数会有什么样的结果?
答:1.能够输出hello.
2.内存泄漏.
|
void Test (void)
{
char * str = ( char *) malloc (100) ;
strcpy (str , “hello” );
free (str );
if (str != NULL)
{
strcpy (str ,”word”);
printf (str );
}
}
请问运行Text 函数会有什么样的结果?
答: 篡改动态内存区的内容,后果难以预料,
非常危险.
因为free(str)之后,str成为野指针,
if(str != NULL)语句不起作用.
|
|
|
五. 编写strcpy 函数
已知 strcpy 函数的原形是:char strcpy (char * strDest ,const char * strSrc);
其中strDest 是目的字符串,strSrc 是源字符串。
(1) 不调用C++ /C的字符串库函数,请编写函数 strcpy
Char* strcpy(char* strDest,const char* strSrc)
{
Char* address = strDest;
assert( ( strDest != NULL) && ( strSrc != NULL ) );
while( ( *strDest ++ = *strSrc++ ) != ‘/0’ );
return address;
}
(2) strcpy 能把strSrc 的内容复制到 strDest,为什么还要用 char * 类型的返回值 ?
答:为了实现链式表达式.
例如:int length = strlen( strcpy( strDest,”hello world” ) );
六.编写类String 的构造函数` 析构函数 和赋值函数
已知类String 的原形为:
class String
{
public:
String (const char *str = NULL); //普通构造函数
String (const String &other ); //拷贝构造函数
~String(void); //析构函数
String operator= (const String &other); //赋值函数
private :
char *m_data ; //用于保存字符串
};
请编写上述4个函数:
//String的普通构造函数
String::String(const char *str)
{
If(str == NULL)
{
m_data = new char[1];
*m_data = ‘/0’;
}
else
{
int length = strlen(str);
m_data = new char[length +1];
strcpy(m_data,str);
}
}
//String 析构函数
String::~String(void)
{
Delete [] m_data;
}
// Stringr 拷贝构造函数
String:: String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data,other.m_data);
}
// String赋值函数
String operator = (const String &other)
{
If( this == &other )
{
Return *this;
}
Delete [] m_data;
Int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data,other.m_data);
return *this;
}