为什么这个 "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 中字符串的末尾。因此,当我们到达字符串末尾时,我们的循环将停止。