C++笔试题库-------Coding整理
1. 反转字符串
char* strrev1(const char* str) { int len = strlen(str); char *temp = new char[len + 1]; char *p = temp + len; *p = '\0'; p--; while(*str != '\0') { *p-- = *str++; } p = NULL; return temp; }
2. 实现strcmp,对比两个字符串,相同返回0,前者大于后者返回正数,反之,返回负数
首先,函数原型得写正确:int strcmp(char *source, char *dest)
int strcmp(char *source, char *dest) { int ret = 0; while(!(ret = *(unsigned char *)source - *(unsigned char *)dest) && *dest) { ++source; ++dest; } if(ret < 0) ret = -1; else if(ret > 0) ret = 1; return ret; }
3. strcpy的实现
char *strcpy(char *dest, const char *src) {
if(NULL == dest || NULL = src) return NULL; char* r = dest; while((*(dest++) = *(src++)) != '\0') ; return r; }
3. 请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
#define Max((a),(b)) ((a)/(b))?(a):(b)
4. 还是关于宏的问题:
下面例子输出的是什么,做了什么运算得出的结果?
#define SQR(X) X*X int _tmain(int argc, _TCHAR* argv[]) { int a = 10; int k = 2; int m = 1; a /= SQR(k+m)/SQR(k+m); printf("%d\n",a); return 0; }
解释:宏没有类型检查,只是做了简单的符号对换!其运算相当于下面语句:
a/=k+m*k+m/k+m*k+m;
即 a = a/7,所以,答案为:1
5. const 符号常量;
(1)const char *p
(2)char const *p
(3)char * const p
说明上面三种描述的区别;
解释:(1)(2)都是同一个意思,p是一个指针,指向一个字符常量,p自身的内容是可变的,但是p指向的内容是不可变的;
(3)与前两者不同,p是一个常量指针,初始化之后,p自身的内容不可变,但是p指向的内容是可变的。
6. socket缓冲区大小设置
//设置发送和接收缓冲区 int rcvbuf; int rcvbufsize=sizeof(int); if(getsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*) &rcvbuf,&rcvbufsize)!=SOCKET_ERROR) { if(rcvbuf<65536) rcvbuf=65536; setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(char*) &rcvbuf,rcvbufsize); } if(getsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*) &rcvbuf,&rcvbufsize)!=SOCKET_ERROR) { if(rcvbuf<65536) rcvbuf=65536; setsockopt(m_Socket,SOL_SOCKET,SO_SNDBUF,(char*) &rcvbuf,rcvbufsize); }
7. 在不实例化struct的情况下,求成员变量的偏移量
#define FIND(struc, e) (unsigned int)(&((struc*)0)->e) typedef struct stu { char a[20]; int b; double d; }stu; int main() { printf("%d\n",FIND(stu,a)); printf("%d\n",FIND(stu,b)); printf("%d\n",FIND(stu,d)); return 0; }
8. 设计仅能在堆创建的类
思路:将析构函数设置为private,从而使得如果在栈上创建该类的话,会出现编译期间错误!
#include<iostream> using namespace std; class onlyHeap { public: onlyHeap() { cout<<"constructor"<<endl; } void destroy() { delete this; } private: ~onlyHeap() { cout<<"destructor"<<endl; } }; int main() { //onlyHeap he; //error while complier onlyHeap *he = new onlyHeap(); he->destroy(); return 0; }
9. 设计仅能在栈上创建的类
思路:重载 new 和 delete 操作符为 private。
#include <iostream> using namespace std; class OnlyStack { public: OnlyStack() { cout<<"构造"<<endl; } ~OnlyStack() { cout<<"析构"<<endl; } private: void* operator new (size_t t); void operator delete(void *ptr); }; int main() { //A* a = new A; //会报错 OnlyStack a; return 0; }
10. dynamic_cast 与 static_cast 的区别
dynamic_cast
用法:dynamic_cast <type-id> (expression)
可以使用 dynamic_cast 操作符将基类类型对象的引用或指针转换为同一继承层次中其他类型的引用或指针。它涉及运行时类型检查。
dynamic_cast 运算符可以在执行期决定真正的类型。
如果 downcast 是安全的(也就说,如果基类指针或者引用确实指向一个派生类对象)这个运算符会传回适当转型过的指针。downcast:基类=>继承类
如果 downcast 不安全,这个运算符会传回空指针(也就是说,基类指针或者引用没有指向一个派生类对象)。
static_cast
用法:static_cast < type-id > ( expression )
该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。
它主要有如下几种用法:
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。
11. strlen 和 sizeof的使用
const char *p = "Hello World"; char p[] = "Hello World";
分别求长度和所占用空间大小。
提示:求长度都可以用strlen(p),求占内存空间大小第一个不能用sizeof,第二个可以用sizeof。另外,第二个:strlen(p) = 11, sizeof(p) = 12
http://blog.csdn.net/lincyang/article/category/710309