指针的深入解析与应用
立即解锁
发布时间: 2025-08-20 01:16:49 阅读量: 1 订阅数: 4 


Arduino C语言编程入门与实践
### 指针的深入解析与应用
#### 1. 指针基础
指针是编程中一个强大且重要的概念。在使用指针时,其标量(scalar)在指针变量定义时就已确定,指针的类型说明符决定了标量的值,而标量用于确定指针要操作的字节数。
需要注意的是,指针在初始化之前不会指向任何有用的内容。可以使用取地址运算符 `&` 来用被指向对象的左值(lvalue)初始化指针,示例代码如下:
```c
int myVariable;
int *ptr;
ptr = &myVariable;
```
取地址运算符 `&` 会获取变量 `myVariable` 的左值,并将该值赋给指针变量 `ptr` 的右值(rvalue)。初始化指针后,就可以使用间接寻址(indirection)来更改被指向变量的右值。例如:
```c
*ptr = 10;
```
上述代码使用间接寻址运算符 `*` 和指针 `ptr` 将值 10 赋给 `myVariable`。也可以使用间接寻址运算符读取被指向的值,示例如下:
```c
Serial.print(*ptr);
```
此语句会在串行显示设备上打印值 10。
#### 2. 指针的用途
在函数调用中,默认情况下函数参数是按值传递(pass-by-value)的,即传递的是参数的临时副本,而不是参数本身。这意味着函数无法改变原始变量的值,因为它只能访问变量的右值,而不知道其左值。但当需要函数改变参数的值时,尤其是需要改变多个值时,指针就派上用场了。
以温度传感器为例,假设传感器每小时读取一次温度并将值记录在数组 `temps[]` 中,在一天结束时,需要读取 24 个值并记录当天的最低和最高温度。以下是实现该功能的代码:
```c
#include <stdio.h>
#define READINGSPERDAY 24
#define VERYHIGHTEMPERATURE 200
#define VERYLOWTEMPERATURE -200
int todaysReadings[] = { 62, 64, 65, 68, 70, 70, 71, 72, 74, 75, 76, 78,
79, 79, 78, 73, 70, 70, 69, 68, 64, 63, 61, 59};
void setup() {
int lowTemp;
int hiTemp;
int retVal;
Serial.begin(115200);
Serial.println("=== Before function call:");
Serial.print("The lvalue for lowTemp is: ");
Serial.print((long) &lowTemp, DEC);
Serial.print(" and the rvalue is ");
Serial.println((long) lowTemp, DEC);
Serial.print("The lvalue for hiTemp is: ");
Serial.print((long) &hiTemp, DEC);
Serial.print(" and the rvalue is ");
Serial.println((long) hiTemp, DEC);
retVal = CalculateMinMax(todaysReadings, &lowTemp, &hiTemp);
Serial.println("=== After the function call:");
Serial.print("The lvalue for lowTemp is: ");
Serial.print((long) &lowTemp, DEC);
Serial.print(" and the rvalue is ");
Serial.println((long) lowTemp, DEC);
Serial.print("The lvalue for hiTemp is: ");
Serial.print((long) &hiTemp, DEC);
Serial.print(" and the rvalue is ");
Serial.println((long) hiTemp, DEC);
Serial.println("\n");
}
void loop() {}
int CalculateMinMax(int temps[], int *minTemp, int *maxTemp) {
int j;
*minTemp = VERYHIGHTEMPERATURE;
*maxTemp = VERYLOWTEMPERATURE;
for (j = 0; j < READINGSPERDAY; j++) {
if (temps[j] >= *maxTemp) {
*maxTemp = temps[j];
}
if (temps[j] <= *minTemp) {
*minTemp = temps[j];
}
}
return j;
}
```
`CalculateMinMax()` 函数有三个参数:一个存储温度读数的 `int` 数组,以及两个存储传入数据的最低和最高温度的 `int` 指针。在 `setup()` 函数中调用该函数的代码如下:
```c
retVal = CalculateMinMax(temps, &lowTemp, &hiTemp);
```
第一个参数 `temps[]` 是包含 24 个温度读数的数组。需要注意的是,当单独使用数组名(没有方括号)时,实际上是引用数组的左值,因为数组是引用类型而非值类型。`CalculateMinMax()` 函数的声明可以写成以下两种形式:
```c
int CalculateMinMax(int temps[], int *minTemp, int *maxTemp)
int CalculateMinMax(int *temps, int *minTemp, int *maxTemp)
```
对于编译器来说,这两种形式中 `temps` 的解释是相同的,都是左值。在 `setup()` 函数中调用 `CalculateMinMax()` 时,后面两个参数 `minTemp` 和 `maxTemp` 是 `int` 变量。为了让函数永久改变这些变量的值,需要将它们的左值传递给 `CalculateMinMax()` 函数,这将参数的传递方式从按值传递改为按引用传递(pass-by-reference)。通过在变量名前加上取地址运算符 `&`,可以实现这种转换。
以下是该过程的流程图:
```mermaid
graph TD;
A[开始] --> B[定义变量 lowTemp 和 hiTemp];
B --> C[调用 CalculateMinMax 函数并传递左值];
C --> D[在 CalculateMinMax 函数中处理数据];
D --> E[更新 lowTemp 和 hiTemp 的值];
E --> F[结束];
```
#### 3. 修改后的闪烁程序
下面对 IDE 中自带的闪烁程序进行修改,使其使用指针。示例代码如下:
```c
#define LED 13
void setup() {
pinMode(LED, OUTPUT);
}
vo
```
0
0
复制全文
相关推荐










