请考虑:

char *s, *t;
char c;

这项任务会发生什么?

*t++ = *s++;

这在功能上是否等同于(选项1):

c = *t;
t++;
*s = c;
s++;

或者,它是否等同于此(选项2):

c = *s;
s++;
*t = c;
t++;

推荐答案

*ptr*ptr++在C中是惯用的, 但是为了非常清楚地说明*是具有单个操作数的一元运算符, 我将继续将该操作数写在括号中. 那么让我们考虑一下*(ptr)*(ptr++).

对于运算符*,我们给它什么表达式并不重要. 重要的是它的运算数的return value, 因为这是正在读取数据(赋值的右操作数)或写入数据(赋值的左操作数)的地址.

ptr++ptr具有the same个返回值(在判断之前给定相同的内存状态). 因此,*(ptr++)的行为与*(ptr)的行为相同. 唯一的区别是ptr++side effect:指针值是递增的.

但这种副作用既不会影响返回值ptr++,也不会影响*的运算. 我总是想象后递增发生在声明的末尾,但这只是我的心理模型. 无论出于什么原因(通常是性能提升),编译器may决定更早地递增ptr; 只要净效果是一样的.

所以任何包含*(ptr++)的C语句基本上都等同于包含*(ptr)的相同语句, 之后是附加语句ptr++;. 这甚至适用于多个变量后递增的情况,如您的示例所示:

*t++ = *s++;

等同于:

*t = *s;
t++;
s++;

当同一指针变量在语句中出现两次时,事情就变得棘手了. 这通常是未定义的行为(UB), 因为同一语句中(子)表达式的求值顺序在C中大部分是未定义的(除了少数操作符).

*s++ = *s++;

not(保证)等同于:

*s = *s;
s++;
s++;

C++相关问答推荐

编译SDL 2时缺少SDL_ttf

使用单个字节内的位字段

来自stdarg.h的c中的va_args无法正常工作<>

我编译了一个新的c程序,并收到以下错误

自定义应用程序上的日志(log)轮换问题

为什么在4.9.37版的内核中,kfio还需要smp_wmb呢?

核心转储文件中出现奇怪的大小变化

#If指令中未定义宏?

在我的代码中,我需要在哪里编写输出函数?

使用scanf在C中读取和存储文件中的值

VS代码';S C/C++扩展称C23真关键字和假关键字未定义

Clang警告称,`ffi_type`与`sizeof`不兼容

用C++高效解析HTTP请求的方法

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

为什么一个在线编译器拒绝这个VLA代码,而本地的Apple clang却不拒绝;t?

std::malloc/calloc/realloc/free 与纯 C 的 malloc/calloc/realloc/free 有什么不同

从管道读取数据时丢失

SSE 向量与 Epsilon 的比较

malloc 属性不带参数

如何在 C 中编辑 struct 体中的多个变量