1. 程式人生 > >牛客網錯題集-C++

牛客網錯題集-C++

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++的深拷貝與淺拷貝。深拷貝是指在新建立的物件中重新申請記憶體空間,淺拷貝是簡單的將新物件的指標指向原有物件的記憶體空間,並未重新分配空間,在物件析構時會出現執行錯誤。