*--a = *--b 在 C 中是什么意思
What does *--a = *--b mean in C
假设a
和b
是指针,
我的理解是*--a = *--b
表示使用指针运算从a
和b
中减去1,然后解引用a
和b
并设置它们相等。
这相当于
--a;
--b;
*a=*b
同样,什么是
*a++ = *b++;
相当于?
*a++ = *b++;
取消引用 b
并将其分配给 a
点。 ++
是后缀运算符,因此 *b
的当前值将赋给 *a
,然后两者都会递增。
如果将其保存在 while
循环中,b
中的所有字符都将被复制到 a
,包括 [=20=]
。只要 *a++ = *b++
不是 [=20=]
,这就会继续,此时循环终止。
while(*a++ = *b++);
示例:
#include <stdio.h>
int main()
{
char a_arr[30] = {0};
char b_arr[] = "Hello,World";
char *a = a_arr;
char *b = b_arr;
while(*a++ = *b++);
puts(a_arr);
puts(b_arr);
return 0;
}
例子
uint8_t *a = 1030; // POINTS TO ADDRESS 1030
uint8_t *b = 1020; // POINTS TO ADDRESS 1020
printf("%d", *(--a)); // PRINTS VALUE ON ADDRESS 1029
printf("%d", *(b++)); // PRINTS VALUE ON ADDRESS 1021
*(--a)
减去一个字节(一个地址),因为指针a
指向一个字节(即uint8_t
)。减法后,它会从地址读取值。
*(--something)
你可以写成
uint32_t *c = 1050;
c -= 1; // SUBCTRACTS 4 BYTE ADDRESS FROM POINTER c
print("%d", *c);
您可能会问为什么是 4 个字节?因为指针c
指向四字节(uint32_t
或int32_t
)数据。您可以使用 sizeof(variable)
.
以字节为单位获取数据大小
在您的例子中,假设指针 a
指向地址 40
。指针 b
指向地址 50。
地址 39
保存值 1
地址 40
保存值 2
地址 50
保存值 10
地址 51
保存值 11
uint8_t *a = 40;
uint8_t *b = 50;
printf("%d", *(--a));
printf("%d", *(b++));
首先 printf
将打印值 1
。第二个 printf
将打印值 50
。
在printf
指针a
指向地址39
并且指针b
指向地址51
之后
原因?在第一个 printf
中,它会先减去一个地址(再次减去一个,因为它指向一个字节值),然后它会解引用值(这就是为什么我们使用 *
从指针读取值地址)。
在第二个 printf
中,它首先解引用值,然后将指针向上移动一个地址。
*––a = *––b
在逻辑上等同于
tmpa = a - 1
tmpb = b - 1
*tmpa = *tmpb
a = a - 1
b = b - 1
需要注意的是 a
、b
和 *tmpa
的更新可以以任何顺序 发生,并且这些更新可以甚至交错。实现也可以跳过临时对象并立即更新指针值:
a = a - 1
b = b - 1
*a = *b
但这不是必需的或保证的。同样,
*a++ = *b++
在逻辑上等同于
tmpa = a
tmpb = b
*tmpa = *tmpb
a = a + 1
b = b + 1
对 a
、b
和 *tmpa
的更新顺序有相同的警告。同样,该实现可能会跳过使用临时对象并将其评估为
*a = *b
a = a + 1
b = b + 1
但同样,这既不是必需的也不是保证的。
假设a
和b
是指针,
我的理解是*--a = *--b
表示使用指针运算从a
和b
中减去1,然后解引用a
和b
并设置它们相等。
这相当于
--a;
--b;
*a=*b
同样,什么是
*a++ = *b++;
相当于?
*a++ = *b++;
取消引用 b
并将其分配给 a
点。 ++
是后缀运算符,因此 *b
的当前值将赋给 *a
,然后两者都会递增。
如果将其保存在 while
循环中,b
中的所有字符都将被复制到 a
,包括 [=20=]
。只要 *a++ = *b++
不是 [=20=]
,这就会继续,此时循环终止。
while(*a++ = *b++);
示例:
#include <stdio.h>
int main()
{
char a_arr[30] = {0};
char b_arr[] = "Hello,World";
char *a = a_arr;
char *b = b_arr;
while(*a++ = *b++);
puts(a_arr);
puts(b_arr);
return 0;
}
例子
uint8_t *a = 1030; // POINTS TO ADDRESS 1030
uint8_t *b = 1020; // POINTS TO ADDRESS 1020
printf("%d", *(--a)); // PRINTS VALUE ON ADDRESS 1029
printf("%d", *(b++)); // PRINTS VALUE ON ADDRESS 1021
*(--a)
减去一个字节(一个地址),因为指针a
指向一个字节(即uint8_t
)。减法后,它会从地址读取值。
*(--something)
你可以写成
uint32_t *c = 1050;
c -= 1; // SUBCTRACTS 4 BYTE ADDRESS FROM POINTER c
print("%d", *c);
您可能会问为什么是 4 个字节?因为指针c
指向四字节(uint32_t
或int32_t
)数据。您可以使用 sizeof(variable)
.
在您的例子中,假设指针 a
指向地址 40
。指针 b
指向地址 50。
地址
39
保存值1
地址
40
保存值2
地址
50
保存值10
地址
51
保存值11
uint8_t *a = 40; uint8_t *b = 50; printf("%d", *(--a)); printf("%d", *(b++));
首先 printf
将打印值 1
。第二个 printf
将打印值 50
。
在printf
指针a
指向地址39
并且指针b
指向地址51
原因?在第一个 printf
中,它会先减去一个地址(再次减去一个,因为它指向一个字节值),然后它会解引用值(这就是为什么我们使用 *
从指针读取值地址)。
在第二个 printf
中,它首先解引用值,然后将指针向上移动一个地址。
*––a = *––b
在逻辑上等同于
tmpa = a - 1
tmpb = b - 1
*tmpa = *tmpb
a = a - 1
b = b - 1
需要注意的是 a
、b
和 *tmpa
的更新可以以任何顺序 发生,并且这些更新可以甚至交错。实现也可以跳过临时对象并立即更新指针值:
a = a - 1
b = b - 1
*a = *b
但这不是必需的或保证的。同样,
*a++ = *b++
在逻辑上等同于
tmpa = a
tmpb = b
*tmpa = *tmpb
a = a + 1
b = b + 1
对 a
、b
和 *tmpa
的更新顺序有相同的警告。同样,该实现可能会跳过使用临时对象并将其评估为
*a = *b
a = a + 1
b = b + 1
但同样,这既不是必需的也不是保证的。