取消引用这个指针给了我 -46,但我不知道为什么 [英] Dereferencing this pointer gives me -46, but I am not sure why

查看:41
本文介绍了取消引用这个指针给了我 -46,但我不知道为什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我运行的程序:

#include <stdio.h>

int main(void)
{
    int y = 1234;
    char *p = &y;
    int *j = &y;
    printf("%d %d
", *p, *j);
}

我对输出有点困惑.我看到的是:

I am slightly confused about the output. What I'm seeing is:

-46 1234

我编写了这个程序作为实验,但不确定它会输出什么.我期待可能来自 y 的一个字节.

I wrote this program as an experiment and wasn't sure what it was going to output. I was expecting possibly one byte from y.

这里的幕后"发生了什么?取消引用 p 如何给我 -46?

What is happening "behind-the-scenes" here? How does dereferencing p give me -46?

正如其他人所指出的,我必须进行显式转换才能不导致 UB.我不会将该行从 char *p = &y; 更改为 char *p = (char *)&y; 以便我不会使答案无效下面.

As pointed out by others, I had to do explicit casting to not cause UB. I am not changing that line from char *p = &y; to char *p = (char *)&y; so that I am not invalidating the answers below.

该程序不会导致任何 UB 行为,如此处所指.

This program is not causing any UB behaviour as pointed here.

推荐答案

如果你有类似的事情,

int x = 1234;
int *p = &x;

如果您取消引用指针 p 那么它将正确读取整数字节.因为你声明它是指向 int 的指针.它将知道 sizeof() 运算符读取多少字节.通常 int 的大小是 4 字节(对于 32/64 位平台)但它依赖于机器,这就是为什么它会使用 sizeof() 操作员知道正确的尺寸并会阅读.

If You Dereference Pointer p then it will correctly read integer bytes. Because You declared it to be pointer to int . It will know how many bytes to read by sizeof() operator. Generally size of int is 4 bytes (for 32/64-bit platforms) but it is machine dependent that is why it will use sizeof() operator to know correct size and will read so.

为了您的代码

 int y = 1234;
 char *p = &y;
 int *j  = &y;

现在 pointer p 指向 y 但我们已经声明它是指向 char 的指针所以它只会读取一个字节或其他任何东西字节字符是 .1234 二进制表示为

Now pointer p points to y but we have declared it to be pointer to a char so it will only read one byte or whatever byte char is of . 1234 in binary would be represented as

        00000000 00000000 00000100 11010010

        00000000 00000000 00000100 11010010

现在如果你的机器是小端的,它会存储反转它们的字节

Now if your machine is little endian it will store the bytes reversing them

        11010010 00000100 00000000 00000000

        11010010 00000100 00000000 00000000

11010010address 00 假设地址00000100address 01> 等等.

11010010 is at address 00 Hypothetical address, 00000100 is at address 01 and so on.

BE:      00   01   02   03
       +----+----+----+----+   
    y: | 00 | 00 | 04 | d2 |
       +----+----+----+----+


LE:      00   01   02   03
       +----+----+----+----+
    y: | d2 | 04 | 00 | 00 |
       +----+----+----+----+

(In Hexadecimal)

所以现在如果你取消引用 pointer p 它将只读取第一个字节并且输出将是 (-46signed char210unsigned char 的情况下,根据 C 标准,普通 char 的符号是实现定义的.)因为字节读取将是 11010010代码>(因为我们指向了signed char(在本例中它是signed char).

So now if you dereference pointer p it will read only first byte and output will be (-46in case of signed char and 210 in case of unsigned char, according to the C standard the signed-ness of plain char is "implementation defined.) as Byte read would be 11010010(because we pointed signed char(in this case it is signed char).

在您的 PC 上,负数表示为 2 的补码,因此 最-有效位是符号位.第一位 1 表示符号.11010010 = –128 + 64 + 16 + 2 = –46 并且如果您取消引用 pointer j 它会像我们一样完全读取 int 的所有字节声明它是指向 int 的指针,输出将是 1234

On your PC negative numbers are represented as 2's Complement so the most-significant bit is the sign bit. First bit 1 denotes the sign. 11010010 = –128 + 64 + 16 + 2 = –46 and if you dereference pointer j it will completely read all bytes of int as we declared it to be pointer to int and output will be 1234

如果您将指针 j 声明为 int *j 那么 *j 将在这里读取 sizeof(int) 4 个字节(取决于机器).与 char 或任何其他数据类型一样,指向它们的指针将读取与大小相同的字节数,char 为 1 个字节.

If you declare pointer j as int *j then *j will read sizeof(int) here 4 bytes(machine dependent). Same goes with char or any other data type the pointer pointed to them will read as many bytes there size is of , char is of 1 byte.

正如其他人指出的那样,您需要显式转换为 char* 作为 char *p = &y; 是一个约束违规 - char *int * 不是兼容的类型,而是写 char *p = (char *)&y.

As others have pointed, you need to explicitly cast to char* as char *p = &y; is a constraint violation - char * and int * are not compatible types, instead write char *p = (char *)&y.

这篇关于取消引用这个指针给了我 -46,但我不知道为什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆