首页
题库
公司真题
专项练习
面试题库
在线编程
面试
面试经验
AI 模拟面试
简历
求职
学习
基础学习课
实战项目课
求职辅导课
专栏&文章
竞赛
搜索
我要招人
发布职位
发布职位、邀约牛人
更多企业解决方案
在线笔面试、雇主品牌宣传
登录
/
注册
2024校招加油
门头沟学院 嵌入式工程师
发布于广东
关注
已关注
取消关注
太细了,强
@小羽的嵌入式校招指南:
嵌入式校招_面试经验大全【C语言】【2_关键字】
【以下内容,后续会不断更新补充!】各位同学有想看某一个知识点详细解析的,也可以在评论区留言~目录【专栏一】嵌入式校招指南作者机械硕士,从零开始自学嵌入式软件,21届秋招进入国内芯片大厂。 从自身转行经历来看,网上嵌入式学习路线的资料少之又少,大多千篇一律且复制粘贴。 而嵌入式入行门槛高,技能树要求多,学习难度非常大,没有有效的方法指导,很容易迷失方向,错过校招。 在此专栏分享我的校招从零开始转行经验,听我给你娓娓道来~专栏链接 https://www.nowcoder.com/creation/manager/columnDetail/MWZkkj1.专栏大纲&写在前面2.转行概述3.前期准备4.自学教材推荐_基础知识5.自学教材推荐_笔试准备6.开发板&项目7.简历8.行业&公司9.城市&岗位10.消费&工业电子类公司未完待续……【专栏二】嵌入式校招_面试经验大全嵌入式软件校招的常见问题,应付校招面试的速效救心丸,你值得拥有! 嵌入式的知识太多太杂,不知道面试经常问哪些? 书上说的知识点太抽象,没有一定的基础很难理解? 别怕,本专栏用通俗的语言和比喻,为你讲清楚! 包含C语言、计算机组成原理、操作系统、数据结构与算法及计算机网络等,详见大纲。1.【C语言】【1_变量】https://www.nowcoder.com/discuss/4917738635256791042.【C语言】【2_关键字】https://www.nowcoder.com/discuss/4975623096282767363.【C语言】【3_数据结构&位运算】https://www.nowcoder.com/discuss/505894349847224320二、关键字【问】介绍一下static关键字的作用【答】static可以修饰全局变量、局部变量和函数。分别有以下作用:全局变量:使全局变量对外部文件不可见。(隐藏)局部变量:使局部变量存储在全局静态区,只初始化一次,函数结束后可一直存在,可在函数内修改。(更改存储区域&延长生命周期)修饰函数,表明函数的作用范围,仅当前.c文件内可被调用,对外不可见。(隐藏)【解析】全局变量全局变量本身就存在于全局静态区,static关键字的作用是隐藏,更改全局变量的作用域。为什么要隐藏呢?有的是考虑到重名的因素,但我个人认为还有一点是比较重要的,那就是处于安全的考虑。比如有一个c文件名为Trusty.c,里面定义了各种对于用户密码的操作,由一个名为安全小组的团队维护。那么我们知道,用户密码肯定是存放在一个全局变量PassWord中,方便各个函数调用操作。PassWord在这个Trusty.c可以随意被调用,因为是由安全小组内部维护的,可以保证安全性。但是,如果另外模块得知了PassWord这个变量名,就可以随意调用。那么缺乏保护措施的另一个模块,很容易泄漏PassWord的内容,导致最重要的密码被窃取!这是绝对绝对不可以的!此时就可以在Trusty.c中定义一个静态全局变量来对外部隐藏PassWord变量啦。static char PassWord[10] = "XiaoYu666";局部变量static修改局部变量主要是延长生命周期。我们都知道,局部变量原本就有隐藏作用,仅对当前函数可见。同时局部变量原本是存放在内存中的栈区,每次进入函数时创建,退出函数时销毁。使用static修改局部变量后,将局部变量从栈区移至全局静态区,其生命周期为一直存在。所以是更改存储区域导致的生命周期延长。那么,问题来了。为什么要这么做呢?举个栗子: 有一个局部变量LocalVar仅被某一个函数RepeatFunc调用。该函数会重复执行很多次,每次都会基于上次的结果,对LocalVar做修改,且保留LocalVar的值到下一次RepeatFunc执行。一种简单粗暴的方法是直接将LocalVar定义为全局变量。但是这样做有两个隐患,一个是其他函数有可能调用并修改LocalVar从而导致运行结果出错;第二个是造成全局变量泛滥,对于大型代码工程来说是不可接受的。因此,static修改的局部变量派上用场了。可以同时具有局部变量的隐藏特性,还具有长久的生命周期来保留上次的结果。真棒呀~~函数我们首先要知道,编程规范中,建议每一个函数只负责执行一个动作,不要一个函数完成多个动作。这叫做低耦合。那么,同修饰全局变量中的例子,用户设置、更改和读取密码的过程中,会使用一系列中间函数来完成一个大的功能如加密&解密,同时返回一些关键信息。如果此时外部模块调用这部分中间函数,非法获取它的返回值,就会造成关键信息泄漏。这个是不被允许的!因此我们可以使用static关键字来修饰中间函数,从而对外隐藏它们。只留给外部模块固定的API接口函数(设置、更改和读取密码),这样就能从代码编写层面来保护啦~————————————————————【问】介绍一下const关键字的作用【答】防止变量被意外地修改。const修饰的变量,只能在初始化时赋初值,其后不能通过该变量来修改。【解析】 常量指针与指针常量1)常量指针。指向常量的指针。const在*的左边。指针指向的变量是常量,不可通过指针改变(可通过原始变量来更改)。 举个栗子:#include <stdio.h>int main(void){ int Value = 2023; const int *ConstPtr = &Value; printf("%d\n",*ConstPtr); *ConstPtr = 2024;}通过上面的例子,我们验证了指针指向的变量是常量,不可通过指针改变的特性。下面来看隐含的另一个意思,即可通过原始变量来更改。#include <stdio.h>int main(void){ int Value = 2023; const int *ConstPtr = &Value; printf("%d\n",*ConstPtr); //*Num1 = 2024; Value = 2024; printf("%d\n",*ConstPtr);}通过上面的例子我们可以知道,虽然我们不能通过ConstPtr这个常量指针来更改Value的值,但是我们可以通过Value这个原始的变量来更改~因为Value本身并不是const类型的~2)指针常量。指针类型的常量。const在*的右边。而指针变量的值是地址,即该指针的指向不可变,不能再指向其他地址。但是指针指向的变量的数值可以改变。#include <stdio.h>int main(void){ int Value = 2023; int TmpValue = 2024; int *TmpPtr = &Value; int *const PtrConst = &Value; printf("%p\n",PtrConst); PtrConst = &TmpValue; printf("%p\n",PtrConst);}3)羽你俗说int Value = 2023;const int *ConstPtr = &Value; //常量指针int *const PtrConst = &Value; //指针常量 怎么区分这两个呢?我们首先明确一个指针的基本概念:Ptr是一个指针变量,所保存的值是一个地址。加上取值符号*后,*Ptr表示的是该地址保存的值。那么为了方便记忆,我们将上述两种指针定义中的int暂时忽略。即:const *ConstPtr = &Value; //常量指针*const PtrConst = &Value; //指针常量现在我们来看const修饰的右边是个什么东西。常量指针中,const修饰的是*ConstPtr。上面我们说过这个*ConstPtr表示一个值,那么const修饰的就是这个值。也就是说这个值不能被修改。指针常量中,const修饰的是PtrConst。上面我们说过指针的值是地址,那么const修饰的是该地址,也就是这个地址不能被修改。这样是不是容易理解和记忆多了呢~~~————————————————————【问】介绍一下volatile关键字的作用【答】volatile关键字告知编译器,所修饰的变量随时有可能被改变,因此程序每次需要存储或读取这个变量时,都直接从变量所在的内存地址中读取数据。【解析】定义volatile是一种类型修饰符,表明该变量可能会被意想不到地改变(操作系统、硬件或者其它线程等),防止编译器对代码进行优化功能1.使编译器每次使用变量时不从寄存器中读取,而是从内存中重新获取2.防止编译器调整操作volatile变量的指令顺序(无法避免CPU动态调度)背景知识1.通常情况下,为了提高运行速度和优化代码量,编译器可能优化读取和存储相关的代码。2.程序运行中读取某一变量时,为提高存取速度,编译器优化时会先把变量读取到一个寄存器中,后续直接从该寄存器中取值(而非从内存中重新读取)。应用场景嵌入式系统程序员经常同硬件、中断、RTOS等打交道,这些都通常要求使用volatile变量。1)硬件相关的寄存器(如:状态寄存器) 我们都知道,嵌入式软件之所以特别,就是因为要和硬件打交道。现在有一个反映硬件状态的变量,由于外部因素改变了硬件状态从而修改了该变量的值。那么此时该变量在内存中的数值和其在寄存器中的数值是不一致的。如果此时CPU需要读取该值,很可能因为编译器的优化而直接读取寄存器中的值,导致读取到的是"旧值"。2)中断服务程序中可能会修改的变量当变量在中断服务程序(ISR)中被修改后,而编译器判断主函数里面没有修改该变量,因此可能只会从该寄存器中读取变量的"旧值"。3)多线程间共享的变量当某一线程读取一个变量时,编译器优化时会先把该变量读取到寄存器中;后面再取变量值时,就直接从寄存器中取值;当另外的线程改变了该值后,该寄存器的值不会相应改变。如果此时CPU需要读取该值,很可能读取到"旧值"。羽你俗说通俗地说,小明(CPU)把自己的个人资料(变量)记录在一张纸上(寄存器)。我们知道,姓名、性别、出生年月这些基本不会改变的属性(非volatile变量),一次记录(从内存copy到寄存器)后每次都可以重复使用。然而身高、体重等随时可能改变的数据(volatile变量),每次必须要现场测量(从内存地址读取)才可以,不然只会得到之前的"旧值"。常见问题1.一个参数既可以是const还可以是volatile吗?可以。用const和volatile同时修饰变量,表示这个变量在软件程序中是只读的,但是可以程序外部条件(硬件)变化下改变。每次使用这个变量时,都要小心地去内存读取这个变量的值,而不是去寄存器读取它的备份。注意:const只是不允许程序代码改变某一变量,其在编译期发挥作用,它并没有实际地禁止某段内存的读写特性。2.一个指针可以是volatile 吗?可以。表示该指针变量容易改变其所指向对象,比如一个指向当前堆栈栈顶的指针,就会随着堆栈的增长改变指向的对象。————————————————————【问】介绍一下extern关键字的作用【答】修饰变量或函数,在当前文件引用另一个文件中定义的变量或者函数。【解析】定义与声明 在这里我们要首先介绍一个概念,就是定义与声明。 函数定义:包含一个函数的所有,包括函数名、返回值、传入参数、函数体(函数功能的具体实现代码)等。 函数声明。也称之为函数原型。将函数名、返回值、传入参数通知编译器,暂不报错,函数定义在后面的代码中。C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错。但在实际开发中,有时调用的函数(Func)在定义当前函数(main)后面时,则需在当前函数前添加函数声明,见下图。若不添加函数声明,则会出现编译与链接 这部分涉及到代码的编译与链接,这里简单介绍一下,具体的看后续专门的文章。 首先我们要知道,CPU在执行代码时,遇到函数Func的时候,不是把Func的代码复制过来运行的。而是跳转到Func代码的存放地址去执行,执行完以后再回到之前函数的代码地址(上下文)。 那么编译器在编译C代码时,遇到调用全局变量和函数的地方,就会用全局变量和函数的地址来代替,从而生成最后的可执行文件。怎么找到全局变量和函数的地址呢?在本文件中查找他们定义的位置即可获取地址。 问题来了,如果全局变量和函数,不是在本文件定义的,但我又想要用到他们怎么办呢? 直接调用是肯定不行滴,会报错的~ 这个时候就要用到extern关键字啦!在调用他们的函数前面声明时,添加extern关键字告知编译器去其他文件中找~当然,他们可不能被static修饰哦~原因见static关键字介绍————————————————————【问】介绍一下typedef关键字的作用【答】使用 typedef 关键字为复杂的数据类型另外定义一个简单的别名。可定义的类型为基本数据类型和自定义数据类型。【解析】功能 1.重定义一个易记且意义明确的新类型名。 查看标准库文件stdint.h,里面定义了很多这样的类型。 这样我们就不必再去思考short究竟是多少位的类型,直接使用int16_t,清晰明了~ 2.简化一些比较复杂的类型声明 在使用某些自定义的数据结构时,常使用typedef来简化声明。 比如结构体PersonData,如果我们要定义一个这样的指向该结构体的指针,需要struct PersonalData *MyDataPtr; 而使用typedef后只需要DataPtr MyDataPtr即可。typedef和define的区别原理不同:#define是预处理指令,预处理阶段;typedef是关键字,在编译阶段功能不同:#define是替换,typedef是别名连续定义变量时,typedef保证所有变量均为同一类型,而#define无法保证————————————————————更多内容,持续更新中!!!【觉得有用的小伙伴们可以订阅一下专栏,后续还有更多文章哦~ 😀 】作者其他专栏【嵌入式校招指南_完整学习路线】https://www.nowcoder.com/creation/manager/columnDetail/MWZkkj请帮忙点赞、评论+收藏,是对我最大的支持~感谢!!!
点赞 45
评论 5
全部评论
推荐
最新
楼层
还没有回复哦~
相关推荐
11-26 17:09
华南理工大学 后端
offer选择 华为 蚂蚁 pdd
蚂蚁
基架java
(n+6)*16 签字费若干
点赞
评论
收藏
分享
昨天 21:20
门头沟学院 C++
大家怎么看待计算机的各个方向
1.传统后端:各种主流语言,如java方向,Cpp方向(很少),以及流行趋势的语言如Go,python2.Cpp方向:Cpp的每个方向就像生殖隔离一样,什么嵌入式,游戏开发,服务器开发,客户端开发,量化之类的种种3.Java方向:java后端,服务器之类的4.测开:版本答案?这个方向如何呢5.前端:也是版本答案?6.客户端:牛客上出现了客户端劝退群体7.传统测试:这个不好说8.数据库相关工作9.运维/技术支持/技术服务......
投递牛客等公司10个岗位 >
生活随笔记录
如果再来一次,你还会选择这个工作吗?
点赞
评论
收藏
分享
11-14 15:03
西安电子科技大学 C++
关于荣耀分组
只能说。。。只要不是安卓就行,松了口气
一名愚蠢的人类:
多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞
评论
收藏
分享
11-12 12:04
美团_核心本地商业—到店_测试开发(实习员工)
被美团hr制裁了 唉
26太不容易了
冲芭芭拉鸭:
你这图还挺新,偷了。
投递美团等公司10个岗位
点赞
评论
收藏
分享
昨天 17:48
中山大学 C++
想回重庆找工作就这么难吗
bg双9,约面的一只手可数,目前重庆offer0,cnmlgbd,我做错了什么
若梦难了:
赛力斯不是点击就送吗?给我开了ssp我没去,方向太辣了
找工作中的意难平
点赞
评论
收藏
分享
评论
点赞成功,聊一聊 >
点赞
收藏
分享
评论
提到的真题
返回内容
全站热榜
1
...
到了新公司,不要用力过猛
1.7W
2
...
万字长文讲透金融科技方向的就业机会
8500
3
...
校招两方/三方违约模板
8223
4
...
泡出来啦
8058
5
...
华为开奖,详细时间线
6849
6
...
华为开奖?
6700
7
...
秋招圆满结束!!
6201
8
...
从露宿街头到百万级种子轮融资②——我的实习期都经历了什么
6101
9
...
我也是好起来了,都能收到offer了
5747
10
...
听学长的没错
5688
正在热议
#
25届秋招总结
#
387108次浏览
3853人参与
#
硬件兄弟们 甩出你的华为奖状
#
76993次浏览
623人参与
#
阿里云管培生offer
#
55648次浏览
1706人参与
#
地方国企笔面经互助
#
6283次浏览
14人参与
#
实习,投递多份简历没人回复怎么办
#
2431998次浏览
34677人参与
#
发工资后,你做的第一件事是什么
#
5682次浏览
24人参与
#
北方华创开奖
#
65303次浏览
542人参与
#
ai智能作图
#
16461次浏览
221人参与
#
实习与准备秋招该如何平衡
#
721199次浏览
8538人参与
#
我的实习求职记录
#
6112755次浏览
83886人参与
#
哪些公司校招卡第一学历
#
31896次浏览
93人参与
#
如果再来一次,你还会选择这个工作吗?
#
106028次浏览
1066人参与
#
工作中,你有没有遇到非常爱骂人的领导?
#
4531次浏览
46人参与
#
在职场上,你最讨厌什么样的同事
#
5382次浏览
77人参与
#
如果你有一天可以担任公司的CEO,你会做哪三件事?
#
9426次浏览
194人参与
#
牛客租房专区
#
4232次浏览
118人参与
#
如果有时光机,你最想去到哪个年纪?
#
27294次浏览
566人参与
#
华为工作体验
#
109738次浏览
853人参与
#
中兴求职进展汇总
#
467300次浏览
2435人参与
#
还记得你第一次面试吗?
#
30840次浏览
435人参与
#
秋招你被哪家公司挂了?
#
344453次浏览
3290人参与
#
许愿池
#
216947次浏览
2544人参与
牛客网
牛客企业服务