我有一个难题:
int *a=*b;
a[1]=3;
a[2]=5
a是指针数组,并将值指定为b。根据我的理解,[]应该是一个地址,那么为什么在实践中我们可以为指针(在本例中为[])的位置赋值?有没有解释?
答案 0 :(得分:2)
我假设这是C或Objective C / C ++的C子集,因为C +,Java,PHP和其他类C语言不使用指针。
每行使用代码标记和单个语句。
声明
int *a = *b;
创建一个指向int的指针。不是指向int的指针,指向int的指针。
然后将a中的当前地址设置为b的解引用,无论b是什么。你没有显示b的声明。除非b的类型为int **
,否则您应该收到编译器警告。
a不是指针数组。 a是指向int的指针。它可以指向单个int,也可以指向一个int数组。编译器无法区分......
如果b的类型为int **
,或者是指向int的指针,那么你的语句会取消引用其中一个指针并指向b中的第一个子数组。
代码
a[1] = 3;
假设a是一个指向整数数组的指针,并且由于编译器不能进行任何范围检查,它会尝试索引到数组并将值保存到内存块中的第二个int,即一个点至。如果a没有指向足够大的内存块以包含至少2个整数,则此语句可能会在使用受保护内存的现代计算机上崩溃,它也可能只是覆盖后面的内存。
作为@EdS。在下面的评论中指出,这在业务中称为
“未定义的行为”
如果您要使用这样的C指针,那么您需要确保它确实指向有效内存,如果您要使用指针就好像它是一个数组,那么你需要确保不要超过指针所指向的内存范围。
答案 1 :(得分:1)
但是,让我们回答你的问题:
我将逐步完成您的代码(虽然我为了示例的目的对其进行了一些修改),并向您展示它在假存储器中的作用,因此您明白了这一点:
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 book,以及this documentation,它们都能很好地解释整个内存的管理方式,以及指针算术和数组。