常見的筆試題--C/C++(持續更新)

1.有三個類A B C定義如下,請確定sizeof(A) sizeof(B) sizeof(C)的大小順序,並給出理由。

struct A{
    A() {}  
    ~A() {}
    int m1;
    int m2;
};

struct B:A{
     B() {}
    ~B() {}
    int m1;
    char m2;
    static char m3;
};
struct C{
    C() {}
    virtual~C() {}
    int m1;
    short m2;
};
答:分別爲8字節,16字節,12字節。A只有兩個int,所以是8字節;B繼承A,char因爲4字節對齊佔4個字節,static不存儲在類中,所以B=8+4+4=16字節;C因爲4字節對齊,所以成員變量佔8字節,有虛函數加4字節虛指針一共12字節。

2.請用C++實現以下print函數,打印鏈表I中的所有元素,每個元素單獨成一行:void print( const std::list<list> &I)

void print( const std::list<int> &I)
{
    //訪問const必須使用const迭代器
    for(const std::list<int>::const_iterator it = I.begin(); it!=I.end(); it++)
        std::cout<<*it<<std::endl;
}

3.假設某C工程包含a.c和b.c兩個文件,在a.c中定義了一個全局變量foo,在b.c中想訪問這一變量時該怎麼做?

答:使用extern

4.函數checkstr判斷一個字符串是不是對稱的,如:“abccba”是對稱的,“abccbaa”則是不對稱的。函數聲明如下,其中msg爲輸入的字符串,對稱返回0,不對稱返回-1,請實現該函數。int checkstr( const char *msg );

int checkstr(const char *msg)
{
	int i = 0, len;
	while(msg[i] != '\0')i++;
	len = i;
	for(i = 0; i < len/2; i++)
		if(msg[i] != msg[len-i-1])
			return -1;
	return 0;
}

5.給出一個單向鏈表的頭指針,輸出該鏈表中倒數第k個節點的指針。鏈表的倒數第0個節點爲鏈表的尾節點(尾節點的next成員爲NULL)。函數findnode實現上述功能,鏈表節點定義及函數聲明如下,請實現函數findnode。

typedef struct Node
{
	struct Node *next;
}Node;
Node* findnode(Node *head, unsigned int k);
答:
Node* findnode(Node *head, unsigned int k)
{
	int cnt = 0;
	Node *p = head;
	while(p)
	{
		cnt++;
		p = p->next;
	}
	if(cnt < k)
		return NULL;
	cnt = cnt - k - 1;
	p = head;
	while(cnt--)
		p = p->next;
	return p;
}

6.請寫出下面程序的運行結果。

int count = 3;
int main()
{
	int i, sum, count = 2;
	for(i = 0, sum = 0; i < count; i += 2,count++)
	{
		static int count = 4;
		count++;
		if(i % 2 == 0)
		{
			extern int count;
			count++;
			sum += count;
		}
		sum += count;
	}
	cout<<count<<' '<<sum<<endl;
	return 0;
}
答:結果爲:4  20。分析:extern是引用全局的count,定義爲static的count只初始化一次,第二次跳過這條語句。for循環裏的count指的是main()裏的,static int count=4這句只執行一次,count++是static這個count,最後輸出的是main()裏的count。

7.請寫出下面程序的運行結果。

void func(char str[50])
{
	cout<<sizeof(str)<<' '<<strlen(str)<<endl;
}
int main()
{
	char stra[] = "HelloWorld";
	char *strb = stra;
	cout<<sizeof(stra)<<' '<<sizeof(strb++)<<endl;
	func(++strb);
	cout<<strlen(stra)<<' '<<strlen(strb++)<<endl;
	return 0;
}
答:
11 4
4 9
10 9
sizeof(stra) = 11:char數組的大小=數組元素的個數=字符個數+1
sizeof(strb++) = 4:strb是一個指針,在32位系統中,指針的大小是4。注意sizeof有一個特性:編譯的時候就把strb替換成類型了,所以裏面任何加減操作都是無效的,事實上++沒有執行
sizeof(str) = 4:不管數組作爲參數怎麼表示,數組還是以地址來傳遞的。str是一個指向stra[1]的指針,所以大小是4,與後面的[50]沒有關係
strlen(str) = 9:strlen是指不包括'\0'的字符的個數,與[50]沒有關係
strlen(stra) = 10:strlen不包括'\0'
strlen(strb++) = 9:strb指向stra[1],再計算長度,再更改strb爲stra[2]

8.請寫出下面程序的運行結果。

struct SC{int a,b,c;};
struct SD{int a,b,c,d;};
int main()
{
	struct SC c1[] = {{3}, {4}, {5}, {6}};
	struct SD *c2 = (struct SD*)c1 + 1;
	cout<<c2->a<<c2->b<<c2->c<<c2->d<<endl;
	return 0;
}
答:0050
c1的存儲方式是這樣的:
3 0 0 | 4 0 0 | 5 0 0 | 6 0 0
c1[0] | c1[2] | c1[3] | c1[4]
c1轉換爲CD結構後是這樣的:
3 0 0 4 | 0 0 5 0 | 0 6 0 0
  c1[0]  |  c1[1]   |    c1[2]
c2 = c1 + 1,因此c2指向轉換後的c1[1],即0050

9.請寫出下面程序的運行結果。

class Base
{
public:

	int m_a;
	Base(int a = 2):m_a(a){cout<<'A'<<m_a;}
	virtual ~Base(){cout<<'B'<<m_a;}
};
class Derived:public Base
{
public:
	Derived(int a = 4):Base(a){cout<<'C'<<m_a;}
	~Derived(){cout<<'D'<<m_a;}
};
int main()
{
	Base *aa, bb;
	aa = new Derived;
	delete aa;
	return 0;
}
答:
答:A2A4C4D4B4B2
L17:生成一個基類對象,調用一次基類的構造函數
L18:生成一個子類的對象,先調用基類構造函數,再調用子類構造函數
L19:由於析構函數是虛函數,根據待釋放對象的類型來調用析構函數。aa指向的是子類對象,先調用子類析構函數,再調用基類析構函數
L21:bb是棧內對象,自動釋放,調用一次基類的析構函數

10.請寫出下面程序的運行結果。

class Base
{
public:
	int m_a, m_b;
	Base(int a = 3, int b = 5):m_a(a), m_b(b){}
	int func_a(){return m_a - m_b;}
	virtual int func_b(){return m_a + m_b;}
};
class Derived:public Base
{
public:
	Derived(int a = 4, int b = 7):Base(a, b){}
	virtual int func_a(){return m_b + m_a;}
	int func_b(){return m_b - m_a;}
};
int main()
{
	Base *aa, *bb;
	aa = new Base(4, 7);
	bb = new Derived(3, 5);
	cout<<aa->func_a()<<' '<<aa->func_b()<<' '<<bb->func_a()<<' '<<bb->func_b()<<endl;
	delete aa;delete bb;
	return 0;
}
答:-3 11 -2 2






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章