Arduino - 变量与常量
Arduino - 变量与常量
Section titled “Arduino - 变量与常量”变量是程序可以操作的命名存储位置。在Arduino(和C++)中,每个变量都有一个特定的类型,它决定了变量内存的大小和布局、可以存储的值的范围以及可以对其应用的操作集。
常见Arduino数据类型
Section titled “常见Arduino数据类型”选择正确的数据类型对于编写高效无误的代码至关重要。使用过小的数据类型会导致错误,而使用过大的则会浪费宝贵的内存。
| 类型 | 大小 (在Uno/AVR上) | 范围 | 典型用途 |
|---|---|---|---|
bool | 1 byte | true or false | 存储状态(例如,按钮是否按下,LED是否亮起) |
byte | 1 byte | 0 to 255 | 处理原始字节数据,PWM值 |
int | 2 bytes | -32,768 to 32,767 | 通用整数运算,循环计数器 |
unsigned int | 2 bytes | 0 to 65,535 | 不需要负数时使用 |
long | 4 bytes | -2,147,483,648 to 2,147,483,647 | 大整数值 |
unsigned long | 4 bytes | 0 to 4,294,967,295 | 存储millis()的返回值 |
float | 4 bytes | -3.4028235E+38 to 3.4028235E+38 | 带小数点的数字(6-7位精度) |
char | 1 byte | -128 to 127 | 存储单个字符(例如,‘A’) |
注意: int和long的大小在不同的Arduino开发板上可能有所不同。在ESP32或Arduino Due等32位开发板上,int通常是4字节。请务必查阅您特定开发板的文档。
变量的作用域定义了它在程序中可以被访问的范围。理解作用域是组织代码和避免bug的关键。
局部变量在函数(如setup()或loop())或代码块(如for循环)内部声明。它们只能在该函数或代码块内访问。当函数被调用时它们被创建,当函数退出时它们被销毁。这是大多数变量的首选作用域。
全局变量在任何函数外部声明,通常位于草图(sketch)的顶部。它们可以在程序的任何函数中被访问和修改。尽管有用,但应谨慎使用,因为它们会使代码更难调试(一个函数中的bug可能会意外地改变另一个函数使用的全局变量)。
static变量是一种特殊的局部变量。它只在其函数内部可访问,但其值在函数调用之间是保留的。这是在不使用全局变量的情况下在函数内部维护状态的好方法。
作用域示例草图
Section titled “作用域示例草图”// --- 全局变量 ---// 在此文件的任何地方都可访问。int globalCounter = 0;
void setup() { Serial.begin(9600);}
void loop() { // --- 局部变量 --- // 'loopMessage' 在每次运行 loop() 时被创建和销毁。 String loopMessage = "Inside loop()."; Serial.println(loopMessage);
// 我们可以在这里访问和修改全局变量。 globalCounter++; Serial.print("Global counter is now: "); Serial.println(globalCounter);
// 调用我们的自定义函数 myFunction();
delay(1000); Serial.println("----------");}
void myFunction() { // 此函数无法访问 loop() 中的 'loopMessage'。 // 尝试这样做会导致编译错误。 // Serial.println(loopMessage); // <-- 这将无法编译
// --- 静态局部变量 --- // 'staticCounter' 只在第一次运行此函数时初始化一次。 // 它的值在对 myFunction() 的多次调用之间被记住。 static int staticCounter = 0; staticCounter++;
Serial.print("myFunction() has been called "); Serial.print(staticCounter); Serial.println(" times.");}常量是定义后其值不能更改的变量。将常量用于引脚编号、传感器阈值或配置设置会使您的代码更具可读性且更易于维护。
使用 ‘const’ 关键字(最佳实践)
Section titled “使用 ‘const’ 关键字(最佳实践)”创建常量的现代首选方式是使用const关键字。它告诉编译器该变量是只读的,并允许编译器执行优化。
const int ledPin = 13;const float pi = 3.14159;const long baudRate = 9600;
void setup() { // 现在使用常量而不是“魔术数字” pinMode(ledPin, OUTPUT); Serial.begin(baudRate);}
void loop() { // ledPin = 12; // 这将导致编译错误,这是件好事!}使用 ‘#define’ 预处理指令(传统方式)
Section titled “使用 ‘#define’ 预处理指令(传统方式)”您可能会看到一些旧代码使用#define来创建常量。这是一个预处理指令,在代码编译之前执行简单的文本替换。虽然它有效,但const通常更安全,因为它具有类型感知能力并遵守作用域规则。
// 传统方法#define LED_PIN 13