机试小知识点(一)

32位操作系统有32根地址线,每根两种状态0/1,表示2的32次方个内存单元,每个内存单元占1个字节(OS只能对字节进行操作,位操作用位操作符),1G = 2^10M,1M = 2^10K,1K = 2^10B,2^32B = 4*2^10*2^10*2^10 = 4G

知识点 1:

class Base
{
public:
    virtual ~Base(){cout<<"~Base"<<endl;}
};

class Derive:public Base
{
public:
    ~Derive(){cout<<"~Derive"<<endl;}
};

main
    Base *r = new Derive;
    delete r;
/*
先调用子类的析构函数,再调用父类的析构函数
运行结果:
    ~Derive
    ~Base
*/

知识点 2:

enum e{
    e1,
    e2,
    e3=10,
    e4,
    e5 = 'a',
    e6
}epr;

main
    cout<<e4<<","<<e6<<endl;
/*
运行结果:
    11,98
*/

知识点 3:

struct st_t
{
    int status;
    short* pdata;
    char errstr[32];
};

main
    st_t st[16];
    char *p = (char*)(st[2].errstr+32);
    printf("%d", (p-(char*)(st)));
/*
结构体st_t 占4+4+32 = 40个字节,p-(char*)(st)包含st[0]、st[1]、st[2]
运行结果:
    120
*/

知识点 4:

class  AA
{
public:
    void xoo(){}
    char a, b;
};
//sizeof(AA) = 2
class  AA
{
public:
    void xoo(){}
};
//sizeof(AA) = 1
class  AA
{
public:
    void xoo(){}
    char a;
};
//sizeof(AA) = 1
//同struct

知识点 5:

    char *p[]={"TENCENT","CAMPUS","RECRUITING"};
    char** pp[]={p+2,p+1,p};
    char ***ppp = pp;

    cout<<**++ppp<<endl;//CAMPUS
    cout<<*++*++ppp<<endl;//CAMPUS

知识点 6:

    int a[2][3] = {0, 2, 4, 6, 8, 10};
    cout<<**(a+1)<<endl;//6
    cout<<*(a[1]+1)<<endl;//8
    cout<<**(a+1)+2<<endl;//8
    cout<<*a[0]<<", "<<**a<<endl;//0
    //a[0]表示第一行,a[1]表示第二行

知识点 7 :

    char* chs[3]/* = {"Z189Z11", "84Z0Z11", "5Z11Z11"}*/;

    chs[0] = new char[10];
    chs[1] = new char[10];
    chs[2] = new char[10];
    //不能将字符串直接赋值给字符指针,原因是:指针指向的是字符串的第一个字符
    strcpy(chs[0], "Z189Z11");
    strcpy(chs[1], "84Z0Z11");
    strcpy(chs[2], "5Z11Z11");

    char* ch = "Z11";
    int i = 0, j = 0, k = 0, num = 0;

    for (; i<3; i++)
    {
        j = 0;
        k = 0;
        while(chs[i][j] != '\0' && ch[k] != '\0')
        {
            while(chs[i][j] == ch[k] && ch[k] != '\0')
            {
                j++;
                k++;
            }
            if (k == 3)
            {
                num++;
                j--;//判断连续Z11,倒回去一个
            }
            k = 0;
            j++;
        }
    }
    cout<<num<<endl;

    for (int m = 2; m>=0; m--)
    {
        cout<<chs[m]<<endl;
    }

    for (int m = 0; m<3; m++)
    {
        delete[] chs[m];
    }

知识点 8 :

    //int *b = new int[];//不完整的类型
    //int (*d)[2] = new int[][2];
    //int (*f)[2][3] = new int[][2][3];

    int *a = new int[34];
    int (*c)[2] = new int[34][2];//申请34个两元素的一维数组
    int (*e)[2][3] = new int[34][2][3];//申请34个2*3的二维数组

    //char str1[];
    char str2[]="01234";

    cout<<a<<", "<<a+1<<endl;//相差4个字节 
    cout<<c<<", "<<c+1<<endl;//相差4*2个字节
    cout<<e<<", "<<e+1<<endl;//相差4*2*3个字节

    cout<<typeid(a).name()<<endl;//输出类型名
    cout<<typeid(c).name()<<endl;
    cout<<typeid(e).name()<<endl;

    delete[] a; delete[] c; delete[] e; 

知识点 9 :

//sizeof 计算的则是分配的数组chh[3] 所占的内存空间的大小,不受里面存储的内容影响
//strlen 计算字符串的长度,以'\0'为字符串结束标记
    char *str1="absde";
    char str2[]="01234";
    char str3[8]={'a','b'};//只有前两个有值,其余都是空的
    char str33[3] = {'c', 'd', 'e'};
    char str333[3] = {'c', 'd'};
    char *str4 = new char;
    int *test = new int[8];

    cout<<"sizeof(str1) = "<<sizeof(str1)<<endl;//4,指针变量占4
    cout<<"sizeof(*str1) = "<<sizeof(*str1)<<endl;//1,实际上是第一个字符a所占内存
    cout<<"sizeof(str2) = "<<sizeof(str2)<<endl;//6,加上'/0'
    cout<<"sizeof(str3) = "<<sizeof(str3)<<endl;//8
    cout<<"sizeof(str33) = "<<sizeof(str33)<<endl;//3
    cout<<"sizeof(str333) = "<<sizeof(str333)<<endl;//3
    cout<<"sizeof(test) = "<<sizeof(test)<<endl;//4,指针变量占4
    cout<<"sizeof(str4) = "<<sizeof(str4)<<endl;//4,指针变量占4
    cout<<endl;
    cout<<"strlen(str1) = "<<strlen(str1)<<endl;//5,字符串长度
    cout<<"strlen(str2) = "<<strlen(str2)<<endl;//5
    cout<<"strlen(str3) = "<<strlen(str3)<<endl;//2,只关心存储的数据内容,不关心空间的大小和类型
    cout<<"strlen(str33) = "<<strlen(str33)<<endl;//14 ? ?
    cout<<"strlen(str333) = "<<strlen(str333)<<endl;//2
//  cout<<"strlen(test) = "<<strlen(test)<<endl;//test 非字符串
    cout<<"strlen(str4) = "<<strlen(str4)<<endl;//16 ? ?

    memset(str2, 0, 2);//把数组的前两个元素清0,'\0'和0效果一样,如果是字符0,则用'0'
    for (int i = 0; i<sizeof(str2); i++)//6
    {
        cout<<str2[i]<<",";
    }
    cout<<endl;
    cout<<"sizeof(str2) = "<<sizeof(str2)<<endl;//6
    cout<<"strlen(str2) = "<<strlen(str2)<<endl;//数组的第一个元素如果为'\0',则strlen(str2)为0,因为strlen计算字符串的长度,以'\0'为结束符,编译器检测到'\0'后,直接结束了

    delete str4;
    delete test;

知识点 10 :

    int a[5] = {1,2,3};//不完全初始化,其他元素自动为0
    cout<<"a[3] = "<<a[3]<<", a[4] = "<<a[4]<<endl;

    //倒置一个数组中元素
    int b[7] = {1, 2, 3, 4, 5, 6, 7};

    int i = 0, j = 6;
    int t;
    while (i < j)
    {
        t = b[i];
        b[i] = b[j];
        b[j] = t;

        i++;
        j--;
    }

    for (i = 0; i < 7; i++)
    {
        cout<<b[i]<<endl;
    }

知识点 11 :

int ii = 5;
    int* pp1 = new int[4];//动态分配4个int型内存
    int* pp2 = new int(4);//动态分配4个字节内存

    *pp1 = 666;
    *(pp1+1) = 777;
    *(pp1+2) = 888;
    *(pp1+3) = 999;

    for (int i = 0; i < 4; i++)
    {
        cout<<*(pp1 + i)<<endl;
    }

    *pp2 = 111;
//  *(pp2 + 1) = 222;//中断

    for (int i = 0; i < 4; i++)
    {
        cout<<*(pp2 + i)<<endl;//第一个是111,后三个为不知名数
    }

    int* pp3 = &ii;
    cout<<*(pp3 + 1)<<endl;//pp3 + 1这个地址中的值可以打印,但是不能赋值,因为没有获得控制权

    delete pp1;
    delete pp2;

知识点 12 :

void f(int** q)//改变了p的指向
{
    int i = 5;
    *q = &i;//使p指向i
}

int main()
{
    cout<<"*****************静态内存不能跨函数使用************************"<<endl;

    int* p;
    f(&p);
    cout<<*p<<endl;//error,但是运行成功,编译器的bug
    //f函数终止后,i的内存释放,此时p是野指针
    p = NULL;

    system("pause");
    return 0;
}

知识点 13 :

void fun(char ch, int a = 6, float ff = 8.9)
{
    cout<<a<<", "<<ff<<endl;
}
main()

    int a = 76;
    float ff = 4.3;
    char ch = 'r';

    fun(ch);
    fun(ch, a);
    fun(ch, a, ff);
/*
    6, 8.9
    76, 8.9
    76, 4.3
*/

知识点 14:

    char* p = new char[100];
    strcpy(p, "Hytera");
    strcat(p+2, "Downloader");

    cout<<p<<endl;//HyteraDownloader
    delete[] p;
    //p的指向并没有改变

知识点 15:

    int n[5] = {1,2,3,4,5};
    int *ptr1 = (int*)(&n+1);//&n指向整个数组,保存的是首地址
    int *ptr2 = (int*)(n+1);
    cout<<n<<", "<<&n<<endl;
    cout<<*(n+1)<<", "<<*(ptr1-1)<<*(ptr2-1)<<endl;

知识点 16:

    vector<int> a(3,0);//包含3个0
    vector<int> b(5,0);

    b = a;//完全覆盖
    a = vector<int>();//清零
    cout<<int(a.size())<<endl;//0
    cout<<int(b.size())<<endl;//3

知识点 16:

class A//8
{
    int k[3];
public:
    virtual void aa(){};
};

class B
{
    int j;
public:
    virtual void bb(){};
};

class C
{//char i;//4 char i[4];//4 char i[5];//8 char i[8];//char i[9];//12
    char i[9];//只要有虚函数(4个字节),char每次分配4个字节
public:
    virtual void cc(){};//4
};

class D
{
    char m[3];//取决于此,3
public:
    void dd(){};
};

main
    cout<<sizeof(A)<<endl;
    cout<<sizeof(B)<<endl;
    cout<<sizeof(C)<<endl;
    cout<<sizeof(D)<<endl;

知识点 17:

class A1//1
{};
class A2
{};
class B:public A1//1
{};
class C:public virtual B//4
{};
class D:public virtual A1, virtual public A2//8
{};
class E:public C//4
{};
class F:public A1, public A2//1
{};

知识点 18:

class N
{
protected:
    int m_data;
public:
    N(int data = 0)
    {
        m_data = data;
    }
    int GetData()
    {
        return doGetData();
    }
    virtual int doGetData()
    {
        return m_data;
    }
};
class S:public N
{
protected:
    int m_data;
public:
    S(int data = 1)
    {
        m_data = data;
    }
    int doGetData()
    {
        return m_data;
    }
};
class F:public S
{
protected:
    int m_data;
public:
    F(int data = 2)
    {
        m_data = data;
    }
};
main
    F x(10);

    cout<<x.GetData()<<endl;
    cout<<x.F::GetData()<<endl;
    cout<<x.N::GetData()<<endl;
    cout<<x.S::GetData()<<endl;

    cout<<x.doGetData()<<endl;
    cout<<x.F::doGetData()<<endl;
    cout<<x.N::doGetData()<<endl;
    cout<<x.S::doGetData()<<endl;
//结果:
/*
    1
    1
    1
    1
    1
    1
    0
    1
*/

知识点 18:

//倒序带头节点单向链表
typedef struct Node
{
    int data;
    struct Node* pNext;
}NODE, *PNODE;

//递归
void revSeq1(PNODE p,PNODE pHead)//p = pHead->pNext;
{  
    if(p->pNext==NULL)  
    {  
        pHead->pNext=p;  
        return;//找到最后一个节点  
    }  
    revSeq1(p->pNext,pHead);  
    p->pNext->pNext = p;//反转节点  
    p->pNext = NULL;//第一个节点反转后其后继应该为NULL  
}

//非递归
PNODE revSeq2(PNODE pHead)
{
    PNODE current, p;
    current = pHead->pNext;
    if (current == NULL)
    {
        return NULL;
    }

    while(current->pNext != NULL)
    {
        p = current->pNext;
        current->pNext = p->pNext;
        p->pNext = pHead->pNext;
        pHead->pNext = p;
    }

    return pHead;
}

//倒序单向链表
int main()
{
    //创建链表
    PNODE pHead, pTail;
    pHead = new NODE;

    pTail = pHead;
    pTail->pNext = NULL;

    for (int i = 0; i<5; i++)
    {
        PNODE pNew = new NODE;
        if (pNew == NULL)
        {
            cout<<"动态内存分配失败!"<<endl;
            exit(-1);
        }
        pNew->data = i;
        pTail->pNext = pNew;
        pNew->pNext = NULL;

        pTail = pNew;
    }

    //遍历链表
    PNODE q = pHead->pNext;
    while (q != NULL)
    {
        cout<<q->data<<", ";
        q = q->pNext;
    }
    cout<<endl;
    //逆序链表
    PNODE pHead_rev = revSeq(pHead);

    PNODE q1 = pHead->pNext;
    while (q1 != NULL)
    {
        cout<<q1->data<<", ";
        q1 = q1->pNext;
    }
    cout<<endl;
    //释放内存
    PNODE p = pHead;
    PNODE r = p->pNext;

    while (r != NULL)
    {
        delete p;
        p = r;
        r = r->pNext;
    }

    system("pause");
    return 0;
}

依次将current节点后面的p插入到头节点0的后面

current 始终指向 1这个节点

知识点 19:

char* p = "abc";
    *(p+1) = 'g';//"abc"分配在文字常量区,p在栈区分配使指向"abc",常量"abc"不能被改变
    cout<<p<<endl;//当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错

    /*
    char *s1 的s1,而指针是指向一块内存区域,它指向的内存区域的大小可以随时改变,而且当指针指向常量字符串时,它的内容是不可以被修改的,否则在运行时会报错。
    char s2[]的s2 是数组对应着一块内存区域,其地址和容量在生命期里不会改变,只有数组的内容可以改变
    */

知识点 20:

//float 与零值比较
    const float EPSINON = 0.00001; 
    float x = 0.5;
    if ((x >= - EPSINON) && (x <= EPSINON)){}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值