一、一些常用的关键字
1.extern
extern表明变量或者函数是定义在其他其他文件中的
例如:extern int a;
显式的说明了a的存储空间是在程序的其他地方分配的,在文件中其他位置或者其他文件中寻找a这个变量。
C语言extern关键字用法和理解_c extern-优快云博客
2.volatile
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
volatile 影响编译器编译的结果,volatile指出 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)
volatile int i=10;
int j = i;
...
int k = i;
volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。
而优化做法是,由于编译器 发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。
这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。
C语言中volatile的用法及意义_volatile char-优快云博客
3.static
static,中文意思是静态的。
1.在函数中声明变量时, static 关键字指定变量只初始化一次,并在之后调用该函数时保留其状态。
2.在声明变量时,变量具有静态持续时间,并且除非您指定另一个值。
3.在全局和/或命名空间范围 (在单个文件范围内声明变量或函数时) static 关键字指定变量或函数为内部链接,即外部文件无法引用该变量或函数。
4.static 关键字 没有赋值时,默认赋值为 0
5.static修饰局部变量时,会改变局部变量的存储位置,从而使得局部变量的生命周期变长。
存储方式:使用 static 关键字可以将变量存储在程序的静态存储区,而不是栈上,这样变量的生命周期会持续到程序结束。
作用范围:static 修饰的变量在其定义的文件或函数内可见,外部无法访问,确保了数据的封装性。
静态成员:在类中声明为 static 的成员可以在类的任何对象创建之前被访问,而不必引用任何对象。
这些特性使得 static 关键字在编程中非常有用,能够帮助程序员更好地管理变量的存储和作用范围。
C/C++ static关键字详解(最全解析,static是什么,static如何使用,static的常考面试题)-优快云博客
二、一些常用的运算符
1.三目运算符
三目运算符是一种判断表达式,可以简化if条件判断的写法。这种结构使得我们可以在一行代码中完成通常需要 if else 语句才能实现的功能。
C语言中的三目运算符只有一个,就是条件运算符? :,它允许我们在一行代码中完成条件判断和赋值操作。这个运算符的语法结构非常独特,由三个部分组成,因此得名“三目运算符”
问号运算符的标准格式:表达式1?表达式2:表达式3
若表达式1为真,则执行表达式2,为假,则执行表达式3
#include <stdio.h>
int main()
{
int a = 10, b = 20;
int max = (a > b) ? a : b;
printf("The maximum of %d and %d is %d\n", a, b, max);
return 0;
}
这段代码的输出结果为:
The maximum of 10 and 20 is 20
device_parametert.runState = device_parametert.runState ? 0:1;
三、基础理论知识
1.寄存器基地址与偏移地址
寄存器的地址 = 基地址+偏移地址
比如:
整个外设的基地址 = AHB1 的偏移+GPIOB 寄存器组的偏移+GPIOB_OSPEEDR 寄存器的偏移
0x4002 0410 = 0x4000 0000 + 0x0002 0000 + 0x0C00 + 0x10

STM32存储器映射:寄存器基地址与偏移解析-物联沃-IOTWORD物联网
2.头文件与源文件
头文件和源文件的主要区别:头文件 led.h 只包含函数声明,而源文件 led.c 包含了这些函数的具体实现。主程序文件 main.c 通过包含头文件来使用这些函数,而不需要知道它们的具体实现细节。
头文件通常包含类的声明、函数原型和宏定义,而源文件则包含具体的函数定义和变量赋值。
头文件(.h)
头文件的主要作用是提供一个接口,让其他源文件知道可以使用哪些函数和类。在头文件中,你会声明类、函数原型和宏定义。为了防止头文件被多次包含,通常会在头文件的开头和结尾使用预编译指令,例如:
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle {
private:
double r; // 半径
public:
Circle(); // 构造函数
Circle(double R); // 构造函数
double Area(); // 求面积函数
};
#endif
这种预编译指令确保了即使头文件被多次包含,其内容也只会在编译过程中出现一次,避免了重复定义的问题。
源文件(.cpp)
源文件包含了头文件中声明的函数和类的具体实现。在源文件的开头,你需要包含(#include)相应的头文件,以及其他需要的头文件。例如:
#include "Circle.h"
Circle::Circle() {
this->r = 5.0;
}
Circle::Circle(double R) {
this->r = R;
}
double Circle::Area() {
return 3.14 * r * r;
}
源文件中的函数实现提供了类和函数如何执行其任务的具体细节。在项目构建时,源文件会被编译成目标文件,然后与其他目标文件链接在一起形成最终的可执行文件。
实际应用
在实际的项目中,通常会有一个主源文件(如main.cpp),它包含了程序的入口点(main函数)。主源文件会包含项目中定义的头文件,并使用这些头文件中声明的类和函数。例如:
#include <iostream>
#include "Circle.h"
using namespace std;
int main() {
Circle c(3);
cout << "Area=" << c.Area() << endl;
return 0;
}
在这个例子中,main.cpp包含了Circle.h头文件,以便使用Circle类。当编译这个文件时,编译器会查找Circle类的定义,并在链接阶段查找Circle类成员函数的实现。
总结
头文件和源文件的区别在于它们的用途:头文件用于声明,源文件用于定义。正确地使用头文件和源文件可以提高代码的可读性和可维护性,使项目更加模块化。在编写大型项目时,这种分离是必不可少的,它允许多个开发者并行工作,而不会相互干扰。
C语言头文件和源文件的区别(附带完整示例) - C语言中文网
3.SDK与API
SDK(软件开发工具包)是一个用于帮助开发者创建应用程序的工具集合。它通常包括以下内容:
工具和库:提供开发所需的工具和库,以便开发者能够利用特定平台或服务的功能。
文档和示例代码:包含相关文档和示例代码,帮助开发者理解如何使用这些工具
API:SDK通常与API(应用程序编程接口)一起使用,API提供了与软件组件之间的交互方式。
总之,SDK是开发特定软件或服务时不可或缺的资源。
STM32 One or more Device Family Pack Devices are not present解决方法-优快云博客
4.如何安装对应芯片支持包
了充分发挥 Keil MDK 的功能,开发者需要安装相应的芯片支持包 (Pack),以获取目标芯片的器件支持、外设驱动、代码模板等资源。

被折叠的 条评论
为什么被折叠?



