-1
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. 怎么样q-p=250

编辑: 我试过printf("%u:%u:%u",q,p,(q-p));输出是一样的

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

输出

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

6 回答 6

4

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

是的。

如果我这样做 *p=22

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

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

qp=250怎么算?

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

在指针上阅读此内容。

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

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

顺便说一句,写作

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

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

printf("%p:%d", (void *)p, i);
于 2012-11-20T06:59:01.237 回答
1

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

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

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

于 2012-11-20T07:10:40.703 回答
1

是的,和*p=22你一起写到 1000 地址。

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

于 2012-11-20T06:59:58.927 回答
0

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

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

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

于 2012-11-20T07:06:44.247 回答
0
  1. 是的,p是指向虚拟地址 1000。如果使用*p = 22;,很可能会出现分段错误;很多时候,整个前 1024 个字节对于读取或写入都是无效的。假设您有虚拟内存,它不会影响另一个程序;每个程序都有自己的虚拟地址空间。

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

于 2012-11-20T07:01:19.563 回答
-1
does this mean that p is pointing to 1000 address location?

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

于 2012-11-20T06:58:31.677 回答