1. 请描述const和#define相比,有何优点?
答:#define定义的其实是一个常数的名字,就是说你可以把这个名字等价于常数使用,在编译时会被编译器替换为该常数。之所以这么做,仅仅是为了提高可读性,但是安全性不能得到保证。出于安全性的考虑,C++引入了const定义。当然这仅仅是const的功能之一。使用const,你可以定义一个不能修改其值的变量,也就是可以作为一个常量来使用了。当然,这个量与100,'a'等还是有区别的。区别就在于这个量有自己的内存地址,是被分配了空间的。
总的说来,#define没有给名字分配空间,仅仅是给一个常数起了一个名字。而const定义了一个其值不能修改的变量,在内存中是有自己的地址的。#define不存在编译时类型检查,而const可以进行编译时类型检查。
2. 请描述static关键字的相关用途。
答:a) 函数体内static变量的作用范围为该函数体,全局数据区。
b) 在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问。
c) 在模块内的static函数只可能被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内。
d) 在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝。
e) 在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
3. 请描述const关键字的相关用途。
答:a) 可以定义const常量。b) const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。c) 定义类中的某个成员函数为恒态函数,即不改变类中的数据成员。
4. 请描述多态的实现方式以及为什么要设计多态?
答:多态是允许将父对象设置成为和他的一个或更多的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单地说就是一句话,允许将子类类型的指针赋值给父类类型的指针。多态性通过虚函数实现。
5. 请说明strcpy、memcpy、memmove的区别。
答:strcpy只能处理字符串,遇’\0’结束,如果拷贝带有特殊字符的串,就只能用memcpy或memmove。
当src和dest所指内存区有重叠时,memmove相对memcpy能提供保证:保证能将src所指内存区的前n个字节正确的拷贝到 dest 所指内存中;当src地址比dest地址低时,两者结果一样。换句话说,memmove与memcpy的区别仅仅体现在dest的头部和src的尾部有重叠的情况下。
详见http://hi.baidu.com/gaj19870311/blog/item/48bc44fa26e2cd1dd8f9fdd8.html的讨论。
6. 请编程实现一个分配动态二维数组的函数:int ** createList(int m, int n);
刚开始想到的是分配m*n的一维数组,但是返回后的一维数组指针不能做类似Array[i][j]的操作,做了相应的修改。
- int **createList(int m, int n) /* 指向数组指针的指针 */
- {
- int i;
- int **Array2D;
- if(m<1 || n<1)
- return NULL;
- Array2D = malloc(m*sizeof(int *));
- if(Array2D == NULL)
- return NULL;
- for(i=0; i<m; i++)
- {
- Array2D[i] = malloc(n*sizeof(int));
- if(Array2D[i] == NULL)
- return NULL;
- }
- return Array2D;
- }
int **createList(int m, int n) /* 指向数组指针的指针 */
{
int i;
int **Array2D;
if(m<1 || n<1)
return NULL;
Array2D = malloc(m*sizeof(int *));
if(Array2D == NULL)
return NULL;
for(i=0; i<m; i++)
{
Array2D[i] = malloc(n*sizeof(int));
if(Array2D[i] == NULL)
return NULL;
}
return Array2D;
}
7. 请实现字符串分割函数string[]split(const string &str, char c);将str这个字符串按c字符分割成多个字串。
如,输入str = “我是好 人”, c = ‘ ’,返回下面三个字串:
我是
好
人
- #include <iostream>
- #include <string>
- using namespace std;
- int split(const string &str, char c)
- {
- if(str.empty())
- return 0;
- string tmp;
- string::size_type pos_begin = str.find_first_not_of(c);
- string::size_type pos_split = 0;
- while(pos_begin != string::npos)
- {
- pos_split = str.find(c, pos_begin);
- if(pos_split != string::npos)
- {
- tmp = str.substr(pos_begin, pos_split-pos_begin);
- pos_begin = str.find_first_not_of(c, pos_split);
- }
- else
- {
- tmp = str.substr(pos_begin);
- pos_begin = pos_split;
- }
- if(!tmp.empty())
- {
- cout<<tmp<<endl;
- }
- }
- return 0;
- }
- int main()
- {
- string str("i am a good student.");
- split(str, ' ');
- return 0;
- }
#include <iostream>
#include <string>
using namespace std;
int split(const string &str, char c)
{
if(str.empty())
return 0;
string tmp;
string::size_type pos_begin = str.find_first_not_of(c);
string::size_type pos_split = 0;
while(pos_begin != string::npos)
{
pos_split = str.find(c, pos_begin);
if(pos_split != string::npos)
{
tmp = str.substr(pos_begin, pos_split-pos_begin);
pos_begin = str.find_first_not_of(c, pos_split);
}
else
{
tmp = str.substr(pos_begin);
pos_begin = pos_split;
}
if(!tmp.empty())
{
cout<<tmp<<endl;
}
}
return 0;
}
int main()
{
string str("i am a good student.");
split(str, ' ');
return 0;
}
8. 给定一个int数组,int a[n],请写程序找到下面两个坐标i和j,使得a[j]-a[i]最大,其中j>i.
这道题要求两数之差最大且大数的下标大于小数的下标,写的时候用了两层循环,其实还有更好的解法。见下:
- static __inline int FindMaxIndex(int *array, int begin, int end)
- {
- int i;
- int index, maxNum;
- index = begin;
- maxNum = array[begin];
- for(i=begin+1; i<end; i++)
- {
- if(array[i] > maxNum)
- {
- maxNum = array[i];
- index = i;
- }
- }
- return index;
- }
- static __inline int FindMinIndex(int *array, int begin, int end)
- {
- int i;
- int index, minNum;
- index = begin;
- minNum = array[begin];
- for(i=begin+1; i<end; i++)
- {
- if(array[i] < minNum)
- {
- minNum = array[i];
- index = i;
- }
- }
- return index;
- }
- int FindIndex(int *array, int num, int *i, int *j)
- {
- int tempi=0, tempj=0;
- int mmax = -1;
- if(array == NULL || num < 2)
- return -1;
- do
- {
- tempj = FindMaxIndex(array, tempi, num);
- tempi = FindMinIndex(array, tempi, tempj);
- if(array[tempj]-array[tempi] > mmax)
- {
- *i = tempi;
- *j = tempj;
- mmax = array[*j] - array[*i];
- }
- tempi = tempj+1;
- }while(tempi<num);
- return 0;
- }
static __inline int FindMaxIndex(int *array, int begin, int end)
{
int i;
int index, maxNum;
index = begin;
maxNum = array[begin];
for(i=begin+1; i<end; i++)
{
if(array[i] > maxNum)
{
maxNum = array[i];
index = i;
}
}
return index;
}
static __inline int FindMinIndex(int *array, int begin, int end)
{
int i;
int index, minNum;
index = begin;
minNum = array[begin];
for(i=begin+1; i<end; i++)
{
if(array[i] < minNum)
{
minNum = array[i];
index = i;
}
}
return index;
}
int FindIndex(int *array, int num, int *i, int *j)
{
int tempi=0, tempj=0;
int mmax = -1;
if(array == NULL || num < 2)
return -1;
do
{
tempj = FindMaxIndex(array, tempi, num);
tempi = FindMinIndex(array, tempi, tempj);
if(array[tempj]-array[tempi] > mmax)
{
*i = tempi;
*j = tempj;
mmax = array[*j] - array[*i];
}
tempi = tempj+1;
}while(tempi<num);
return 0;
}
9. 编程实现单链表翻转
- typedef struct ListNode
- {
- int data;
- struct ListNode *pnext;
- }ListNode;
- ListNode *reverse_list(ListNode *head)
- {
- ListNode *pre, *curr, *nxt;
- if(head == NULL)
- return NULL;
- if(head->pnext == NULL)
- return head;
- pre = head;
- curr = head->pnext;
- while(curr != NULL)
- {
- nxt = curr->pnext;
- curr->pnext = pre;
- pre = curr;
- curr = nxt;
- }
- return pre;
- }
typedef struct ListNode
{
int data;
struct ListNode *pnext;
}ListNode;
ListNode *reverse_list(ListNode *head)
{
ListNode *pre, *curr, *nxt;
if(head == NULL)
return NULL;
if(head->pnext == NULL)
return head;
pre = head;
curr = head->pnext;
while(curr != NULL)
{
nxt = curr->pnext;
curr->pnext = pre;
pre = curr;
curr = nxt;
}
return pre;
}
10. 编程实现查找二叉树两个节点的最近公共祖先
- #define CONSIST_NODE1 0x01
- #define CONSIST_NODE2 0x02
- #define CONSIST_BOTH (CONSIST_NODE1 | CONSIST_NODE2)
- typedef struct BTreeNode
- {
- int data;
- struct BTreeNode *pLchild;
- struct BTreeNode *pRchild;
- }BTreeNode;
- BTreeNode *FindNearestCommonParent(BTreeNode *root, BTreeNode *Node1, BTreeNode *Node2, int *flag)
- {
- BTreeNode *CommonParent;
- int flag1 = 0, flag2 = 0;
- if(root->pLchild != NULL && *flag != CONSIST_BOTH)
- CommonParent = FindNearestCommonParent(root->pLchild, Node1, Node2, &flag1);
- if(flag1 == CONSIST_BOTH)
- {
- *flag = CONSIST_BOTH;
- return CommonParent;
- }
- if(root->pRchild != NULL && *flag != CONSIST_BOTH)
- CommonParent = FindNearestCommonParent(root->pRchild, Node1,Node2, &flag2);
- if(flag2 == CONSIST_BOTH)
- {
- *flag = CONSIST_BOTH;
- return CommonParent;
- }
- if(root == Node1)
- *flag = flag1 | flag2 | CONSIST_NODE1;
- else if(root == Node2)
- *flag = flag1 | flag2 | CONSIST_NODE2;
- if(*flag == CONSIST_BOTH)
- return root;
- else
- return NULL;
- }
#define CONSIST_NODE1 0x01
#define CONSIST_NODE2 0x02
#define CONSIST_BOTH (CONSIST_NODE1 | CONSIST_NODE2)
typedef struct BTreeNode
{
int data;
struct BTreeNode *pLchild;
struct BTreeNode *pRchild;
}BTreeNode;
BTreeNode *FindNearestCommonParent(BTreeNode *root, BTreeNode *Node1, BTreeNode *Node2, int *flag)
{
BTreeNode *CommonParent;
int flag1 = 0, flag2 = 0;
if(root->pLchild != NULL && *flag != CONSIST_BOTH)
CommonParent = FindNearestCommonParent(root->pLchild, Node1, Node2, &flag1);
if(flag1 == CONSIST_BOTH)
{
*flag = CONSIST_BOTH;
return CommonParent;
}
if(root->pRchild != NULL && *flag != CONSIST_BOTH)
CommonParent = FindNearestCommonParent(root->pRchild, Node1,Node2, &flag2);
if(flag2 == CONSIST_BOTH)
{
*flag = CONSIST_BOTH;
return CommonParent;
}
if(root == Node1)
*flag = flag1 | flag2 | CONSIST_NODE1;
else if(root == Node2)
*flag = flag1 | flag2 | CONSIST_NODE2;
if(*flag == CONSIST_BOTH)
return root;
else
return NULL;
}
11. 假设在文件中有1亿个int数据,请选出top100个最小的数来,不用写程序。描述思路即可,尽量使得算法最优。
July的博客有专门的对大数据处理的总结,传送门:http://blog.csdn.net/v_july_v/article/details/7382693