31.简述数组与指针的区别?
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 编译器不能发现该错误,运行时错误
(2) 用运算符sizeof 可以计算出数组的容量(字节数)。sizeof(p),p 为指针得到的是一个指针变量的字节数,而不是p 所指的内存容量。C++/C 语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
char a[] ="hello world";
char*p = a;
cout<<sizeof(a) << endl; // 12 字节
cout<<sizeof(p) << endl; // 4 字节
计算数组和指针的内存容量
void Func(char a[100])
{
cout<<sizeof(a) << endl; // 4 字节而不是100 字节
}
31.类成员函数的重载、覆盖和隐藏区别?
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)
32. 如何打印出当前源文件的文件名以及源文件的当前行号?
cout << FILE ;
cout<<LINE ;
33. main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?
void main( void )
{
String str("zhanglin");
_onexit( fn1 );
_onexit( fn2 );
_onexit( fn3 );
_onexit( fn4 );
printf( "This is executed first.\n" );
}
int fn1()
{
printf( "next.\n" );
return0;
}
int fn2()
{
printf( "executed " );
return0;
}
int fn3()
{
printf( "is " );
return0;
}
int fn4()
{
printf( "This " );
return0;
}
34. 如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
#ifdef __cplusplus
cout<<"c++";
#else
cout<<"c";
#endif
35.文件中有一组整数,要求排序后输出到另一个文件中(面试官,超级喜欢考排序的。你要去面试,数据结构的那几个排序一定要非常熟悉,用笔也可以写出代码来,用笔写代码,就是这样变态啊,其实感觉没有必要这样笔试)
#include<iostream>
#include<fstream>
usingnamespace std;
void Order(vector<int>& data)//bubble sort
{
int count = data.size() ;
int tag =false ; // 设置是否需要继续冒泡的标志位
for ( int i =0 ; i < count ; i++)
{
for ( int j =0 ; j < count - i -1 ; j++)
{
if ( data[j] > data[j+1])
{
tag =true ;
int temp = data[j] ;
data[j] = data[j+1] ;
data[j+1] = temp ;
}
}
if ( !tag )
break ;
}
}
void main( void )
{
vector<int>data;
ifstream in("c:\\data.txt");
if ( !in)
{
cout<<"file error!";
exit(1);
}
int temp;
while (!in.eof())
{
in>>temp;
data.push_back(temp);
}
in.close(); //关闭输入文件流
Order(data);
ofstream out("c:\\result.txt");
if ( !out)
{
cout<<"file error!";
exit(1);
}
for ( i =0 ; i < data.size() ; i++)
out<<data[i]<<"";
out.close(); //关闭输出文件流
}
36. 链表题:一个链表的结点结构
struct Node
{
int data ;
Node *next ;
};
typedef struct Node Node ;
class Solution {
public:
ListNode* ReverseList(ListNode* pHead)
{
// 反转指针
ListNode* pNode=pHead; // 当前节点
ListNode* pPrev=nullptr;// 当前节点的上一个节点
ListNode* pNext=nullptr;// 当前节点的下一个节点
ListNode* pReverseHead=nullptr;//新链表的头指针
// 反转链表
while(pNode!=nullptr)
{
pNext=pNode->next; // 建立链接
if(pNext==NULL) // 判断pNode是否是最后一个节点
pReverseHead=pNode;
pNode->next=pPrev; // 指针反转
pPrev=pNode;
pNode=pNext;
}
return pReverseHead;
}
};
37、已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode temp(0);
ListNode *pre = &temp;
while(pHead1&&pHead2)
{
if(pHead1->val<=pHead2->val)
{
pre->next = pHead1;
pHead1= pHead1->next;
}
else
{
pre->next = pHead2;
pHead2= pHead2->next;
}
pre = pre->next;
}
if(pHead1)
{
pre->next = pHead1;
}
if(pHead2)
{
pre->next = pHead2;
}
return temp.next;
}
};
38、已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序,这次要求用递归方法进行。(Autodesk)
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
// 鲁棒性(边界检查)
if(pHead1==nullptr)
return pHead2;
if(pHead2==nullptr)
return pHead1;
// 递归合并
ListNode* head = nullptr;
if(pHead1->val < pHead2->val)
{
head = pHead1;
head->next = Merge(pHead1->next,pHead2);
}
else
{
head = pHead2;
head->next = Merge(pHead1,pHead2->next);
}
return head;
}
};
39、写一个函数找出一个整数数组中,第二大的数(microsoft)
//初始化最大值为a[0],次大值为a[1],遍历一次,每次比较并更新最大值和次大值,最后就可以得到次大值。
int findsecondmaxvalue(int *a,int size)
{
int max = a[0]; //最大值
int second = a[1]; //次大值
for(int i = 0;i < size;i++)
{
if(a[i] > max) //更新最大值和次大值
{
second = max; //步骤1
max = a[i]; //步骤2
}
else if(a[i] < max && a[i] > second) //更新次大值
{
second = a[i];
}
}
return second;
}
int main(void)
{
int a[] = {22,222,76,26,87,99};
printf("second value = %d\n",findsecondmaxvalue(a,sizeof(a)/sizeof(a[0])));
return 0;
}
40. 写一个在一个字符串(n)中寻找一个子串(m)第一个位置的函数。
KMP算法效率最好,时间复杂度是O(n+m)。
41. 多重继承的内存分配问题:
比如有class A : public class B, public classC {}
那么A的内存结构大致是怎么样的?
答:参考《深入探索C++对象模型》
本人博客有一篇 C++ - 对象模型之内存布局(一)有描述到
42. 如何判断一个单链表是有环的?(注意不能用标志位,最多只能用两个额外指针)
struct node { char val; node* next;}
bool check(const node* head) {}
//return false : 无环;true: 有环一种O(n)的办法就是
//(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
bool check(const node* head)
{
if(head==NULL)
return false;
node *low=head, *fast=head->next;
while(fast!=NULL && fast->next!=NULL)
{
low=low->next;
fast=fast->next->next;
if(low==fast)
{
return true;
}
}
return false;
}