【问题标题】:why a pointer can be assigned value?为什么指针可以赋值?
【发布时间】:2014-01-31 21:12:09
【问题描述】:

我有一个谜题:

int *a=*b;
a[1]=3;
a[2]=5

a 是一个指针数组,赋值为 b。在我的理解中,a[] 应该是一个地址,那么为什么在实践中我们可以为指针(在本例中为 a[])指向的位置赋值呢?有解释吗?

【问题讨论】:

  • a[1] 与写 *(a + 1) 完全相同。显然你可以写*a = 3,因为aint*,所以你也可以写*(a + 1) = 3,所以你也可以写a[1] = 3
  • a 不是指针数组。 a 是一个指针。
  • 什么是*(a+1)?你的意思是*a[1]?
  • 不,我的意思正是我写的。试试看,然后找一些指针教程来更新你的知识。
  • 阅读comp.lang.c FAQ的第6部分。

标签: c pointers


【解决方案1】:

我假设这是 C 或 Objective C/C++ 的 C 子集,因为 C+、Java、PHP 和其他类似 C 的语言不使用指针。

使用代码标签和每行单个语句。

声明

int *a = *b;

创建 a 作为指向 int 的指针。不是指向 int 的指针,而是指向 int 的指针。

然后它将 a 中的当前地址设置为 b 的取消引用,无论 b 是什么。您没有显示 b 的声明。除非 b 的类型为 int **,否则您应该会收到编译器警告。

a 不是指针数组。 a 是指向 int 的指针。它可以指向一个整数,也可以指向一个整数数组。编译器无法区分..

如果 b 的类型为 int **,或指向 int 的指针,那么您的语句会取消引用其中一个指针并指向 b 内的第一个子数组。

代码

a[1] = 3;

假设 a 是一个指向整数数组的指针,并且由于编译器无法进行任何范围检查,它会尝试对数组进行索引并将值保存到 a 指向的内存块中的第二个 int到。如果 a 没有指向足够大以包含至少 2 个整数的内存块,则此语句可能会在使用受保护内存的现代计算机上崩溃,它也可能只是覆盖后面的内存。

作为@EdS。在下面的评论中指出,这在业界被称为

“未定义的行为”

如果您要使用这样的 C 指针,您有责任确保它确实指向有效内存,并且如果您要像使用数组一样使用指针,您确保不超出指针所指向的内存范围的负担是您的责任。

【讨论】:

  • 这一切都很好,但实际上,至少应该提到一个术语未定义的行为
【解决方案2】:

但是让我们回答你的问题:

下面我将逐步浏览您的代码(尽管出于示例的目的我对其进行了一些修改),并向您展示它在假内存中所做的事情,所以您明白了:

int b[4];

在这里您分配 4 个内存单元,并为包含第一个内存单元地址的内存单元设置 b 一个标签:

variable     b                      
address      0x1   0x2 0x3 0x4 0x5 
memory      [0x2] [   |   |   |   ]

然后:

int* a = b;

在这里,您分配一个可以包含地址的新内存单元,因为它是用指针​​类型声明的,然后您将b 内存单元的内容分配给它:

variable     b                       a
address      0x1   0x2 0x3 0x4 0x5   0x6
memory      [0x2] [   |   |   |   ] [0x2]

然后:

a[1]=3;
a[2]=5;

您正在将一个值设置为a[1],它使用指针算术转换为*(a+1),这是地址0x2 + 1 的内容,即0x3 的内容。与a[2] 相同。现在的记忆是:

variable     b                       a
address      0x1   0x2 0x3 0x4 0x5   0x6
memory      [0x2] [   |  3|  5|   ] [0x2]

我希望这个 ASCII 码能让数组的工作原理更加清晰!您绝对应该阅读Kernighan and Ritchie bookthis documentation,它们都很好地解释了整个内存是如何管理的,以及指针算法和数组。

【讨论】:

  • 注:这就是在阅读this之类的内容后回答时会发生的情况
  • 谢谢。真的很有帮助。
  • 真的,阅读本书和在线文档,它们应该对你有帮助!
  • 好的,我会的。我是 c 代码的新手。再次感谢您的回答。
  • 好吧,如果你想感谢我,我更喜欢+1 而不是-1 :->
猜你喜欢
  • 2021-10-13
  • 1970-01-01
  • 2023-04-02
  • 2021-03-10
  • 1970-01-01
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多