嵌入式大厂面经第 8(持续更新中!)

这是一个嵌入式大厂面试题专栏,每天更新高频面试题。专栏将包含题目描述、详细解析、相关知识点扩展以及实际代码示例。内容涵盖操作系统、驱动开发、通信协议等核心领域,并结合实际项目经验进行分析。每道题目都会附带面试官可能的追问方向,帮助大家更好地准备面试!

1. struct 和 class 的区别

主要区别

  • 默认访问权限不同:struct:默认为 publicclass:默认为 private
  • 默认继承方式不同:struct:默认 public 继承class:默认 private 继承
  • 使用习惯不同:struct:通常用于简单的数据结构class:通常用于实现完整的面向对象功能
// struct 示例
struct Point {
    int x;  // 默认 public
    int y;  // 默认 public
    
    void setPoint(int a, int b) {  // 默认 public 方法
        x = a;
        y = b;
    }
};

// class 示例
class Circle {
    double radius;  // 默认 private
    
public:
    Circle(double r) : radius(r) {}
    
    double getArea() {
        return 3.14159 * radius * radius;
    }
};

// 继承示例
struct DerivedStruct : Point {  // 默认 public 继承
    int z;
};

class DerivedClass : Circle {  // 默认 private 继承
    // 无法访问 Circle 的 public 成员
};


2. C++ 类的访问权限

三种访问权限

  1. public类内外都可访问子类可继承
  2. protected类内可访问子类可继承类外不可访问
  3. private类内可访问子类不可继承类外不可访问
class Base {
public:
    int publicVar;      // 公有成员
    
    void publicMethod() {
        cout << "Public method" << endl;
        privateMethod();  // 类内可访问私有方法
    }
    
protected:
    int protectedVar;   // 保护成员
    
    void protectedMethod() {
        cout << "Protected method" << endl;
    }
    
private:
    int privateVar;     // 私有成员
    
    void privateMethod() {
        cout << "Private method" << endl;
    }
};

// 继承与访问权限
class Derived : public Base {
public:
    void test() {
        publicVar = 1;      // 可访问基类公有成员
        protectedVar = 2;   // 可访问基类保护成员
        // privateVar = 3;  // 错误:不能访问基类私有成员
        
        publicMethod();     // 可调用基类公有方法
        protectedMethod();  // 可调用基类保护方法
        // privateMethod(); // 错误:不能调用基类私有方法
    }
};

// 友元函数和友元类
class MyClass {
private:
    int data;
    
    friend void friendFunction(MyClass& obj);  // 友元函数声明
    friend class FriendClass;                  // 友元类声明
    
public:
    MyClass(int d) : data(d) {}
};

// 友元函数可以访问私有成员
void friendFunction(MyClass& obj) {
    cout << "Friend function accessing private data: " << obj.data << endl;
}

// 友元类可以访问私有成员
class FriendClass {
public:
    void accessPrivateData(MyClass& obj) {
        cout << "Friend class accessing private data: " << obj.data << endl;
    }
};


3. 内联函数

基本概念

  • 通过 inline 关键字声明
  • 编译时将函数调用替换为函数体
  • 减少函数调用开销,提高执行效率

特点与使用场景

  1. 优点减少函数调用开销提高执行效率保持代码可读性
  2. 缺点增加代码体积不适合复杂函数不适合频繁修改的函数
// 内联函数定义方式一:使用 inline 关键字
inline int max(int a, int b) {
    return (a > b) ? a : b;
}

// 内联函数定义方式二:在类定义中直接实现
class Calculator {
public:
    // 自动成为内联函数
    int add(int a, int b) {
        return a + b;
    }
    
    // 显式声明为内联函数
    inline int subtract(int a, int b);
    
    // 声明为非内联函数
    int multiply(int a, int b);
};

// 类外定义内联函数
inline int Calculator::subtract(int a, int b) {
    return a - b;
}

// 类外定义非内联函数
int Calculator::multiply(int a, int b) {
    return a * b;
}

// 内联函数的实际应用
class Vector {
private:
    double x, y, z;
    
public:
    Vector(double a, double b, double c) : x(a), y(b), z(c) {}
    
    // 简单的访问器和修改器适合内联
    inline double getX() const { return x; }
    inline double getY() const { return y; }
    inline double getZ() const { return z; }
    
    inline void setX(double a) { x = a; }
    inline void setY(double b) { y = b; }
    inline void setZ(double c) { z = c; }
    
    // 复杂计算不适合内联
    double magnitude() const;
};

// 非内联实现
double Vector::magnitude() const {
    return sqrt(x*x + y*y + z*z);
}


内联函数注意事项

  1. 内联是建议性的编译器可能忽略 inline 关键字复杂函数可能不会被内联
  2. 不适合内联的情况包含循环或递归的函数函数体过大的函数包含虚函数调用的函数
  3. 调试困难内联函数在调试时可能无法单步执行可能导致错误定位困难

更多内容全在下方专栏

全网最受欢迎的嵌入式笔试专栏

笔试专栏包含全部最新的笔试必考考点,非常适合在找工作面经薄弱的同学

3000+订阅还会涨价,提前订阅提前享受,持续更新中。

专栏链接:https://www.nowcoder.com/creation/manager/columnDetail/mPZ4kk

#嵌入式笔面经分享##嵌入式测试,嵌入式开发#
全部评论

相关推荐

4.综合题(18道)4.1&nbsp;下面代码输出是几?int&nbsp;main(){int&nbsp;j&nbsp;=&nbsp;2;int&nbsp;i&nbsp;=&nbsp;1;if(i&nbsp;=&nbsp;1)&nbsp;j&nbsp;=&nbsp;3;if(i&nbsp;=&nbsp;2)&nbsp;j&nbsp;=&nbsp;5;printf(&amp;quot;%d&amp;quot;,&nbsp;j);}答案:输出为5。解读:注意if的条件语句用的是赋值符&amp;quot;=&amp;quot;而不是等号&amp;quot;==&amp;quot;,因此条件一直为真。4.2&nbsp;负数和正数的反码、补码分别是什么?(1)负数的反码:对原码除符号位外的其余各位逐位取反就是反码。(2)负数的补码:负数的补码就是对反码加1。(3)正数的原码、反码、补码都一样。4.3&nbsp;编译和链接有什么不同?(如对外部符号的处理)(1)编译(+汇编)生成的是目标文件(*.o)。编译过程中对于外部符号(如用extern跨文件引用的全局变量)不做任何解释和处理,外部符号对应的就是&amp;quot;符号&amp;quot;。(2)链接生成的是可执行程序。链接将会解释和处理外部符号,外部符号对应的是地址。4.4&nbsp;函数参数的传递方式有几种?(1)两种:值传递、指针传递。(2)严格来看,只有一种传递,值传递,指针传递也是按值传递的,复制的是地址。4.5&nbsp;局部变量能否和全局变量重名?答案:能,局部会屏蔽全局。要用全局变量,需要使用&amp;quot;::&amp;quot;。注意:对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。4.6如何引用一个已经定义过的全局变量?答案:可以用引用头文件的方式(不建议,可能会造成重复定义),也可以用extern关键字。注意:(1)如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错。(2)如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在链接期间报错。以上内容摘自牛客官方专刊《嵌入式岗位笔试面试真题讲解》,数千位同学已订阅,该专刊不仅有真题讲解,还有经验分享,不清楚嵌入式该学什么的同学,想找嵌入式实习/正式工作的同学,都可以来看看:&nbsp;&nbsp;https://blog.nowcoder.net/zhuanlan/v0ELPM推荐公司:华为、小米&nbsp;、OPPO、VIVO、荣耀、努比亚、CVTE&nbsp;、&nbsp;大疆、insta360影石、美的、&nbsp;TCL、创维、海信、海尔、长虹、烽火、经纬恒润&nbsp;、小鹏、图森未来、&nbsp;百度、滴滴、蔚来、理想、比亚迪、吉利、小马智行、元戎启行、摩拜、豪威、&nbsp;联发科、&nbsp;紫光展锐、全志、&nbsp;寒武纪、晶晨半导体、汇顶、&nbsp;华为、中兴、浪潮、TP-LINK、讯飞、商汤、海康威视、浙江&nbsp;大华、旷视、360。
查看6道真题和解析
点赞 评论 收藏
分享
评论
点赞
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务