笔试常见试题

本文深入探讨了C++中的构造和析构过程、delete与delete[]的区别、指针与引用的不同之处、常量指针与指向常量的指针的区别,并提供了一个string类的实现案例。此外,还介绍了一个具体的链表应用示例。

1、c++类的构造和析构?

      构造函数: 1、定义与类名相同的成员函数叫构造函数

                        2、构造函数在定义时可以有参数

                       3、没有任何返回类型的声明

     析构函数:1、清理对象的函数,没有参数也没有任何返回类型的声明

                      2、在对象销毁时自动调用

先创建的对象后析构,类没有提供构造函数c++编译器会自动给你提供一个默认的构造函数,类没有提供拷贝构造函数,c++会提供一个默认的拷贝构造函数,

拷贝函数调用时机:

1、Test(const Test &obj)

    Test t1(1,2);

    Test t2(3,4);

    Test  t3 =t1;//用t1来初始化t3 会调用拷贝构造函数

    t2 =t1;//用t1给t2赋值,不会调用拷贝构造函数会调用 operator =()

  赋值操作和初始化是两个不同的概念。

2、第二种调用时机

    Test t1(1,2);

   Test t2(t1);//用t1对象初始化t2对象 时会调用拷贝构造函数

3、第三种调用时机

  当类的对象当作实参传给形参时,调用拷贝构造函数

   Test t1(1,2);

  void Gets(Test t);

 Gets(t1);//会调用拷贝构造函数

4、第四种调用时机

 void play ()

{   

     Test t1;

    t1 =g();//用返回的匿名对象赋值给另外一个同类型的对象,那么匿名对象被析构,

   Test t2 = g();

  //用返回的匿名对象,来初始化另外一个同类型的对象,那么匿名对象会直接转成新的对象,会调用拷贝构造函数,匿名对象不会析构掉

}

Test g()

{

    Test  a(1,2);

    return a;//返回匿名对象

}

构造函数执行顺序:先构造的后析构,后构造的先析构,它相当于一个栈,先进后出。

2、delete和delete[]的区别

new 和 delete是操作符,free和malloc是c/c++的标准函数库

delete 释放new分配的单个对象指针指向的内存
delete[] 释放new分配的对象数组指针指向的内存

C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。 

 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。 基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。对于 new 的单个对象,只能用 delete 不能用 delete[] 回收空间。

3、指针和引用的区别

  (1)、指针可以赋予空值,引用不可以赋值空值且当被创建的时候必须初始化,

  (2)、指针的指向可以改变,当应用初始化后不可以改变,

  (3)、sizeof指针 得到的为指针本身的大小,在32位系统中为4个字节,sizeof引用的字节大小为引用对象的大小

 (4)、指针有多级指针,引用只有一级

  (5)、指针和引用的自增++运算意义不一样

4、代码定义了一个常量指针和一个指向常量的指针,问2个指针有什么区别?

  常量指针是指指针本身是常量,指向的对象是变量

  指向常量的指针是指:指针本身是变量,指向的对象是常量

5、string 类的成员函数补全,包括3种构造函数和一种=的运算符重载。

#include <iostream>  
#include <string.h>  
#include "String.h"  
  
using namespace std;  
  
String::String()  
{  
    str_ = new char['\0'];  
    cout << "default construct String!" << endl;  
}  
  
String::String(char *str)  
{  
    cout << "construct String!" << endl;  
  
    int len = strlen(str) + 1;  
    str_ = new char[len];  
    memset(str_, 0, len);  
    strcpy(str_, str)  
}  
  
String::String(const String& other)  
{  
    int len = strlen(other.str_) + 1;  
    str_ = new char[len];  
    memset(str_, 0, len);  
    strcpy(str_, other.str_);  
}  
  
String& String::operator=(const String& other)  
{  
    if(this == &other)  
    {  
        return *this;  
    }  
      
    int len = strlen(other.str_) + 1;  
    delete [] str_;  
    str_ = new char[len];  
    memset(str_, 0, len);  
    strcpy(str_, other.str_);  
  
    return *this;  
}  
  
String& String::operator=(char *str)  
{  
    delete [] str_;  
    int len = strlen(str) + 1;  
    str_ = new char[len];  
    memset(str_, 0, len);  
    strcpy(str_, str);  
  
    return *this;  
}  
  
char& String::operator[](unsigned int index)  
{  
    //return str_[index];  
    return const_cast<char&>(static_cast<const String&>(*this)[index]);  
}  
  
const char& String::operator[](unsigned int index) const  
{  
    return str_[index];  
}  
  
String operator+(const String& s1, const String& s2)  
{  
#if 0  
    int len = strlen(s1.str_) + strlen(s2.str_) + 1;  
    char *newptr = new char[len];  
    memset(newptr, 0, len);  
    strcpy(newptr, s1.str_);  
    strcat(newptr, s2.str_);  
    String tmp(newptr);  
#endif  
  
    String tmp(s1);  
  
    tmp += s2;  
  
    return tmp;  
}  
  
String& String::operator+=(const String& s)  
{  
    int len = strlen(s.str_) + strlen(str_) + 1;  
  
    char *newptr = new char[len];  
    memset(newptr, 0, len);  
    strcpy(newptr, str_);  
    strcat(newptr, s.str_);  
    String tmp(newptr);  
      
    delete [] str_;  
    str_ = new char[len];  
    strcpy(str_, newptr);  
  
    return *this;  
}  
  
ostream& operator<<(ostream& out, const String& s)  
{  
    out << s.str_;  
    return out;  
}  
  
istream& operator>>(istream& in, String& s)  
{  
    char buffer[4096];  
  
    in >> buffer;  
    s.str_ = buffer;  
  
    return in;  
}  
  
String::~String()  
{  
    cout << "destroy String!" << endl;  
}  
  
void String::Display()  
{  
    cout << "str = " << str_ << endl;  
}  

#include <iostream>  
#include "String.h"  
  
using namespace std;  
  
int main()  
{  
    String s1("hello");  
    s1.Display();  
  
    String s2(s1);  
    //String s2;  
    //s2.Display();  
#if 0  
    String s3;  
    s3 = s1;  
    //s3 = "hello";  
    s3.Display();  
//#endif  
  
    s1[1] = 'E';  
    s1.Display();  
#endif  
  
    String s3("world");  
#if 0  
    s3 += s1;  
    s3.Display();  
  
    cin >> s2;  
    cout << s2 << endl;  
#endif  
  
    s3 = s1 + s2;  
    s3.Display();  
  
    return 0;  
}  

#ifndef _STRING_H_  
#define _STRING_H_  
#endif  
#include <iostream>  
  
using namespace std;  
  
class String  
{  
public:  
    String();  
    String(char *str);  
    String(const String& other);  
    ~String();  
  
    String& operator=(char *str);  
    String& operator=(const String& other);  
  
    char& operator[](unsigned int index);  
    const char& operator[](unsigned int index) const;  
  
    friend String operator+(const String& s1, const String& s2);  
  
    String& operator+=(const String& s);  
  
    friend ostream& operator<<(ostream& out, const String& s);  
    friend istream& operator>>(istream& in, String& s);  
  
    void Display();  
  
private:  
    char *str_;  
};  

6、编号1-n的人围成1圈,数到m的人站出来,直到所有人站出来,求站出来的人的序列(key:细节处理)

#include"stdafx.h"
#include<iostream>
struct ChainNode
{
    int data;
    ChainNode* next;
};
//编号为1-n的人,数到m的人站出来,求站出来的人的序列(key:细节处理)
int main()
{
    int n, m;
    cin >> n >> m;


    //create circularList
    int len = n;
    ChainNode* headNode = new ChainNode;
    ChainNode* pNode = headNode;
    while (n--)
    {
        pNode->data = len - n;
        if (n)                            //不需要的不申请
        {
            pNode->next = new ChainNode;
            pNode = pNode->next;
        }
    }
    pNode->next = headNode;
    pNode = pNode->next;
    

    //print order
    int rest = len;
    while (rest)                          //用rest判断而不用pNode判断,链表是否为空用指针无法判断
    {
        int cot = m - 2; 
        while (cot--)
        {
            pNode = pNode->next;
        }
        cout << pNode->next->data << endl;
        ChainNode* tmp = pNode->next;
        pNode->next = pNode->next->next;
        delete tmp;
        rest--;
        pNode = pNode->next;
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值