1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数;
答:
//假设线性表的双向链表存储结构
typedef struct DulNode{
struct DulNode *prior; //前驱指针
ElemType data; //数据
struct DulNode *next; //后继指针
}DulNode,*DulinkList;
//删除操作
Status ListDelete_DuL(DulinkList &L,int i,ElemType &e)
{
if(!(p=GetElemP_DuL(L,i))) //此处得到i位置的节点指针,如果有需要也得写出具体函数实现
return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->pror;
free(p);
return OK;
}
//插入操作
Status ListInsert_DuL(DulinkList &L,int i,ElemType &e)
{
if(!(p=GetElemP_DuL(L,i)))
return ERROR;
if(!(s=(DulinkList)malloc(sizeof(DuLNode))))
return ERROR;
s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
return OK;
}
2.写一个函数,将其中的t都转换成4个空格。
答:
该函数命名为convert,参数的意义为:
*strDest目的字符串,*strSrc源字符串,length源字符串的长度
函数实现为:
char* convert(char *strDest, const char *strSrc,int length)
{
char * cp = strDest;
int i=0;
while(*strSrc && i{
if (*strSrc=https://www.mshxw.com/skin/sinaskin/image/nopic.gif //将t转换成4个空格
{
for(int j=0;j<4;j++)*cp++=' ';}else //否则直接拷贝 *cp++=*strSrc;strSrc++;i++;}return strDest;}3.Windows程序的入口是哪里?写出Windows消息机制的流程。答:Windows程序的入口是WinMain函数消息机制:系统将会维护一个或多个消息队列,所有产生的消息都会被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统。4.如何定义和实现一个类的成员函数为回调函数?答:所谓的回调函数,就是预先在系统的对函数进行注册,让系统知道这个函数的存在,以后,当某个事件发生时,再调用这个函数对事件进行响应。定义一个类的成员函数时在该函数前加CALLBACK即将其定义为回调函数,函数的实现和普通成员函数没有区别5.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。答:不是,比如中断引起的中断处理不是直接由main()引起的,而是由外部事件引起的。6.C++里面如何声明const void f(void)函数为C程序中的库函数?答:在该函数前添加extern “C”声明7.下列哪两个是等同的 int b; A const int* a = &b; B const* int a = &b; C const int* const a = &b; D int const* const a = &b;答:各式表示的意思分别为:A const int* a = &b; /
#ifdef __cplusplus
}
#endif
#endif
解答:
头文件中的编译宏
#ifndef __INCvxWorksh
#define __INCvxWorksh
#endif
的作用是防止被重复引用。
作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在symbol库中的名字与C语言的不同。例如,假设某个函数的原型为:
void foo(int x, int y);
该函数被C编译器编译后在symbol库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息,C++就是考这种机制来实现函数重载的。
为了实现C和C++的混合编程,C++提供了C连接交换指定符号extern “C”来解决名字匹配问题,函数声明前加上extern “C”后,则编译器就会按照C语言的方式将该函数编译为_foo,这样C语言中就可以调用C++的函数了。
试题5:编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”
函数头是这样的:
//pStr是指向以’’结尾的字符串的指针
//steps是要求移动的n
void LoopMove ( char * pStr, int steps )
{
//请填充…
}
解答:
正确解答1:
Code
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) – steps;
char tmp[MAX_LEN];
strcpy ( tmp, pStr + n );
strcpy ( tmp + steps, pStr);
*( tmp + strlen ( pStr ) ) = ‘’;
strcpy( pStr, tmp );
}
正确解答2:
Code
void LoopMove ( char *pStr, int steps )
{
int n = strlen( pStr ) – steps;
char tmp[MAX_LEN];
memcpy( tmp, pStr + n, steps );
memcpy(pStr + steps, pStr, n );
memcpy(pStr, tmp, steps );
}
剖析:
这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。
最频繁被使用的库函数包括:
(1) strcpy
(2) memcpy
(3) memset
memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
用法:#include
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
注意:与strcpy相比,memcpy并不是遇到’’就结束,而是一定会拷贝完n个字节。
举例:
// memcpy.c
#include
#include
int main(int argc, char* argv[])
{
char *s=”Golden Global View”;
char d[20];
clrscr();
memcpy(d,s,strlen(s));
d[strlen(s)]=’’;
printf(“%s”,d);
getchar();
return 0;
}
截取view
#include
int main(int argc, char* argv[])
{
char *s=”Golden Global View”;
char d[20];
memcpy(d,s+14,4);
//memcpy(d,s+14*sizeof(char),4*sizeof(char));也可
d[4]=’’;
printf(“%s”,d);
getchar();
return 0;
}
输出结果:
View
初始化数组
char msg[10];
memcpy(msg,0,sizeof(msg));
memset
函数原型
void *memset(void *s, int ch, unsigned n);
编辑本段
程序例
#include
#include
#include
memset函数
int main(void)
{
char buffer[] = “Hello worldn”;
printf(“Buffer before memset: %sn”, buffer);
memset(buffer, ‘*’, strlen(buffer) );
printf(“Buffer after memset: %sn”, buffer);
return 0;
}
输出结果:
Buffer before memset: Hello world
Buffer after memset: ***********
编译平台:
Microsoft Visual C++ 6.0
也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。例如下面这样:
int array[5] = {1,4,3,5,2};
for(int i = 0; i < 5; i++) cout<
class String{
public:
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]=''; }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<
unsigned int const size2 = temp;
char str2[ size2 ];
答:str2定义出错,size2非编译器期间常量,而数组定义要求长度必须为编译期常量。
7. 以下反向遍历array数组的方法有什么错误?
vector array;
array.push_back( 1 );
array.push_back( 2 );
array.push_back( 3 );
for( vector::size_type i=array.size()-1; i>=0; –i ) // 反向遍历array数组
{
cout << array[i] << endl;}答:首先数组定义有误,应加上类型参数:vector array。其次vector::size_type被定义为unsigned int,即无符号数,这样做为循环变量的i为0时再减1就会变成最大的整数,导致循环失去控制。8. 以下代码中的输出语句输出0吗,为什么?struct CLS{int m_i;CLS( int i ) : m_i(i) {}CLS(){CLS(0);}};CLS obj;cout << obj.m_i << endl;答:不能。在默认构造函数内部再调用带参的构造函数属用户行为而非编译器行为,亦即仅执行函数调用,而不会执行其后的初始化表达式。只有在生成对象时,初始化表达式才会随相应的构造函数一起调用。9. C++中的空类,默认产生哪些类成员函数?答:class Empty{public:Empty(); // 缺省构造函数Empty( const Empty& ); // 拷贝构造函数~Empty(); // 析构函数Empty& operator=( const Empty& ); // 赋值运算符Empty* operator&(); // 取址运算符const Empty* operator&() const; // 取址运算符 const};10. 以下两条输出语句分别输出什么?float a = 1.0f;cout << (int)a << endl;cout << (int&)a << endl;cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?float b = 0.0f;cout << (int)b << endl;cout << (int&)b << endl;cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?答:分别输出false和true。注意转换的应用。(int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1,(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。对b的两种转换意义同上,但是0的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。注意,程序的输出会显示(int&)a=1065353216,这个值是怎么来的呢?前面已经说了,1以浮点数形式存放在内存中,按ieee754规定,其内容为0x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容0x0000803F按整数解释,其值正好就是1065353216(十进制数)。通过查看汇编代码可以证实“(int)a相当于重新构造了一个值等于a的整型数”之说,而(int&)的作用则仅仅是表达了一个类型信息,意义在于为cout<<及==选择正确的重载版本。11. 以下代码有什么问题?typedef vector IntArray;IntArray array;array.push_back( 1 );array.push_back( 2 );array.push_back( 2 );array.push_back( 3 );// 删除array数组中所有的2for( IntArray::iterator itor=array.begin(); itor!=array.end(); ++itor ){if( 2 == *itor ) array.erase( itor );}答:同样有缺少类型参数的问题。另外,每次调用“array.erase( itor );”,被删除元素之后的内容会自动往前移,导致迭代漏项,应在删除一项后使itor--,使之从已经前移的下一个元素起继续遍历。12. 写一个函数,完成内存之间的拷贝。[考虑问题是否全面]答:void* mymemcpy( void *dest, const void *src, size_t count ){char* pdest = static_cast( dest );const char* psrc = static_cast( src );if( pdest>psrc && pdest{
for( size_t i=count-1; i!=-1; –i )
pdest[i] = psrc[i];
}
else
{
for( size_t i=0; ipdest[i] = psrc[i];
}
return dest;
}



