牛客网错题集-C++

本文详细介绍了C++中的枚举初值、地址运算、类大小计算、虚函数继承中的函数调用、静态局部变量以及深浅拷贝的概念。枚举默认初始化值、地址运算的字节计算、类成员对齐方式、虚函数调用机制、静态局部变量的存储特性以及拷贝构造与复制运算符在深浅拷贝中的作用,都得到了深入讨论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 枚举初值

enum string{    
    x1,    
    x2,    
    x3=10,    
    x4,    
    x5,    
} x;

函数外部问x等于什么?
定义在函数外是全局变量,程序初始化为0;若是定义在函数内,编译器提示变量未初始化错误。此时x1=0,x2=1,x3=10,x4=11,x5=12。相应的,若x1=’a’,则输出时,x1=97(取’a’的ascii码值),x2=98,以此类推。同时枚举类型数据占4个字节,与int相同。

2.地址运算

unsigned char *p1;
unsigned long *p2;
p1=(unsigned char *)0x801000;
p2=(unsigned long *)0x810000;

请问p1+5= 什么?
p2+5= 什么?
1代表的是一个单位量
p1+5=p1+5*1=p1+5*sizeof(unsigned char)=p1+5*1=0x801000+ox5=0x801005
p2+5=p2+5*1=p2+5*sizeof(unsigned long)=p1+5*4=0x810000+20=0x810000+0x14=0x810014
最后要转换成16进制。

3. 类所占字节大小计算

若char是一字节,int是4字节,指针类型是4字节,代码如下:

class CTest
{
    public:
        CTest():m_chData(‘\0’),m_nData(0)
        {
        }
        virtual void mem_fun(){}
    private:
        char m_chData;
        int m_nData;
        static char s_chData;
};
char CTest::s_chData=’\0’;

问:
(1)若按4字节对齐sizeof(CTest)的值是多少?
(2)若按1字节对齐sizeof(CTest)的值是多少?
一张图说明类中成员变量,成员函数,静态变量与函数的空间位置。
这里写图片描述
4字节对齐,结果是12= 4(虚表指针)+1(char )+3(对齐补位)+4(int)
1字节对齐,结果是9 =4(虚表指针)+1(char )+4(int)

4.虚函数继承中函数调用关系

写出输出结果

class A
{
public:
 void FuncA()
 {
     printf( "FuncA called\n" );
 }
 virtual void FuncB()
 {
     printf( "FuncB called\n" );
 }
};
class B : public A
{
public:
 void FuncA()
 {
     A::FuncA();
     printf( "FuncAB called\n" );
 }
 virtual void FuncB()
 {
     printf( "FuncBB called\n" );
 }
};
void main( void )
{
 B  b;
 A  *pa;
 pa = &b;
 A *pa2 = new A;
 pa->FuncA(); ( 3)
 pa->FuncB(); ( 4)
 pa2->FuncA(); ( 5)
 pa2->FuncB();
 delete pa2;
}

FuncA called
FuncBB called
FuncA called
FuncB called
父类指针指向子类实例对象,调用普通重写方法时,会调用父类中的方法。而调用被子类重写虚函数时,会调用子类中的方法。
再次说明了,子类中被重写的虚函数的运行方式是动态绑定的,与当前指向类实例的父类指针类型无关,仅和类实例对象本身有关。

5.静态局部变量

写出下列程序的运行结果。

#include "stdio.h"
int sum(int a)
{
    auto int c = 0;
    static int b = 3;
    c += 1;
    b += 2;
    return (a + b + c);
}
int main()
{
    int i;
    int a = 2;
    for (i = 0; i < 5; i++) 
    { 
        printf("%d,", sum(a)); 
    } 
} 

8,10,12,14,16,
c为局部变量,存储在栈内存区,每次调用重新初始化;b为静态局部变量,存储在全局数据区,在函数调用过程中始终存在,并被每次加2。详情见C++中的static关键字总结这篇博文。

6.深浅拷贝

#include<iostream>
using namespace std;
class MyClass
{
public:
    MyClass(int i = 0)
    {
        cout << i;
    }
    MyClass(const MyClass &x)
    {
        cout << 2;
    }
    MyClass &operator=(const MyClass &x)
    {
        cout << 3;
        return *this;
    }
    ~MyClass()
    {
        cout << 4;
    }
};
int main()
{
    MyClass obj1(1), obj2(2);
    MyClass obj3 = obj1;
    return 0;
}

运行时的输出结果是(122444
obj3还不存在,所以调用拷贝构造函数输出2,如果obj3存在,obj3=obj,则调用复制运算符重载函数,输出3这里还是浅拷贝操作。可以参考这篇博文C++的深拷贝与浅拷贝。深拷贝是指在新创建的对象中重新申请内存空间,浅拷贝是简单的将新对象的指针指向原有对象的内存空间,并未重新分配空间,在对象析构时会出现运行错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值