文章目錄
- 1、用預先處理指令#define聲明一個常數,用以表明一年中有多少秒(忽略閏年的問題)
- 2、寫一個“標準”的宏MIN,這個宏輸入兩個參數並返回較少的一個
- 3、const有什麼用途?請至少說明兩種?
- 4、const與#define相比有什麼不同?
- 5、下面代碼輸出結果是什嗎?
- 6、以下代碼為32位機器編譯,資料是以4位元組為單位,這兩個類型的輸出結果為什麼不同?
- 7、說明sizeof和strlen之間的區別
- 8、以下代碼的輸出結果是多少?
- 9、一個空類佔多少空間?多重繼承的空類呢?
大四了,開始找工作了,發現很多公司軟體開發類的筆試題都是考C++的,所以最近總結一下看到的一些題。
然而,預先處理、const和sizeof問題是C++語言中的幾個重點也是痛點,也是各大企業不論是筆試還是面試都喜歡出的題型,下面是個人從網上和書籍中收集或總結的一點資料。希望能跟和我一樣在辛苦找工作的同學們共同分享,也願以下資料能幫到你找到合適滿意的工作。
1、用預先處理指令#define聲明一個常數,用以表明一年中有多少秒(忽略閏年的問題)
解析:1.#define文法的基本知識(例如,不能以分號結束,括弧的使用等)
2.要懂得前置處理器將為你計算常數運算式的值,因此,寫出你是如何計算一年中有多少秒而不是計算出實際的值,會更好意義。
3.意識到這個運算式將使一個16位機的整型數溢出,因此要用到長整形符號L,告訴編譯器這個常數是長整型數。
如果運算式中用到UL(表示無符號長整型),那麼你就有了一個好的第一印象了,記住,第一印象很重要。
答案:
#define SECONDS_PER_YEAR(60*60*24*365)UL
2、寫一個“標準”的宏MIN,這個宏輸入兩個參數並返回較少的一個
解析:1.標識#define在宏中應用的基本知識,這是很重要的,因為知道嵌入操作符變為標準C的一部分,宏都是方便地產生內嵌程式碼的唯一方法。對伊嵌入
式系統來說,為了能達到要求的效能,內嵌程式碼經常是必須的方法。
2.三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產生比if-then-else更最佳化的代碼,瞭解這個用法是很重要的。
3.懂得在宏中小心的把參數用括弧括起來。
答案:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))
3、const有什麼用途?請至少說明兩種?
解析:在C程式中,const的用法主要有定義常量、修飾函數參數、修飾函數傳回值。在C++程式中,它還可以修飾函數的定義體,定義類中某個成員函數為恒態函數,即不改變類中的資料成員。
答案:
(1)可以定義const常量。(2)const可以修飾函數的參數和傳回值,甚至函數的定義體。被const修飾的東西都受到強制保護,可以預防意外的變動,能提高程式的健壯性。
4、const與#define相比有什麼不同?
答案:
C++語言可以用const定義常量,也可以用#define定義常量,但是前者比後者有更多的有點:
(1)const常量有資料類型,而宏常量沒有資料類型。編譯器可以對前者進行 型別安全檢查,而對後者只是進行字元替換,沒有型別安全檢查,並且在字元替換中可能產生意料不到的錯誤(邊際效應)。
(2)有些整合話的調試工具可以對const常量進行調試,但是不能對宏常量進行調試。在C++程式中只使用const常量而不使用宏常量,即const常量完全取代宏常量。
5、下面代碼輸出結果是什嗎?
#include<iostream>using namespace std;struct{short a1;short a2;short a3;}A;struct{long a1;short a2;}B;int main (){char* ss1 = "0123456789";char ss2[] = "0123456789";char ss3[100] = "0123456789";int ss4[100];char q1[] = "abc";char q2[] = "a\n";char* q3 = "a\n";char *str1 = (char *)malloc(100);void *str2 = (void *)malloc(100);cout<<"sizeof(ss1):"<<sizeof(ss1)<<endl;cout<<"sizeof(ss2):"<<sizeof(ss2)<<endl;cout<<"sizeof(ss3):"<<sizeof(ss3)<<endl;cout<<"sizeof(ss4):"<<sizeof(ss4)<<endl;cout<<"sizeof(q1):"<<sizeof(q1)<<endl;cout<<"sizeof(q2):"<<sizeof(q2)<<endl;cout<<"sizeof(q3):"<<sizeof(q3)<<endl;cout<<"sizeof(A):"<<sizeof(A)<<endl;cout<<"sizeof(B):"<<sizeof(B)<<endl;cout<<"sizeof(str1):"<<sizeof(str1)<<endl;cout<<"sizeof(str2):"<<sizeof(str2)<<endl;return 0;}
解析:ss1是一個字元指標,指標的大小是一個定值,就是4位元組,所以sizeof(ss1)是4位元組
ss2是一個字元數組,這個數組最初未定大小,由具體填儲值來定。填儲值是“0123456789 ”。1個字元所佔空間是1位元組,10個就是10位元組,再加上隱含的“\0”,所以一共是11位元組。
ss3也是一個字元數組,這個數組開始預分配100,所以它的大小一共是100位元組。
ss4也是一個字元數組,這個數組開始預分配100,但是每個整型變數所佔用空間是4,所以它的大小一共是400位元組。
q1與ss2類似,所以是4位元組。
q2裡面有一個“\n”,“\n”算做一位,所以它的空間大小是3位元組。
q3是一個字元指標,指標的大小是一個定值,就是4,所以sizeof(q3)是4位元組。
A和B是兩個結構體,在預設情況下,為了方便對結構體內元素的訪問和管理,當結構體內的元素的長度都小於處理器的位元的時候,便以結構體裡面最長的資料元素為對齊單位,也就是說,結構體的長度一定是最長的資料元素的整數倍。如果結構體記憶體在長度大於處理器位元的元素,那麼就以處理器的位元為對齊單位,但是結構體內類型相同的連續元素將在連續的空間內,和數組一樣。
結構體A中有3個short類型變數,各自以2個位元組對齊,所以sizeof(A)是為6位元組。結構體B中a1以4位元組對齊,a2以2位元組對齊,則結構體大小為6位元組,但是結構體的長度一定是最長資料元素的整數倍,顯然6不是4的整數倍數,補空位元組,增到8位元組,符合所以條件。故sizeof(B)為8位元組。
str1和str2都是字元指標,都是4位元組。
答案:
sizeof(ss1): 4
sizeof(ss2): 11
sizeof(ss3): 100
sizeof(ss4): 400
sizeof(q1): 4
sizeof(q2): 3
sizeof(q3): 4
sizeof(A): 6
sizeof(B): 8
sizeof(str1): 4
sizeof(str2): 4
6、以下代碼為32位機器編譯,資料是以4位元組為單位,這兩個類型的輸出結果為什麼不同?
class B{private:bool m_bTemp1;int m_nTemp;bool m_bTemp2;};class C{private:int m_nTemp;bool m_bTemp1;bool m_bTemp2;};cout << sizeof(B) << endl;cout << sizeof(C) << endl;
解析:編譯器會對結構體進行對齊處理,根據對齊原則。
類型B情況如下:
| bool |-----|----|----|
|-----------int---------|
| bool |-----|----|----|
類型C情況如下:
|-----------int-----------|
| bool | bool |----|----|
答案:
B類輸出12位元組,C類輸出8位元組。
7、說明sizeof和strlen之間的區別
解析:
第1個例子:
char *a="0123456789";
sizeof(a)結果為4,a是指向字串常量的字元指標。
sizeof(*a)結果是1,*a是第一個字元。
strlen(a)結果是10,它內部實現是用一個迴圈計算字元的長度,直到“\0”為止。
第2個例子:
char a[100]="0123456789";
sizeof(a)結果為100,a表示在記憶體中預分配的大小。
strlen(a)結果還是10,它內部實現是用一個迴圈計算字元的長度,直到“\0”為止。
第3個例子:
char a[]="0123456789";
sizeof(a)結果為11,a是數組計算到“\0”位置,因此是(10+1)。
strlen(a)結果還是10,它內部實現是用一個迴圈計算字元的長度,直到“\0”為止。
第4個例子:
int a[100]="0123456789";
sizeof(a)結果為400,a表示在記憶體中預分配的大小,100*4。
strlen(a)錯誤,strlen的參數只能是char*,且必須是以“\0”結尾的。
答案:
(1)sizeof操作符的結果類型是size_t,它在標頭檔中的typedef為unsigned int類型。該類型保證能容納實現所建立的最大對象的位元組大小。
(2)sizeof是運算子,strlen是函數。
(3)sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以“\0”結尾的。sizeof還可以用函數做參數,結果與函數傳回值的類型一致。
(4)數組做sizeof的參數不退化,傳遞給strlen就退化為指標。
(5)strlen的結果要運行時才能計算出來,用來計算字串的長度,而不是類型占記憶體的大小。
(6)sizeof計算結構變數的大小就必須討論資料對齊問題(C++處理資料時經常把結構變數中的成員的大小按照4或8的倍數計算)。
(7)sizeof操作符不能用於函數類型、不完全類型或位欄位。不完全類型指具有未知儲存大小資料的資料類型,如:未知儲存大小的數群組類型、未知內容的結構或等位型別、void類型等。
8、以下代碼的輸出結果是多少?
char var[10]int test (char var[]){return sizeof(var);}
解析:數組作為參數傳遞,傳遞的是一個首地址,等價於*var,已退化成一個指標了,所以大小是4。
答案:
4
9、一個空類佔多少空間?多重繼承的空類呢?
解析:我們用程式來實現一個空類和多重繼承的空類,看看它們的大小是多少。代碼如下:
#include<iostream>using namespace std;class A1{};class A2{};class B : public A1{};class C : public virtual B{};class D : public A1,public A2{};int main (){cout <<"sizeof(A1):" << sizeof(A1) << endl;cout <<"sizeof(B):" << sizeof(B) << endl;cout <<"sizeof(C):" << sizeof(C) << endl;cout <<"sizeof(D):" << sizeof(D) << endl;return 0;}
以上答案分別是1,1,4,1。這說明空類所佔空間為 1,單一繼承的空類空間也是 1,多重繼承的空類空間還是 1,但是虛繼承涉及虛表(虛指標),所以大小為 4。
答案:
一個空類占空間為 1 ,多重繼承的空類所佔空間還是 1,但虛繼承的為 4。
看了這些希望也對你有協助