读取指针时递增指针

Incrementing a pointer while reading it?

本文关键字:指针 读取      更新时间:2023-10-16

以下代码来自Arduino的"Print.cpp":

size_t Print::print(const __FlashStringHelper *ifsh)
{
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    n += write(c);
  }
  return n;
}

__FlashStringHelper基本上是存储在PROGMEM(程序存储器)而不是RAM中的字符数组或字符串文字。它在WString.h:中声明为

class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal))) 

我对unsigned char c = pgm_read_byte(p++);系列感兴趣,更具体地说,对(p++)部分感兴趣。我假设指针p的值在这里被读取,并且在这里也增加了一个字节,这样*ifsh中的所有字节都可以一个接一个地被读取。我说得对吗?

考虑到以上情况,我有两个问题;

  1. 在普通的C/C++编译器中,序列是什么?在Arduino中,序列又是什么?是否先读取值,然后指针递增?还是相反
  2. C/C++编译器的序列总是一样的吗他们之间有什么不同

表达式pgm_read_byte(p++)等效于

pgm_read_byte(p);
p += 1;

所有遵循该标准的C或C++编译器都将以这种方式运行。

它由C++标准和:定义

  1. 它是相同的(在这种情况下,它是后增量,因此它将在从p读取值后发生)
  2. 总是一样

关于第二个问题,这来自c89标准:

后缀++运算符的结果是操作数的值。获得结果后,操作数的值将递增。

不知何故,我相信这对于所有较新的c版本和cpp都是正确的。

Arduino使用avr-gcc编译器。所以我猜你可以放心地假设:

A=p++等于A=p;p++;

后增量运算符(即变量++)将增加变量,但返回变量的旧值。相当于:

SomeType PostIncrement(SomeType& v)
{
    SomeType oldValue = v;
    v = v + 1;
    return oldValue;
}

示例:

int x = 5;
int y = x++;
// Here x is 6 while y is 5 (i.e. the old value of x)

当对函数调用中传递的变量使用后增量时,将使用旧值调用该函数。尽管如此,增量还是在函数调用之前完成的,因为参数将在调用之前完全求值。

示例:

void f(int y)
{
    // When execution arrives here, x is 6 while y is 5 (i.e. the old value of x)
}
int main()
{
    int x = 5;
    f(x++);
    return 0;
}