1 Star 0 Fork 139

玛卡巴卡 / 嵌入式软件笔试题汇总

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
103-C语言选择填空问答 15.60 KB
一键复制 编辑 原始数据 按行查看 历史
zhangjing 提交于 2020-03-15 19:46 . [Modify]修改文件
====
38、算术运算符,赋值运算符和关系运算符的运算优先级按从高到低依次为
  A.算术运算、赋值运算、关系运算
  B.算术运算、关系运算、赋值运算
  C.关系运算、赋值运算、算术运算
  D.关系运算、算术运算、赋值运算
参考答案:B
权重:较高
备注:这个没办法,可以把C语言操作符优先级记住
====
7:定义函数时,缺省函数的类型声明,则函数类型取缺省类型
A.void
B.char
C.float
D.int
参考答案:D
备注:较低,实际工作中需要显式说明函数类型
====
8:若main()函数带参数,参数个数最多是
A.0
B.1
C.2
D.3
参考答案:C 只知道有定义形式main(int argc,char* argv[]))
权重:中
====
20:C 语言中运算对象必须是整型的运算符是
A.%
B./
C.!
D.**
参考答案:A
权重:中
====
华为
1、局部变量能否和全局变量重名?
答:能,局部会屏蔽全局。要用全局变量,需要使用"::"
局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。
权重:较低
====
2、如何引用一个已经定义过的全局变量?
答:extern
可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
权重:较高
====
3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?
答:可以,在不同的C文件中以static形式来声明同名全局变量。
可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时链接不会出错。
权重:中
====
4、语句for( ;1 ;)有什么问题?它是什么意思?
答:无限循环,和while(1)相同。问题是别的人可能会以为你只是漏写什么了,不推荐这么做。
权重:中
====
5、do……while和while……do有什么区别?
答:前一个循环一遍再判断,后一个判断以后再循环。
权重:中
备注:要掌握do...while在宏定义函数的用法
#define func(x) do { \
do something \
} while (0)
====
1、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
答:全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。
static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件
static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;
static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;
static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝
权重:高
备注:掌握全局静态变量、函数内静态变量、静态函数,实际中经常用
====
2、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。
权重:高
备注:编程时,在有需要的情况下,需要手动调整分区表配置,要理解代码的存储机制
====
41、对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
答:c用宏定义,c++用inline。
其实,c里面也可以用inline啊。
权重:较高
备注:宏定义函数每行句末都必须加上反斜杠
#define func(x) do { \
return (x)*(x); \
} while(0);
inline int func(x)
{
return x * x;
}
====
intel:
1. A.c 和B.c两个c文件中使用了两个相同名字的static变量,编译的时候会不会有问题?这两个static变量会保存到哪里(栈还是堆或者其他的)?
答:static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在数据区,但是编译器对他们的命名是不同的。
权重:高
====
1. const的理解:const char*, char const*, char*const有什么区别?
答:常考的题目。事实上这个概念谁都有,只是三种声明方式非常相似很容易记混。Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:把一个声明从右向左读。
char * const cp; ( * 读成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;
char const * p;
同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。
权重:高
====
2. c指针,解释下面定义是什么意思?
int *p[n];—–指针数组,每个元素均为指向整型数据的指针。
int (*p)[n];——p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();———-函数带回指针,指针指向返回的值。
int (*p)();——p为指向函数的指针。
权重:高
====
5. ASSERT()是干什么用的
答:ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:
……
ASSERT( n != 0);
k = 10/ n;
……
ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。
assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。
权重:较高
====
9. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
答;全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。
全局变量在main函数调用后,就开始分配,
静态变量则是在main函数前就已经初始化了。
局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)
权重:中
====
13:全局变量与局部变量在内存中是否有区别,是什么区别?
全局变量存储在静态数据库,局部变量存储在堆栈;
权重:中
====
b) 在ARM系统中,函数调用的时候,参数是通过哪种方式传递的?
答:用寄存器R0传递第一个参数,R1传递到第二个,一直到R3传递第四个参数。但是实际上有时可能传递的参数非常多,超过8个,或是参数中有浮点数之类,参数也会超过4个寄存器,对于超出的部份并不使用R4,而是使用堆栈的方式。
权重:较低
备注:每个函数能使用的栈大小是有上限的,如512K,所以最好不要传大块的结构体,多使用指针。
====
c) 中断(interrupt,如键盘中断)与异常(exception,如除零异常)有何区别?
答:
中断:中断是指来自CPU执行指令以外的事件发生后,处理机暂停正在运行的程序,转去执行处理该事件的程序的过程。
异常:异常是指源自CPU执行指令内部的事件发生后,处理机暂停正在运行的程序,转去执行该事件的过程。
区别:广义的中断包括中断和异常,统一称为中断。狭义的中断和异常的区别在于是否与正在执行的指令有关,中断可以被屏蔽,异常不能被屏蔽,一旦出现应立即处理。
权重:较低
====
重入是什么?如何保证函数可以重入。
重入一般可以理解为一个函数在多线程下,同时被多次调用,前一个调用还没退出,下一个调用已经开始进行。例如操作系统在进程调度过程中,或者单片机、处理器等的中断的时候会发生重入的现象。
一般浮点运算都是由专门的硬件来完成,举个例子假设有个硬件寄存器名字叫做FLOAT,用来计算和存放浮点数的中间运算结果
假设有这么个函数
void fun()
{
//...这个函数对FLOAT寄存器进行操作
}
假如第一次执行,有个对浮点数操作运算的结果临时存在FLOAT寄存器中,而就在这时被中断了,而中断函数或者另一个进程也调用fun函数,这时第二次调用的fun函数在执行的过程中就会破坏第一次FLOAT寄存器中的结果,这样当返回到第一次fun函数的时候,结果就不正确了。
想要函数能够重入,不要在函数内部使用static静态变量,不要操作硬件寄存器。可重入代表可被中断。
问题1,如何编写可重入的函数?
答:在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用局部变量,写出的函数就将是可重入的。如果必须访问全局变量,记住利用互斥信号量来保护全局变量。
问题2,如何将一个不可重入的函数改写成可重入的函数?
答:把一个不可重入函数变成可重入的唯一方法是用可重入规则来重写它。其实很简单,只要遵守了几条很容易理解的规则,那么写出来的函数就是可重入的。
1) 不要使用全局变量。因为别的代码很可能覆盖这些变量值。
2) 在和硬件发生交互的时候,切记执行类似disinterrupt()之类的操作,就是关闭硬件中断。完成交互记得打开中断,在有些系列上,这叫做“进入/退出核心”。
3) 不能调用其它任何不可重入的函数。
4) 谨慎使用堆栈。最好先在使用前先OS_ENTER_KERNAL。
堆栈操作涉及内存分配,稍不留神就会造成益出导致覆盖其他任务的数据,所以,请谨慎使用堆栈!最好别用。
权重:中
备注:类似的思想体现在,在中断处理函数中不要操作浮点数,不要使用printf等IO函数,不操作全局变量,不使用同步、互斥、锁、信号量这些,不使用malloc、free。
====
9、若main()函数带参数,参数个数最多是
A.0
B.1
C.2
D.3
参考答案:C
权重:较高
备注:定义形式 main(int argc, char* argv[]))
调用程序二进制文件时可以在后面加参数控制不同行为
====
10、C 语言中运算对象必须是整型的运算符是
A.%
B./
C.!
D.**
参考答案:A
权重:中
====
37、对语句 if else 与操作符 ? : 使用场合的比较。
答: ?:简短,可以多层嵌套,增加代码可读性,也很适合宏定义函数中用,还有显示高逼格。
如() ? ( [] ? [] : []) : ( [] ? [] : [])这样的写法可以省略三次if else,但是不影响理解代码的含义。
权重:较高
备注:实际使用时经常使用?:
====
32、如何在两个.c文件中引用对方的变量。
这个问题也问的挺含糊的,怎么说呢,最简单最直接的方法是为变量添加extern修饰词,当然,这个变量必须是全局变量。(这种方式非常不提倡,会让程序结构非常乱)
还有一种就是初始化时注册回调函数,在b.c中调用a.c的注册函数,把自己变量的地址赋给a.c回调函数的指针中,实际工作中推荐这么用。
权重:低
备注:特别注意c语言中头文件不能相互包含,只能是线性包含,比如,所有的全局变量在a.c中定义,b.c包含a.h,不能a.c包含b.h,而b.c也包含a.h。
====
33、 如何让局部变量具有全局生命期。
也可以这样问,如何在函数退出后保留函数中局部变量的值,不过这个知识点嵌入式应该掌握。
具体的生命期的概念我觉得我还要好好深入的学习一下,但是这个题目还算比较简单,即用static修饰就可以了,但是只是生命期延长,范围并没有扩大,除非把这个变量定义在函数体外的静态区,不过那样就变成全局变量了,仿佛不符合题目要求。
权重:中
备注:需要掌握,嵌入式经常用。
====
31、使用malloc之前需要做什么准备工作。
首先要知道malloc的用途,简单的说就是动态的分配一段空间,返回这段空间的头指针。实际的准备工作可以这么分:需要这段空间的指针是否存在,若不存在,则定义一个指针用来被赋值,还要清楚要返回一个什么类型的指针,分配的空间是否合理;如果指针已经存在,那么在重新将新的空间头地址赋值给这个指针之前,要先判断指针是否为NULL,如果不是要free一下,否则原来的空间就会被浪费,或者出错,free之后就按照前一种情形考虑就可以了。
权重:较低
备注:嵌入式应该掌握malloc和free
====
2、 二维数组中的元素AA [ 3 ][ 7 ]的另外一种表示方法?
答:*(*(AA+3)+7;
权重:中
====
17、 如何初始化一个指针数组。
题目出的不好,题意不明确,而且方法有好几种。
首先明确一个概念,就是指向数组的指针,和存放指针的数组。
指向数组的指针:char (*array)[5];含义是一个指向存放5个字符的数组的指针。
存放指针的数组:char *array[5];含义是一个数组中存放了5个指向字符型数据的指针。
按照题意,我理解为初始化一个存放指针的数组,char *array[2]={"China","Beijing"};其含义是初始化了一个有两个指向字符型数据的指针的数组,这两个指针分别指向字符串"China"和"Beijing"。也可以用memset
权重:中
====
18、 如何在C中初始化一个字符数组。
题目模糊,出题人请给我解释系列
这个问题看似很简单,但是我们要将最简单的问题用最严谨的态度来对待。关键的地方:初始化、字符型、数组。最简单的方法是char array[];。这个问题看似解决了,但是在初始化上好像还欠缺点什么,个人认为:char array[5]={'1','2','3','4','5'};或者char array[5]={"12345"};或者char array[2][10]={"China","Beijing"};也许更符合“初始化”的意思。
权重:中
C
1
https://gitee.com/makabak/embedded_exercise_problems.git
git@gitee.com:makabak/embedded_exercise_problems.git
makabak
embedded_exercise_problems
嵌入式软件笔试题汇总
master

搜索帮助