[C++面試題]之預先處理、const與sizeof

來源:互聯網
上載者:User
文章目錄
  • 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。

 

看了這些希望也對你有協助

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.