如果是右值,系统如何知道它指向的地址类型?

问题描述 投票:0回答:1

当涉及到预增量或后增量时,我对右值的概念有一些疑问(可能是误解)。考虑以下 C 程序:

#include <stdio.h>

int main() {
    int a[10];
    int *ptr = a;
    printf("%d", *++ptr);

    return 0;
}

在这里,在

*++ptr
表达式中,首先评估
++ptr
,它返回
a[1]
的地址,这是一个右值。我的问题是,当我们随后使用
*
运算符取消引用该右值(地址)时,系统如何知道要获取多少字节的内存?因为
++ptr
只是一个右值,无法从右值知道它指向什么类型的数据(地址/常量)。

相反,当我们做像

*ptr
这样的事情时,系统知道取4个字节或2个字节(取决于
int
的大小)因为
ptr
*ptr
都被视为左值和系统知道
ptr
指向的数据类型。

你能消除我对此的误解吗?

arrays c pointers rvalue lvalue
1个回答
1
投票

右值确实有一个类型——在前缀(和后缀)递增和递减运算符的情况下,该类型与操作数的类型相同。所以,如果

ptr
声明为
int *ptr;
,那么
++ptr
的结果类型也是
int*

如果右值没有类型,那么数组访问将毫无意义,因为表达式

a[i]
(其中
a
T
类型的数组)是 完全等同于
*(a + i)
,其中如果a + i操作的右值结果保持第一个(在这种情况下)操作数的类型(将被视为指向数组第一个元素的指针, 因此
T*
).
不过,当使用运算表达式的结果作为类型时,有一些“陷阱”。在下面的代码中,我们可以看到

++c

的结果类型是(就像

c
本身一样)a
char
;然而,
c + 1
的结果类型是一个
int
(在我的平台上,它的大小是 4 个字节):
#include <stdio.h>

int main()
{
    char c = 42;
    printf("%zu %zu %zu\n", sizeof(c), sizeof(++c), sizeof(c + 1)); // Shows: 1 1 4
    return 0;
}

© www.soinside.com 2019 - 2024. All rights reserved.