C语言 在右值的情况下,系统如何知道它所指向的地址类型?

hgb9j2n6  于 2023-03-22  发布在  其他
关注(0)|答案(1)|浏览(132)

我对右值的概念有一些疑问(可能是误解),当涉及到前增量或后增量时。考虑下面的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指向的数据类型。
你能澄清我对这件事的误解吗?

xzabzqsa

xzabzqsa1#

右值 * 确实 * 有一个类型--在前缀(和后缀)递增和递减运算符的情况下,该类型与操作数的类型相同。因此,如果ptr声明为int *ptr;,则++ptr的结果类型也是int*
如果右值没有类型,那么数组访问实际上是没有意义的,因为表达式a[i](其中aT类型的数组)完全等价于*(a + i),如果a + i操作的右值结果保持第一个的类型,则指针算术和随后的解引用可以 * 仅 * 被正确地执行。(在这种情况下)操作数(它将被视为指向数组第一个元素的指针,因此是T*)。
在下面的代码中,我们可以看到++c的结果类型是(像c本身一样)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;
}

相关问题