【秋招】C++面试题

本文主要探讨了C++中的sizeof运算符,包括空类型实例的大小、sizeof的作用、不同类型的数据大小以及在数组和类中的应用。同时,提到了面试中常见的数组查找重复数字、两数之和问题,以及时间复杂度、空间复杂度等知识点,还涉及了C++版本差异、C++与Python的区别、数据结构和网络编程等相关面试主题。

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

sizeof

1.定义一个空的类型,里面没有任何成员变量和成员函数,对该类型求sizeof,得到的结果是多少?

答案:1

问:为什么不是0?

答案:空类型的实例中不包含任何信息,本来对其求sizeof应该是0,但是当我们在声明该类型实例的时候,它必须在内存中占一定的空间,否则无法使用这些实例。至于到底要占多少内存空间则由编译器决定。在visual studio中,每个空类型的实例占用1字节的空间。

2.sizeof 是什么?

答案:sizeof 是一个关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小。

sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。

使用 sizeof 的语法如下:

sizeof (data type);
sizeof (object);
sizeof object;

3.各数据类型的sizeof大小?

32位 64位
char 1 1
int 4 大多数4少部分8
long 4 8
float 4 4
double 8 8
指针 4 8
short 2
  1. sizeof(a)/sizeof(a[0]) 表示的是什么?

    答案: 可以获取数组的长度,原理是 sizeof(a) 代表整个数组的大小,sizeof(a[0]) 代表数组中第一个元素的大小,而数组中的每个元素大小都是相同的,所以最后的计算结果就是数组的长度。

    但是!这个问题也不绝对,如果数组作为参数传入到函数中,结果得到的就不是数组的大小了,sizeof(a)得到的是指针的大小。

  2. 字节对齐,sizeof(MyStruct)?
    struct MyStruct 
    { 
    double dda1; 
    char dda; 
    int type 
    }; 
    
    答案:16
    原因:各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照各自的对齐方式调整位置,空缺的字节Visual Studio会自动填充。
    (1)先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;
    
    (2)接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用 sizeof(char)=1个字节;
    
    (3)接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof (int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的(4)地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;
    (5)这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+ 3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。 
    
    
  3. 常用类型(32位)的对齐方式:

    char 偏移量必须为sizeof(char)1的倍数
    int 偏移量必须为4的倍数
    float 偏移量必须为4的倍数
    double 偏移量必须为8的倍数
    short 偏移量必须为8的倍数
  4. 问题:求以下结构体所占用的内存空间?sizeof(MyStruct)
    struct MyStruct 
    { 
    char dda; 
    double dda1; 
    int type 
    }; 
    答案:24bytes
    解析:偏移量为0,满足对齐方式,dda占用1个字节;
    下一个可用的地址的偏移量为1,不是sizeof(double)=8的倍数,需要补足7个字节才能使偏移量变为8(满足对齐方式),因此VC自动填充7个字节,dda1存放在偏移量为8的地址上,它占用8个字节。
    下一个可用的地址的偏移量为16,是sizeof(int)=4的倍数,满足int的对齐方式,所以不需要VC自动填充,type存放在偏移量为16的地址上,它占用4个字节。
    下一个可用的地址的偏移量为16,是sizeof(int)=4的倍数,满足int的对齐方式,所以不需要VC自动填充,type存放在偏移量为16的地址上,它占用4个字节。
    
    
    struct S3  
    {  
    };  
    sizeof(S3); //值为1,空结构体也占内存
    

9.数组的sizeof:

char a[10];  
char n[] = "abc";   
  
cout<<"char a[10]"<<sizeof(a)<<endl;//数组,值为10  
  
cout<<"char n[] = /"abc/"  "<<sizeof(n)<<endl;//字符串数组,将'/0'计算进去,值为4

解析:1)当字符数组表示字符串时,其sizeof值将’/0’计算进去。

     2)当数组为形参时,其sizeof值相当于指针的sizeof值。 

10.类中含有virtual时的sizeof?

类中含有virtual时(无论一个还是多个),内存中就会出现一个虚指针,而指针的大小为4,所以类的大小也是4;

单一继承下,无论父类还是派生类中存在虚函数,派生类中大小都为4(只考虑虚函数,无其他成员),虚函数地址都存在于虚函数指针指向的虚函数表中。

多重继承时,派生类会出现多个虚指针,此时大小就要具体计算了,如图继承两个含有虚函数的基类,派生类中存在两个虚指针,其大小为8。
class BaseAA{
public:
      virtual void AATest(){};
};
class BaseAAA:public BaseA,public BaseAA
{
vitrual void AATest(){};
};

size of (BaseAAA):8 bytes
某32位系统下, C++程序,请计算sizeof 的值
char str[] = “http://www.ibegroup.com/”
char *p = str ;
int n = 10;
请计算
sizeof (str ) = ?  //25
sizeof ( p ) = ?   //4
sizeof ( n ) = ?   //4

void Foo ( char str[100]){
请计算
sizeof( str ) = ?  //4
}

void *p = malloc( 100 );
请计算
sizeof ( p ) = ?   //4

  1. 题目一:在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7,的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数组2或者3。(n个元素,n种可能的取值)

    ##解法二开辟一个新数组B,每次扫描源数组A中的元素,如果不在B中,就加入B中,如果在B中,就找到一个重复的元素,时间复杂度log(n)
    ##python
    lisA=[8,5,3,3,7,6,3,9,1,8]
    def findDuplicates(lisA):
        lisB = []
        for i in lisA:
            if i in lisB:
                print("找到一个重复的元素:%d"%i)
                break
            else:                   #当前扫描的元素不在lisB中,就加入到lisB中
                lisB.append(i)
                continue
    findDuplicates(lisA)
    
    ##解法三因为列表总共有n个元素,所有元素可能取到的元素有0~n-1,共n种。如果不存在重复的数字,那么排序后数字i将会出现在下标为i的位置。现在让我们重新扫描数组,
    
    当扫描到下标为i的数字时,首先比较这个数字(记为m)与i是否相等:
    如果是,继续扫描下一个元素,
    如果不是,则再拿它与第m个数字比较:
    如果它和第m个数字相同,就找到了一个重复的元素;
    如果不同,就将m与第m个数字互换。接下来继续重头开始,重复换这个比较。
    ##python
    lisA=[8,0,2,3,7,6,4,2,1,5]
    def findDuplicates(lisA):
     
        i=0
        while i <len(lisA) and lisA!=[]:
            m = lisA[i]
            if m == i:    
                i += 1
            else:
                if m == lisA[m]:
                    print('找到一个重复的元素:%d' % m)
                    break
                else:
                    temp = lisA[i]
                    lisA[i] = lisA[m]
                    lisA[m] = temp
                    i = 0
     
    findDuplicates(lisA)
    
    

13.leetcode两数之和:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

你可以按任意顺序返回答案。

##最优解
def twoSum(self,nums, target):
    dct = {}
    for i, n in enumerate(nums):
        if target - n in dct:
            return [dct[target - n], i]
        dct[n] = i

##我的答案:
class Solution:
    def twoSum (self,nums,target):
        
        for i in range(len(nums)):
            for k in range(i+1,len(nums)):
                if nums[i]+nums[k]==target:
        
                    return i,k


if __name__=='__main__':
    s=Solution()
    s.twoSum([2,7,11,15],9)

14.时间复杂度与空间复杂度

时间复杂度简单来说指的是语句的执行次数,而空间复杂度表示算法所占的存储空间
按数量级递增排列,常见的时间复杂度有:
常数阶O(1),
对数阶O(log2n),
线性阶O(n),
线性对数阶O(nlog2n),
平方阶O(n^2),
立方阶O(n^3),…,
k次方阶O(n^k),
指数阶O(2^n)。

15.各算法复杂度自查表

img

Snipaste_2019-09-20_17-16-14

数组排序image-20190920164408891

图操作

image-20190920164509533

堆操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值