C/C++ 笔试(三)

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值