加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

嵌入式开发工程师面试题1

2小时前
212
阅读需 11 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1.若有以下定义语句double a[8],*p=a;int i=5;对数组元素错误的引用是?

A *a

B a[5]

C *(p+1)

D p[8]

在 C 或 C++ 语言中,对于数组和指针的操作需要严格遵守语法规则。

我们逐一分析选项来确定哪个是对数组元素错误的引用:A. *a

这是正确的。a 是数组名,它在大多数表达式中等价于指向数组第一个元素的指针。因此,*a 等价于 a[0],表示数组的第一个元素。

B. a[5]

这也是正确的。a[5] 直接引用数组的第六个元素(数组索引从 0 开始)。

C. *(p+1)

这同样是正确的。p 是一个指向 double 类型的指针,指向数组 a 的第一个元素。p+1 将指针移动到数组的第二个元素,*(p+1) 解引用这个指针,得到数组的第二个元素,即 a[1]

D. p[8]

这是错误的。在 C/C++ 中,p[i] 是指针 p 偏移 i 个元素后的值的简写,等价于 *(p+i)。因此,p[8] 等价于 *(p+8),这意味着尝试访问 p 指向的位置之后的第九个 double 元素。由于 p 指向的是一个只有 8 个元素的数组,p[8] 尝试访问数组之外的内存,这是越界的,因此是错误的。

综上所述,错误的引用是 D. p[8]。

2.在上下文及头文件均正常的情况下,设:

enum color { red, yellow = 2, blue, white, black }r = white;

,执行 printf("%d", r) ;后的输出结果是?

在C语言中,enum类型用于定义一组命名的整数常量。当定义enum时,可以给枚举成员显式赋值,也可以不赋值。如果未显式赋值,则枚举成员的值将默认为前一个成员的值加1(第一个未赋值的成员默认为0)。

考虑以下enum定义:c

复制代码

enum color { red, yellow = 2, blue, white, black } r = white;

 

这里,enum color定义了五个成员:

red:未显式赋值,且是第一个成员,因此默认为0。

yellow:显式赋值为2。

blue:未显式赋值,因此继承

yellow的值加1,即3。

white:未显式赋值,因此继承

blue的值加1,即4。

black:未显式赋值,因此继承

white的值加1,即5。

同时,定义了一个enum color类型的变量r,并将其初始化为white。由于white的值是4,因此执行printf("%d", r);后,输出结果是4。总结:执行printf("%d", r);后的输出结果是4

3.对于条件表达式(k)?(i++):(i--)来说,其中的表达式k等价于()

A k==0B k==1C k!=0D k!=1

在C语言中,条件表达式(也称为三元运算符)的语法是:

复制代码

condition ? expression1 : expression2;

这里,condition 是一个任意表达式,它会被评估为真(非零)或假(零)。如果 condition 为真(即非零),则整个条件表达式的结果是 expression1 的值;如果 condition 为假(即零),则结果是 expression2 的值。现在考虑给定的条件表达式:

代码

(k) ? (i++) : (i--);

在这个表达式中,k 是条件部分。根据条件表达式的规则,k 会被评估:如果 k 的值非零(即真),则执行 i++。如果 k 的值为零(即假),则执行 i--。

这里的关键是理解 k 如何被评估。在C语言中,任何非零值都被视为真,而零被视为假。因此,当 k 被用作条件时,它实际上是在检查 k 是否不等于零。

现在来看选项:A. k==0:这是检查 k 是否等于零,与条件表达式的逻辑不符。B. k==1:这是检查 k 是否等于1,这同样不是条件表达式所检查的。C. k!=0:这是检查 k 是否不等于零,这与条件表达式中 k 的评估方式相符。D. k!=1:这是检查 k 是否不等于1,这也不是条件表达式所检查的。

因此,对于条件表达式 (k) ? (i++) : (i--) 来说,其中的表达式 k 等价于 k!=0正确答案是 C。

4.设有以下函数void fun(int n,char *s)(......),则下面对函数指针的定义和赋值均是正确的:()

A void (*pf)(int,char); pf=&fun;B void (*pf)(int n,char *s); pf=fun;C void *pf(); *pf=fun;D void *pf(); pf=fun;

在C语言中,定义一个指向函数的指针需要指定函数的返回类型、函数名(在指针定义中省略)以及函数的参数类型。对于给定的函数:

复制代码

void fun(int n, char *s);

我们需要定义一个函数指针,该指针能够指向这样一个函数:返回类型为void,接受一个int类型的参数和一个char *类型的参数。现在,我们逐一分析选项:A. void (*pf)(int,char); pf=&fun;

这个选项中的函数指针定义是错误的。它应该指定第二个参数为char *类型,而不是char类型。此外,虽然取函数地址是常见的做法,但在这个上下文中,直接赋值pf = fun;也是合法的,因为函数名在大多数表达式中会被解释为指向该函数的指针。

B. void (*pf)(int n,char *s); pf=fun;

这个选项是正确的。函数指针pf被正确地定义为指向一个接受int和char *参数并返回void的函数。然后,pf被赋值为fun,这是合法的,因为fun是一个符合该签名的函数。

C. void *pf(); *pf=fun;

D. void *pf(); pf=fun;

这个选项同样是错误的。与选项C类似,pf的定义与fun的签名不匹配。此外,尝试将函数名fun直接赋值给pf也是不正确的,因为类型不匹配。

综上所述,只有选项B正确地定义了函数指针,并将其赋值为指向给定函数的指针。正确答案是B:

5.阅读下面代码:

class B{public:   virtual void Fun(){}};class D: public B{public:   void Fun(){}};D dd;B* pb = ⅆD* pd = ⅆpb->Fun();pd->Fun();

上述例程调用的Fun函数顺序为()A B::Fun, D::FunB B::Fun, B::FunC D::Fun, D::FunD D::Fun, B::Fun

在C++中,虚函数(virtual function)机制允许派生类(derived class)重写(override)基类(base class)中的函数。当通过基类指针或引用调用虚函数时,实际调用的函数是派生类中重写的那个版本,而不是基类中的版本。

这种动态绑定(dynamic binding)或称为运行时多态性(runtime polymorphism)是面向对象编程中的一个核心概念。现在,我们来分析提供的代码:c复制代

class B 定义了一个虚函数 Fun()class D 继承自 B 并重写了 Fun() 函数。创建了一个 D 类型的对象 dd

B* pb = ⅆ

创建了一个指向 dd 的 B 类型的指针 pb。由于 B 中的 Fun() 是虚函数,通过 pb 调用 Fun() 时,将发生动态绑定,实际调用的是 D 类中的 Fun().

D* pd = ⅆ 创建了一个指向 dd 的 D 类型的指针 pd。通过 pd 调用 Fun() 时,直接调用的是 D 类中的 Fun(),因为这里没有涉及多态性(即没有通过基类指针调用派生类函数)。

现在,我们来看函数调用的顺序:

pb->Fun();:由于 pb 是 B 类型的指针,但指向 D 类型的对象,且 Fun() 是虚函数,因此这里调用的是 D::Fun()。

pd->Fun();:pd 是 D 类型的指针,直接指向 D 类型的对象,因此这里调用的也是 D::Fun().

综上所述,调用的 Fun 函数顺序为 D::Fun, D::Fun正确答案是 C。

未完待续,持续更新!以防后边找不到可以点赞收藏下!

相关推荐

电子产业图谱

90后500强外企软件研发工程师,专注C/C++/IoT等技术分享。