关于指针大小的困惑

The*_*war -1 c windows 64-bit pointers

这可能是一个菜鸟问题..但这真让我感到困惑..

下面是一些示例代码

void main() {

    int a = 300;
    char *ptr = &a;
    int *intptr = &a;

    printf("%d\n %d\n", *ptr, *intptr);

}
Run Code Online (Sandbox Code Playgroud)

产量:
44
300

根据我的理解,为什么解除引用*ptr打印44是由于char指针是一个字节的事实,所以它只从int的地址读取8位...

但是这个问题:指针的大小是多少?状态Regardless of what data type they are pointing to, they have fixed size

我错过了一些东西.为什么解引用char指针打印44,如果指针大小相同?

Lun*_*din 5

首先,您的代码不是有效的C,它还会调用未定义的行为,因此任何事情都可能发生.如果您的编译器没有向您显示任何诊断消息,则需要将其卸载并改为运行.您有以下错误:

  • void main() 仅适用于专门允许这种形式的主要版本的独立实现.
  • char *ptr = &a;在C中不是有效的赋值形式.指针不兼容(1).
  • 使用%d格式说明符打印字符会调用未定义的行为.

修复这些错误后,我们得到:

#include <stdio.h>

int main (void)
{
  int a = 300;
  char *ptr = (char*)&a;
  int *intptr = &a;

  printf("%d\n %d\n", (int)*ptr, *intptr);
}
Run Code Online (Sandbox Code Playgroud)

这些都不会打印指针的大小.您打印的第一个字节的内容int a,您转换为a char,可能会或可能不会签名,并可能给出不正确的结果(此部分依赖于endianess).然后你打印整个内容int a.

你似乎想要的是打印指针本身的大小:

printf("%zu %zu\n", sizeof ptr, sizeof intptr);
Run Code Online (Sandbox Code Playgroud)

(1) C11 6.5.16.1强调矿井:

约束条件
下列之一应该成立:
/ - /
- 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值转换后的类型)两个操作数都是指向合格或非限定版本的指针兼容类型,左边指向的类型具有右边指向的所有类型的限定符;


dbu*_*ush 5

对象指针(例如指向函数之外的任何指针)在您可能遇到的大多数系统上通常具有相同的大小,但是不能保证这一点.话虽如此,即使指针大小相同,它们指向的类型也不是.

例如,在64位Windows系统上,指针的大小通常为8个字节.在你的例子中,你有char *一个int *很可能都是8个字节.这里的区别在于,取消引用char *将读取/写入1个字节,同时取消引用int *将读取/写入4个字节(假设int为32位).

假设小端字节排序,a在内存中看起来像这样:

  ------------------
a | 44 | 1 | 0 | 0 |
  ------------------
Run Code Online (Sandbox Code Playgroud)

无论ptrintptr包含的地址a.当解除引用时ptr,它只是类型char *,它只查看第一个字节.相反,当解除引用intptr(类型)时int *,它会查看所有4个字节.

  • @TheGameiswar不一定是8个字节(不是8位).如果您使用的是32位系统,则可能是4个字节.该标准并不保证所有指针的大小都相同,但实际上它们往往是.但是,是的,主要区别在于指针被解除引用.读/写的字节数取决于类型. (2认同)