【嵌入式面試】2022年嵌入式經典面試題匯總(C語言)

📜作者:不想脫發的基兄

📺專欄:《嵌入式面試》

📣格言:不管前方的路有多苦,只要走的方向正確,不管多么崎嶇不平,都比站在原地更接近幸福。

前言:

2022年秋招我面試嵌入式MCU開發方向,經過了多場的筆試與面試,在準備的過程中看了非常多的資料,我的匯總的筆記一直寫在有道云筆記中,沒有分享出來。現在已經到了23年春招了,特此整理后分享出來。資料看過了覺得不錯就保存下來了,如果有不對的地方,歡迎批評指正,侵權聯刪!

1、遞歸函數定義沒有問題,遞歸深層次后易引發什么問題?

(1)影響執行效率

(2)棧溢出。

因為每一次調用函數是,棧區都要給函數分配空間,而且上一次調用并沒有結束,調用的次數太多,棧區的內存不夠分配了,便會出現棧溢出的情況。

2、堆與棧的區別?

(1)棧的空間是系統自動分配和回收,堆的空間是用戶手動分配回收(malloc,calloc,realloc,free)

(2)棧的空間較小,堆的空間較大

(3)棧的地址空間往地址向下增長,堆的地址空間是由低地址到高地址

(4)棧的存儲效率更高

3、循環控制條件關鍵字goto被經常使用,但是goto的使用場合為什么受到局限?

因為goto會破壞程序的棧邏輯。

4、循環控制條件關鍵字goto的使用場景有哪些?

(1)常用來跳出死循壞;

(2)打印錯誤;

(3)goto被經常使用,只是使用場合受到局限,因為他會破壞程序的棧邏輯。

5、字節對齊的理解

5.1 什么是字節對齊?

字節對齊主要是針對結構體而言的,通常編譯器會自動對其成員變量進行對齊,以提高數據存取的效率

5.2 字節對齊的兩種方式

默認對齊方式、指定對齊方式;

(1)默認對齊方式內存分配滿足以下三個條件:

  • 結構體第一個成員的地址和結構體的首地址相同;

  • 結構體每個成員地址相對于結構體首地址的偏移量(offset)是該成員大小的整數倍,如果不是則編譯器會在成員之間添加填充字節;

  • 結構體總的大小要是其成員中最大size的整數倍,如果不是編譯器會在其末尾添加填充字節。

如char是1字節,short是2字節,int是4字節...

(2)指定對齊方式使用以下方式聲明:

//注:通過#pragma pack(n)改變C編譯器的字節對齊方式
#pragma pack(4)         //安裝4字節的對齊方式

指定對齊方式內存分配滿足以下幾個條件:

  • 結構體第一個成員的地址和結構體的首地址相同

  • 結構體每個成員的地址偏移需要滿足:N大于等于該成員的大小,那么該成員的地址偏移需滿足默認對齊方式(地址偏移是其成員大小的整數倍);N小于該成員的大小,那么該成員的地址偏移是N的整數倍。

  • 結構體總的大小需要時N的整數倍,如果不是需要在結構體的末尾進行填充。

  • 如果N大于結構體成員中最大成員的大小,則N不起作用,仍然按照默認方式對齊。

注:在使用#pragma pack設定對齊方式一定要是2的整數冪,也就是(1,2,4,8,16,…),不然不起作用的,仍然按照默認方式對齊。

例1:結構體使用字節對齊為1


// date:2022年 11月 08日 星期二 19:35:36 CST
// author: HeiBaiYe
// path: /mnt/hgfs/CD2206/02-c語言
#include <stdio.h>#pragma pack(1)     //通過#pragma pack(n)改變C編譯器的字節對齊方式 在C語言中,結構是一種復合數據類型
struct s1{char ch;    // 1int a;      //4double b;   //8char c1;    //1
};#pragma pack(1) 
struct s2{char ch;    //1int a;      //4double b;   //8
};int main()
{printf("s1的大小:%ld\n ",sizeof(struct s1));printf("s2的大小:%ld\n ",sizeof(struct s2));return 0;
}
結果:
s1的大小:14
s2的大小:13

例2:結構體使用默認字節對齊方式,m值

// date:2022年 11月 08日 星期二 19:35:36 CST
// author: HeiBaiYe
// path: /mnt/hgfs/CD2206/02-c語言
#include <stdio.h>
struct s1{char ch;    // 1int a;        //4double b;    //8char c1;    //1
};struct s2{char ch;    //1int a;        //4double b;    //8
};int main()
{printf("s1的大小:%ld\n ",sizeof(struct s1));printf("s2的大小:%ld\n ",sizeof(struct s2));return 0;
}
結果:
s1的大小:24
s1的大小:16

參考鏈接:https://blog.csdn.net/wdl20170204/article/details/109386825

6、局部變量和全局變量可以重名嗎?

(1)能,局部變量會屏蔽全局變量。C++中要用全局變量,需要使用 "::"(域解析符) C語言中局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。

(2)對于有些編譯器而言,在同一個函數內可以定義多個同名的局部變量,比如在兩個循環體內都定義一個同名的局部變量,而那個局部變量的作用域就在那個循環體內。

7、UNIX系統中fsync函數的作用?

fsync()負責將參數fd 所指的文件數據, 由系統緩沖區寫回磁盤, 以確保數據同步。

頭文件:#include

定義函數:int fsync(int fd);

函數說明:fsync()負責將參數fd 所指的文件數據, 由系統緩沖區寫回磁盤, 以確保數據同步.

返回值:成功則返回0, 失敗返回-1, errno 為錯誤代碼。

參考鏈接:https://blog.csdn.net/Michaelwubo/article/details/41210547

8、const關鍵字使用有哪些?

8.1 修飾變量

const的 常規用法,在變量初次定義時賦初,并用關鍵字const修飾,使變量只可訪問,不能重新賦值修改變量。

8.2 修飾指針

(1)限制指針變量修飾:指針變量指向的位置不能被修改。定義時,被 const 修飾的指針變量指針只能在定義時初始化,不能定義之后重新指向新的數據。

(2)限制指針變量指向的數據修飾【指針的解引用】:修飾的指針變量指向的變量的值不能被修改,但是該指針可以指向其它空間。

(3)同時限制指針變量和指針變量指向的變量的值修飾:指針變量指向的位置不能被修改,并且指針變量指向變量的值也不能被修改。

(4)修飾函數形參【指針】:函數形參可以利用const關鍵字進行限制,來防止在函數內部修改指針指向的數據。

9、內存布局中有哪些段?

文本段(.text)、數據段(.data)、.bss段、堆(heap)、棧(stack)

圖 虛擬空間的各個部分

10、volatile關鍵字的作用?

(1)裸機編程時,某變量是指向寄存器中某一特定地址,添加volatile的變量不進行優化處理;

(2)某函數與中斷函數共享全局變量時,加上volatile,讓編譯器不要省略該變量的訪問;

(3)多線程中修飾共享全局變量,讓編譯器不要省略該變量的訪問。

11、sizeof()與strlen()的區別?

(1)sizeof是運算符,計算能容納實現所建立的最大對象的字節大小,參數可以是數組、指針、類型、對象、函數等;

(2)strlen是函數,功能是返回字符串的長度,參數必須是字符型指針(char*)。

12、內存泄漏和內存溢出是什么?

(1)內存溢出:指程序申請內存時,沒有足夠的內存供申請者使用。或者說,給了你一塊存儲int類型數據的存儲空間,但是你卻存儲long類型的數據,那么結果就是內存不夠用,此時就會報錯Out Of Memory,即所謂的內存溢出。

(2)內存泄漏:是指程序在申請內存后,無法釋放已申請的內存空間。一次內存泄漏似乎不會有大的影響,但內存泄漏堆積后的后果就是內存溢出。

13、定義一個指針賦值字符串與定義一個數組賦值字符串有什么區別?

(1)指針賦值字符串是指向一定內存的指針,只不過是指向字符串常量的指針,指針中的數據不能修改。

(2)數組賦值字符串是一片char型的數組,可以理解為緩沖區,只不過是賦值為了字符串。

14、malloc()與calloc分配空間有什么不一樣?

(1)malloc申請后空間的值是隨機的,并沒有進行初始化;calloc卻在申請后,對空間逐一進行初始化,并設置值為0

(2)malloc要申請的空間大小,需要我們手動的去計算;calloc并不需要人為的計算空間的大小。

15、實現循環的方式?

while、for 、do while 、goto 循環。

16、全局變量和局部變量在內存中有什么不同?

(1)全局變量保存在內存的全局存儲區中,占用靜態的存儲單元

(2)局部變量保存在中,只有在所在函數被調用時才動態地為變量分配存儲單元。

17、預處理的作用是什么?

預處理器可以刪除注釋、包含其他文件以及執行宏(宏macro是一段重復文字的簡短描寫)替代。

18、編譯器的作用?

編譯器就是將一種語言(通常為高級語言)翻譯為另一種語言(通常為低級語言)的程序。一個現代編譯器的主要工作流程:源代碼(.c)→ 預處理器(.i) → 編譯器 (.s)→ 目標代碼 (.o)→ 鏈接器 → 可執行程序 。

19、.ELF文件是什么?

.ELF是C語言在linux中的可執行文件。

20、C語言程序編譯的流程是什么?

圖 編譯過程

(1)預處理:根據以字符#開頭的命令修給原始的C程序,結果得到另一個C程序,通常以.i作為文件擴展名。主要是進行文本替換、宏展開、刪除注釋這類簡單工作。

對應的命令:linux> gcc -E hello.c hello.i

(2)編譯:編譯器將文本文件hello.i翻譯成hello.s,包含相應的匯編語言程序。

對應的命令:linux> gcc -S hello.c hello.s

(3)匯編:將.s文件翻譯成機器語言指令,把這些指令打包成一種叫做可重定位目標程序的格式,并將結果保存在目標文件.o中(把匯編語言翻譯成機器語言的過程)。

把一個源程序翻譯成目標程序的工作過程分為五個階段:詞法分析;語法分析;語義檢查和中間代碼生成;代碼優化;目標代碼生成。主要是進行詞法分析和語法分析,又稱為源程序分析,分析過程中發現有語法錯誤,給出提示信息。

對應的命令:linux> gcc -c hello.c hello.o

(4)鏈接:將靜態庫和動態庫的庫函數連接到可執行程序中。靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為.a。動態庫與之相反,在編譯鏈接時并沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般后綴名為.so,gcc在編譯時默認使用動態庫。

原文鏈接:https://blog.csdn.net/daide2012/article/details/73065204

21、如何用C語言實現C++的類?

(1)由于C語言是面向過程,而C++是面向對象,所以在定義數據時,可以用C的結構體成員充當C++類的成員定義;

(2)由于結構體只能定義變量,不能夠定義函數,所以通過函數指針的方法來實現其類函數的定義。

參考鏈接:https://blog.csdn.net/forever__1234/article/details/61429870

結語

C語言是嵌入式的基礎,像我總結的這些面試題,都是去年我去面試好幾家公司所遇到的常見面試題。因此,在面試找工作的那段時間,歸納總結常遇到過的面試題,并將不會的知識點進行檢索歸納,是很必要的。這樣做的話,可以提升自己的知識面,面試時,就能從容面對不同面試官各種不同的問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/165381.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/165381.shtml
英文地址,請注明出處:http://en.pswp.cn/news/165381.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++之初始化列表詳細剖析

一、初始化列表定義 初始化列表&#xff1a;以一個冒號開始&#xff0c;接著是一個以逗號分隔的數據成員列表&#xff0c;每個"成員變量"后面跟一個放在括號中的初始值或表達式。 class Date { public:Date(int year, int month, int day): _year(year), _month(mont…

OpenCV快速入門:圖像分析——圖像分割和圖像修復

文章目錄 前言一、圖像分割1.1 漫水填充法1.1.1 漫水填充法原理1.1.2 漫水填充法實現步驟1.1.3 代碼實現 1.2 分水嶺法1.2.1 分水嶺法原理1.2.2 分水嶺法實現步驟1.2.3 代碼實現 1.3 GrabCut法1.3.1 GrabCut法原理1.3.2 GrabCut法實現步驟1.3.3 代碼實現 1.4 Mean-Shift法1.4.1…

論文閱讀 (106):Decoupling maxlogit for out-of-distribution detection (2023 CVPR)

文章目錄 1 概述1.1 要點1.2 代碼1.3 引用 2 預備知識3 方法3.1 MaxLogit3.2 改進MaxCosine和MaxNorm3.3 DML 1 概述 1.1 要點 題目&#xff1a;解耦最大logit分布外檢測 (Decoupling maxlogit for out-of-distribution detection) 方法&#xff1a; 提出了一種心機基于log…

多級緩存快速上手

哈嘍~大家好&#xff0c;這篇來看看多級緩存。 &#x1f947;個人主頁&#xff1a;個人主頁????? &#x1f948; 系列專欄&#xff1a;【微服務】 &#x1f949;與這篇相關的文章&#xff1a; JAVA進程和線程JAVA進程和線程-CSDN博客Http…

不做機器視覺工程師,轉行,轉崗的建議與想法

正所謂外行看熱鬧&#xff0c;內行看門道。提前咨詢前輩們&#xff0c;多問問&#xff0c;多看看。要做就做&#xff0c;一定要提前做好防范。 無論你是要轉行或者是轉崗&#xff0c;看你有沒有本錢和試錯成本 有些人&#xff0c;家庭好&#xff0c;可以一直去試錯和從頭再來。…

無線WiFi安全滲透與攻防(國外篇):使用 Aircrack-ng 破解 WEP 密碼

使用 Aircrack-ng 破解 WEP 密碼 使用 Aircrack-ng 破解 WEP 密碼一. 用 Aircrack-ng 破解 WEP 密碼 - 背景知識網卡與網卡芯片WEP 加密協議WEP 所使用的身份認證協議二. 使用 Aircrack-ng 破解 WEP 密碼 - 破解原理破解機理三. 使用 Aircrack-ng 破解 WEP 密碼 - aircrack-ng …

學習.NET驗證模塊FluentValidation的基本用法(續1:其它常見用法)

FluentValidation模塊支持鏈式驗證方法調用&#xff0c;也就是說&#xff0c;除了 RuleFor(r > r.UserName).NotEmpty()調用方式之外&#xff0c;還可以將對單個屬性的多種驗證函數以鏈式調用方式串接起來&#xff0c;比如UserName屬性不能為空&#xff0c;長度在5~10之間&a…

__attribute__((constructor))用法解析

__attribute__((constructor))是GCC和兼容的編譯器中的一個特性&#xff0c;用于指示編譯器將一個函數標記為在程序啟動時自動執行的初始化函數。 同樣的還有__attribute__((destructor))在main()函數后調用。 當你在一個函數聲明或定義前加上__attribute__((constructor))屬…

淺談 Guava 中的 ImmutableMap.of 方法的坑

作者&#xff1a;明明如月學長&#xff0c; CSDN 博客專家&#xff0c;大廠高級 Java 工程師&#xff0c;《性能優化方法論》作者、《解鎖大廠思維&#xff1a;剖析《阿里巴巴Java開發手冊》》、《再學經典&#xff1a;《EffectiveJava》獨家解析》專欄作者。 熱門文章推薦&…

vue項目下.env.development環境變量配置文件

.env.development 文件是一個用于開發環境配置的文件。在許多應用程序中&#xff0c;開發環境和生產環境具有不同的配置需求。.env.development 文件允許你在開發環境中定義特定的環境變量和配置選項。 一般來說&#xff0c;.env.development 文件用于存儲開發環境相關的配置信…

國自然項目基金撰寫的隱藏技巧、范例分析及提交前的自我審查

目錄 一、基金項目申請要求、重點及項目介紹 二、基金的撰寫技巧 三、基金撰寫的隱藏技巧 四、范例分析及提交前的自我審查 更多應用 基金項目申請需要進行跨學科的技術融合&#xff0c;申請人需要與不同領域結合&#xff0c;形成多學科交叉的研究。基金項目申請在新時期更…

由紅黑樹引出的HashMap擴容機制的思考

紅黑樹是什么&#xff1f; 三大特點&#xff1a; 根節點是黑色&#xff0c;葉節點是不存儲數據的黑色空節點 任何相鄰的兩個節點不能同時為紅色 任意節點到其可到達的節點間包含相同數量的黑色節點 聯想&#xff1a;Java HashMap底層紅黑樹原理 HashMap基于哈希表Map接口實…

快速掌握Pyqt5的三種主窗口

PyQt5是一個強大的跨平臺GUI框架&#xff0c;它提供了多種不同類型的主窗口類&#xff0c;以滿足不同的應用需求。下面是PyQt5中最常見的幾種主窗口類型及其創建方式的簡介&#xff1a; 1. QMainWindow QMainWindow是用于創建具有菜單欄、工具欄、狀態欄和中心窗口部件&#…

內存池 示例一

內存池是一種管理內存分配和釋放的技術&#xff0c;用于優化內存的使用效率。它通過預先分配一塊內存區域&#xff0c;并將其劃分為多個較小的塊&#xff08;內存塊池&#xff09;&#xff0c;然后按需分配這些內存塊來減少內存碎片化和頻繁的系統調用。這些內存塊可以是相同大…

Centos7.9配置nfs共享及rsync同步

客戶需求對oracle數據庫做一個跨機房的備份&#xff0c;原環境已做rman備份和每天expdp全庫導出&#xff0c;遠端只有虛擬化環境&#xff0c;可提供一個虛擬機&#xff0c;2個機房間網絡互通。 首先配置nfs服務端 查看操作系統版本 [rootnas199 ~]# more /etc/redhat-relea…

Python面經【1】

一、協程的相關概念 協程&#xff08;又稱微線程&#xff09;運行在線程之上&#xff0c;更加輕量級&#xff0c;協程并沒有增加線程總數&#xff0c;只是在線程的基礎上通過分時復用的方式運行多個協程&#xff0c;大大提高工程效率。 協程的特點&#xff1a; 輕量級&#…

WordPress站點屏蔽過濾垃圾評論教程(Akismet反垃圾評論插件)

前段時間我的WordPress站點經常收到垃圾評論的轟炸&#xff0c;嚴重時一天會收到幾十條垃圾評論。我這個小破站一沒啥流量&#xff0c;二又不盈利&#xff0c;實在是不太理解為啥有人要這么執著地浪費資源在上面。 Akismet反垃圾評論插件 其實用了 Akismet 反垃圾評論插件后&a…

快速掌握Pyqt5的6種按鈕

在PyQt5中&#xff0c;按鈕是構建用戶界面的基本元素之一&#xff0c;用于執行命令、啟動功能或觸發事件。PyQt5提供了多種類型的按鈕&#xff0c;每種都適用于不同的場景和需求。 1. QPushButton QPushButton 是最常用的按鈕類型&#xff0c;適用于大多數情況&#xff0c;如…

ARCore:在Android上構建令人驚嘆的增強現實體驗

ARCore&#xff1a;在Android上構建令人驚嘆的增強現實體驗 一、 AR 介紹1.1 AR技術簡介1.2 AR技術原理1.3 AR技術應用領域 二、Google的增強現實平臺ARCore2.1 ARCore簡介2.2 ARCore API介紹2.3 ARCore API使用示例 三、總結 一、 AR 介紹 增強現實 Augmented Reality&#x…

【算法-字符串2】替換空格 + 反轉單詞

今天&#xff0c;帶來字符串相關算法的講解。文中不足錯漏之處望請斧正&#xff01; 理論基礎點這里 1. 替換空格 題目描述&#xff1a;請實現一個函數&#xff0c;把字符串 s 中的每個空格替換成"%20"。 來源&#xff1a;力扣&#xff08;LeetCode&#xff09; 難…