繁体   English   中英

指针类型转换

[英]pointer typecasting

int main()
{
int *p,*q;
p=(int *)1000;
q=(int *)2000;
printf("%d:%d:%d",q,p,(q-p));
}

输出

2000:1000:250

1.我无法理解p=(int *)1000; 行,这是否意味着p指向1000个地址位置? 如果我做*p=22 ,该值存储在1000个地址并覆盖现有值怎么办? 如果它覆盖该值,那么如果另一个程序正在使用1000地址空间怎么办?

  1. qp=250如何?

编辑:我试过printf("%u:%u:%u",q,p,(qp)); 输出是相同的

int main()
{
int *p;
int i=5;
p=&i;
printf("%u:%d",p,i);
return 0;
}

输出

3214158860:5
  1. 这是否意味着编译器使用的地址是整数? 普通整数和地址整数之间没有区别吗?

这是否意味着p指向1000个地址位置?

是。

如果我做* p = 22怎么办

它正在调用未定义的行为-您的程序很可能会因段错误而崩溃。

请注意,在现代操作系统中,地址是虚拟的-您不能像这样覆盖其他进程的地址空间,但是可以尝试在自己进程的地址空间中写入无效的内存位置。

qp = 250如何?

因为指针算法的工作原理是这样的(为了与数组索引兼容)。 两个指针的区别是它们的值之差除以sizeof(*ptr) 类似地,将n添加到类型T的指针ptr会得到数值ptr + n * sizeof(T)

阅读有关指针的内容。

这是否意味着编译器使用的地址是整数?

甚至没有必要“由编译器使用”部分。 地址整数,它只是C语言的一种抽象,我们有很好的指针来简化我们的生活。 如果您使用汇编语言进行编码,则只需将它们视为无符号整数即可。

顺便说一下

printf("%u:%d", p, i);

也是未定义的行为- %u格式说明符期望unsigned int ,而不是指针。 要打印指针,请使用%p

printf("%p:%d", (void *)p, i);

是的,使用*p=22您将写入1000个地址。

qp是250,因为int的大小是4,所以它是2000-1000 / 4 = 250

p = (int *) 1000的含义是实现定义的。 但是,是的,在典型的实现中,它将使p指向地址1000

之后执行*p = 22确实会尝试将22存储在地址1000 但是,在一般情况下,这种尝试将导致不确定的行为,因为不允许您仅将数据写入任意内存位置。 您必须以一种或另一种方式分配内存才能使用它。 在您的示例中,您没有做出任何努力来分配地址1000任何内容。 这意味着您的程序很可能会崩溃,因为它试图将数据写入未正确分配的内存区域。 (此外,在许多平台上,为了通过指针访问数据,这些指针必须指向正确对齐的位置。)

即使您以某种方式成功完成了在地址1000处写入22 ,也并不意味着它将以任何方式影响“其他程序”。 在某些旧平台上(例如DOS,例如)。 但是现代平台为每个正在运行的程序(进程)实现了独立的虚拟内存。 这意味着每个正在运行的进程都有其自己的单独地址1000并且看不到另一个程序的地址1000

  1. 是的, p指向虚拟地址1000 *p = 22; ,您很可能会遇到细分错误; 通常,整个前1024个字节对于读取或写入都是无效的。 假设您有虚拟内存,它不会影响其他程序; 每个程序都有其自己的虚拟地址空间。

  2. q - p的值是两个地址之间的sizeof(*p)sizeof(*q)sizeof(int)的单位数。

将任意整数强制转换为指针是未定义的行为。 任何事情都可能发生,包括什么都没有,分段错误或无声地覆盖其他进程的内存(在现代虚拟内存模型中不太可能)。

但是我们曾经在DOS实模式下使用过这样的绝对地址来访问中断表和BIOS变量:)

关于qp == 250 ,这是指针算术语义的结果。 在您的系统中, sizeof int显然是4。 因此,当您将1加到int指针时,它实际上会增加4,因此它指向下一个int而不是下一个字节。 此行为有助于阵列访问。

does this mean that p is pointing to 1000 address location?

是。 但是这个1000地址可能属于其他一些进程地址。在这种情况下,您非法访问了另一个进程的地址空间的内存。 这可能会导致分割错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM