練一練!3道經典嵌入式C 面試題,答案在文末

2021-08-21 09:32:35 字數 2674 閱讀 1963

題一,堆和棧的區別是?

題二,volatile與register的區別是?

題三,arm裡的大端格式和小端格式分別是什麼意思?

(1)儲存內容不同

堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容由程式設計師分配。

(2)管理方式上不同

棧:由系統自動分配並釋放空間。 例如,宣告在函式中乙個區域性變數 int b; 系統自動在棧中為b開闢空間,當對應的生存週期結束後棧空間被自動釋放。

堆:需要程式設計師指定大小手動申請和手動釋放,在c語言中使用malloc函式申請,使用free函式釋放。

(3)空間大小不同

堆:獲得空間根據系統的有效虛擬記憶體有關,比較靈活、大。

(4)能否產生碎片不同

棧:不會產生碎片,空間連續。

堆:採用的是鍊錶的儲存方式,會產生碎片。

(5)生長方向不同

(6)分配方式不同

棧:有2種分配方式:靜態分配和動態分配,靜態由編譯器完成,例如區域性變數;動態由malloc函式實現,由編譯器進行釋放。

堆: 都是動態分配的,沒有靜態分配的堆。

(7)分配效率不同

棧:由系統自動分配,速度較快。但程式設計師無法控制。

堆:由new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便。

a.volatile

volatile是易變的,不穩定的意思,volatile是關鍵字,是一種型別修飾符,用它修飾的變數表示可以被某些編譯器未知的因素更改,比如作業系統、硬體或者其他執行緒等,遇到這個關鍵字宣告的變數,編譯器對訪問該變數的**不在進行優化,從而可以提供對特殊位址的穩定訪問。那麼什麼是編譯器優化呢?

為了提高執行效率,攻城師們費盡心機地把**優化,優化程式執行時訪問速度。一般,分為硬體優化和軟體優化。硬體優化,流水線工作,詳細可以參考《計算機組成原理》。軟體優化,一部分是程式猿們做的**優化(前提你得有優化的思路和能力),還有一部分就是我們的編譯器優化了。

現代的編譯器經過那麼多年的發展,已經比較成熟,它會把多餘的變數忽略掉,讓**的執行效率更高。預設情況下,編譯器都會對**進行優化,會把一些變數在暫存器裡訪問,而不是在記憶體裡訪問,如此一來,cpu在自己家裡拿東西當然比從記憶體那裡拿東西要快得多。舉個小栗子:

int i = 5;

int a = i;

…… int b = i;

編譯器發現兩次從i讀資料的**之間,並沒有對i進行過操作,它會自動把上次讀的資料放在b中,而不是重新從i裡面讀取。

而volatile關鍵字告訴編譯器該變數是隨時可能發生變化的,每次使用它的時候必須從記憶體中取出它的值,因而編譯器生成的彙編**會從原記憶體位址中讀取資料使用,而不是從暫存器或者快取中讀取,從而保證了對特殊位址的穩定訪問。

簡言之,狀態要經常變化的,為了防止我們編譯優化而導致的訪問的資料不同步的問題,這時我們就需要用到volatile。那具體到什麼場景下需要用到volatile關鍵字呢?

1、並行裝置的硬體暫存器(如:狀態暫存器);

2、乙個中斷服務子程式中會訪問到的非自動變數();

3、多執行緒應用中被幾個任務共享的變數;

上面提到了非自動變數,這裡進一步對幾種變數做一番解釋:

自動變數:是在函式內部定義和使用的變數,它是區域性變數。

非自動變數:有兩種,一種是全域性變數,一種是靜態變數。

全域性變數:在函式外面定義的變數,只能定義一次,不能有重複的定義,不然就會發生錯誤,而其他的檔案要想使用這個變數,需要extern來宣告這個變數(也可省略,因為預設就是extern),這個宣告叫做引用宣告。

若不想被其他檔案訪問,則用static關鍵字宣告為靜態變數。靜態變數與自動變數的本質區別是,靜態變數並不像自動變數那樣使用堆疊機制來使用記憶體。

而是為靜態變數分配固定的記憶體,在程式執行的整個過程中,它都會被保持,而不會被銷毀。這就是說靜態變數的持續性是程式執行的整個週期。這有利於我們共享一些資料。

如果靜態變數在函式內部定義,則它的作用域就是在這個函式內部,僅在這個函式內部使用它才有效,但是它不同於自動變數,自動變數離開函式後就會被銷毀,而靜態變數不會被銷毀。他在函式的整個執行週期內都會存在。

b. register

這個關鍵字請求編譯器盡可能的將變數存在cpu內部暫存器中,而不是通過記憶體定址訪問,以提高效率。注意是盡可能,不是絕對。你想想,乙個cpu 的暫存器也就那麼幾個或幾十個,你要是定義了很多很多register 變數,它累死也可能不能全部把這些變數放入暫存器吧。

當前的儲存器,多以byte為訪問的最小單元,當乙個邏輯上的位址必須分割為物理上的若干單元時就存在了先放誰後放誰的問題, 於是端(endian)的問題應運而生了, 對於不同的儲存方法, 就有大端(big-endian)和小端(little- endian)兩個描述。

位元組排序按分為大端和小端,概念如下

大端(big endian): 低位址存放高有效位元組

小端(little endian): 低位元組存放低有效位元組

現在主流的cpu, intel系列的是採用的little endian的格式存放資料,而motorola系列的cpu採用的是big endian,arm則同時支援 big和little。

舉個例子

int a = 0x12345678;

a是四位元組的int型別變數,需要佔四個位元組空間,假設變數a的首位址是0x2000,那麼資料儲存在位址中的格式如下:

3道經典嵌入式Linux面試題

題一 簡述memcpy和strcpy的區別?題二 訊號量與互斥鎖的區別?題三 簡述程式編譯的過程?題一答案 1 複製的內容不同。strcpy只能複製字串,而memcpy可以複製任意內容,例如字元陣列 整型 結構體 類等。2 複製的方法不同。strcpy不需要指定長度,它遇到被複製字串的結束符 0 才...

面試題解析,3道經典嵌入式Linux面試題

題一 簡述memcpy和strcpy的區別?題二 訊號量與互斥鎖的區別?題三 簡述程式編譯的過程?題一答案 1 複製的內容不同。strcpy只能複製字串,而memcpy可以複製任意內容,例如字元陣列 整型 結構體 類等。2 複製的方法不同。strcpy不需要指定長度,它遇到被複製字元的串結束符 0 ...

面試題每日一練 2020 06 03

邏輯思維題 1 3l和5l的桶,要得到4l的水如何操作?步驟 先裝滿3l的桶,倒入5l的桶裡面 裝滿3l的桶並倒水進5l的桶直到滿了 此時3l剩餘1l的水 將5l的水倒了,剩餘的1l倒進去 裝滿3l的匯入,此時5l的桶就有4l的水了。2 2個沙漏乙個4分鐘漏完,乙個7分鐘漏完,怎麼製作乙個9分鐘的漏...