(嵌入式八股)No.1 C语言(1)

写在前面,在嵌入式软件面试中,面试官会问你使用哪个编程语言更多一点?C or C++?其实在嵌入式中用C多一点,那么接下来你要重点掌握关键字的作用及其原理,然后就是指针,位运算等,还有内存管理,排序算法最好也了解一下,毕竟有的面试官直接让你手撕快排!

1.1 static(建议不仅要知道用法还要知道原理)

static关键字有多种用途,主要用于控制变量和函数的作用域和存储期。

  它主要有三种常见使用场景:

  1. 修饰局部变量(local variable)

void foo(void) {
    static int count = 0;
    count++;
    printf("count = %d\n", count);
}

  2. 修饰全局变量(global variable)

应用:
限制全局变量的可见性(“封装”全局变量)
避免命名冲突
// file1.c
static int g_val = 10; // 仅 file1.c 内可见

// file2.c
static int g_val = 20; // 与 file1.c 的 g_val 无冲突

   3. 修饰函数(function)

static void helper(void) {
    // 仅在本文件可见
}

总结:

a.修饰局部变量

b.修饰全局变量

c.修饰函数

1.2 const(C中的变量:局部,函数形成,返回值,指针)

const 是 C 语言中一个非常常见但容易混淆的关键字,它用于定义只读对象(read-only object),也常与指针结合使用

Const的基本用法:

1.修饰变量

const int a = 100;  // a 是常量,值不能被修改
// a = 200;  // 错误:a 是常量,不能被修改
说明:const 修饰的变量在初始化后,其值不能被修改。

2.修饰函数参数

void func(const int x) {
    // x = 200;  // 错误:x 是常量,不能被修改
}
说明:const 修饰函数参数,表示函数体内不能修改该参数的值。这通常用于防止函数意外修改参数值。

3.修饰函数返回值

const char* getstr() {
    return "Hello, World!";  // 返回的是字符串常量
}
说明:const 修饰函数返回值,表示返回值不能被修改。这通常用于返回字符串常量或其他不可修改的对象。

4.修饰指针(务必掌握)

1.常量指针:指针指向的内容不能修改,但指针的地址可以修改。
const int* a;  // 等同于 int const* a;
const int b = 100;
const int* a = &b;
// *a = 200;  // 错误:a 指向的内容不能修改
a = &b;  // 正确:a 的地址可以修改
说明:int* const a 表示 a 的地址是常量,不能修改 a 的地址。
2.指针常量:指针的地址不能修改,但指针指向的内容可以修改。
int* const a;
int b = 100;
int* const a = &b;
*a = 200;  // 正确:a 指向的内容可以修改
// a = &b;  // 错误:a 的地址不能修改
说明:int* const a 表示 a 的地址是常量,不能修改 a 的地址。
3.常量指针常量:指针的地址和指向的内容都不能修改。
const int* const a;
const int b = 100;
const int* const a = &b;
// *a = 200;  // 错误:a 指向的内容不能修改
// a = &b;  // 错误:a 的地址不能修改
说明:const int* const a 表示 a 的地址和指向的内容都是常量,都不能被修改。

形式

含义

可改内容

const int *p 或 int const *p

常量指针(pointer to const)

✅ 指针可改❌ 所指内容不可改

int * const p

指针常量(const pointer)

❌ 指针不可改✅ 所指内容可改

const int * const p

指向常量的常指针

❌ 都不可改

1.3 const 和 #define的区别(了解即可)

1.#define 是一个预处理指令,用于定义宏(macro)。宏是一种简单的文本替换机制,它在编译之前由预处理器(preprocessor)处理。#define 可以用于定义常量、函数宏以及条件编译指令。

类别

示例

功能

对象宏

#define PI 3.14

定义常量

数宏

#define MAX(a,b) ((a)>(b)?(a):(b))

实现简单函数替代(注意括号的重要性!!!)

条件宏

#ifdef DEBUG ... #endif

控制编译行为

字符串化

#define STR(x) #x

参数转字符串

拼接

#define JOIN(a,b) a##b

拼接标识符

系统宏

__FILE__, __LINE__

获取编译信息

2.二者区别

特性

#define

const

处理阶段

预处理阶段(文本替换)

编译阶段

是否分配内存

是否有类型

有类型

是否可调试(在符号表中)

是否可作用域控制

否(全局有效)

调试安全性

3.使用 #define 定义常量

#include <stdio.h>

#define MAX_VALUE 100 // 使用宏定义一个常量 MAX_VALUE,值为 100
                      // 这是一个简单的文本替换,没有类型,作用域是整个文件

int main() {
    int value = MAX_VALUE; // 将 MAX_VALUE 的值赋给变量 value
                           // 在预处理阶段,MAX_VALUE 会被替换为 100
    printf("The value is: %d\n", value); // 打印变量 value 的值
    return 0; // 程序正常结束
}

4.使用const定义常量

#include <stdio.h>

const int MAX_VALUE = 100; // 使用 const 定义一个常量 MAX_VALUE,值为 100
                           // 这是一个有类型的常量,类型为 int,作用域取决于定义位置
                           // 如果定义在函数外部,它是全局常量;如果定义在函数内部,它是局部常量

void MofConst()
{
  const int MIN_VALUE = 10; //注意如果在函数内部定义的局部变量后面是无法访问到的。
}
int main() {
    int value = MAX_VALUE; // 将 MAX_VALUE 的值赋给变量 value
                           // MAX_VALUE 是一个实际的变量,有内存分配
    printf("The value is: %d\n", value); // 打印变量 value 的值
    return 0; // 程序正常结束
}

5.const修饰的变量存放位置

对于const修饰的局部变量:存放在栈中,代码结束就会释放,在C语言中可以通过指针修改里面的值。

对于const修饰的全局变量(已初始化的)存放在只读数据段,不可以通过指针修改里面的值,未出示化的存放在.bss。

1.4 volatile(编译优化阶段)

    它在嵌入式开发、驱动编程、RTOS 等场景中尤为关键,因为它直接影响编译器优化行为volatile表示“易变的”,告诉编译器:这个变量的值随时可能发生变化,不能对它进行优化。

使用场景:

情况

示例

外设寄存器(硬件自动修改)

ADC 状态寄存器

中断服务程序修改的变量

flagcounter

多线程共享变量

RTOS / 多核系统中的全局标志位

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

泻湖花园嵌入式Offer指南 文章被收录于专栏

从入门到上岸,一站式搞定求职! 本硕纯机械,无竞赛无论文,后转行嵌入式软件开发(因为课题组师哥转嵌入式拿到30Woffer之后狠狠心动),秋招最终收获35W+offer可以为27届或者28届的的UU们提供参考,可以关注一下!!!

全部评论
点赞 回复 分享
发布于 03-03 22:46 山东
蹲蹲面经
点赞 回复 分享
发布于 03-03 22:45 山东
都是比较基础,常用的东西
点赞 回复 分享
发布于 2025-11-13 18:51 陕西

相关推荐

04-18 21:21
佛山大学 Java
点赞 评论 收藏
分享
评论
5
17
分享

创作者周榜

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