为什么这个 "for loop" 有效而不是溢出
why this "for loop" works instead of overflows
这是arduino SPI通信实例中的部分代码。
char c;
for (const char* p = "Hello, world!\n"; c = *p; p++){
SPI.transfer(c);
Serial.print(c);
}
它会输出“Hello,world!”在串口和SPI。但是为什么c = *p
可以判断这个char字符串是否结束呢?通常我们使用
int k;
char p[]="hello world!";
for (k=0; k < strlen(p); k++){
SPI.transfer(p[k]);
Serial.print(p[k]);
}
在解释之前,你必须了解一些事情:
- 字符(即
char
类型)可以被视为数字,无需根据其 ASCII 编码进行任何转换
- C 中的字符串总是以 NUL 终止符结尾。重要的是,此字符的数值为 0(即,当您将其视为数字时,它等于零)。
- 布尔值并不真正存在于独立于整数表示的 C 语言中。零被视为“假”,其他任何东西都被视为“真”。
说完这个,让我们看看循环中发生了什么。
首先,我们有一个指针p
指向字符串"Hello world!\n"
的第一个字符(这来自语句const char* p = "Hello, world!\n"
).
在循环的顶部,我们检查循环条件,即 c = *p
。请注意,这会将 p
指向的值赋值给 c
,并且 C 中的赋值计算为已赋值的值。在这种情况下,这意味着我们的测试本质上只是 *p
.
因为 C 中不存在布尔值,只有当 p
指向的字符的值为零时,*p
才为假。只有当 p
指向 NUL 终止符时才会发生这种情况,它始终位于 C 中字符串的末尾。因此,当我们到达字符串末尾时,我们的循环将停止。
这是arduino SPI通信实例中的部分代码。
char c;
for (const char* p = "Hello, world!\n"; c = *p; p++){
SPI.transfer(c);
Serial.print(c);
}
它会输出“Hello,world!”在串口和SPI。但是为什么c = *p
可以判断这个char字符串是否结束呢?通常我们使用
int k;
char p[]="hello world!";
for (k=0; k < strlen(p); k++){
SPI.transfer(p[k]);
Serial.print(p[k]);
}
在解释之前,你必须了解一些事情:
- 字符(即
char
类型)可以被视为数字,无需根据其 ASCII 编码进行任何转换 - C 中的字符串总是以 NUL 终止符结尾。重要的是,此字符的数值为 0(即,当您将其视为数字时,它等于零)。
- 布尔值并不真正存在于独立于整数表示的 C 语言中。零被视为“假”,其他任何东西都被视为“真”。
说完这个,让我们看看循环中发生了什么。
首先,我们有一个指针p
指向字符串"Hello world!\n"
的第一个字符(这来自语句const char* p = "Hello, world!\n"
).
在循环的顶部,我们检查循环条件,即 c = *p
。请注意,这会将 p
指向的值赋值给 c
,并且 C 中的赋值计算为已赋值的值。在这种情况下,这意味着我们的测试本质上只是 *p
.
因为 C 中不存在布尔值,只有当 p
指向的字符的值为零时,*p
才为假。只有当 p
指向 NUL 终止符时才会发生这种情况,它始终位于 C 中字符串的末尾。因此,当我们到达字符串末尾时,我们的循环将停止。