数组和指针使算术混乱
Arrays and pointers arithmetic confusion
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
return 0;
}
这里有相当新的编码器。这是取自cplusplus.com
上的指针页面的示例。他们谈论取消引用,运算符的地址,然后他们谈论数组和指针之间的关系。我注意到如果我简单地打印出一个声明的数组,它会吐出数组的地址。我真的在试图确切地理解其中一些代码行在做什么,并且遇到了困难。
一切都有意义,直到*p=10
.我把它理解为,"指针 p 指向的值等于 10",但array
不仅仅是一个值。在这种情况下,它是 5...那么,这是怎么回事呢?编译器会假设我们正在谈论数组的第一个元素吗?
更让我困惑的是p++;
. 现在p
是数组的地址。当 p 是地址时,你怎么p=p+1
?
我明白p= &numbers[2];
.以及以下*p = 30;
.
p = numbers + 3;
让我感到困惑。为什么我们可以获取一个地址并向其添加3
?而且,这甚至意味着什么?
for 循环中的所有内容都是有意义的。只是打印出数组正确吗?
提前感谢您的帮助!
正如指出的那样,由于指针算术。 所以数组numbers
和指针p
都是int的,所以在将numbers
的基址分配给指针p
并且*p=10
numbers[0]=10
现在,当您执行 p++ 时,p 的地址会递增,但不会像++
的正常算术运算那样递增到下一个数值,而是递增到下一个索引的地址numbers
。
假设一个 int 是 4 字节的内存,numbers
的初始地址是 1000。 因此,p++
使地址增加到1004,这是numbers[1]
基本上它指向内存中的下一个 int 变量位置。因此,当遇到*p = 20
时,值 20 将被分配给下一个相邻内存,即 1004 或numbers[1]=20
。
之后,p
直接分配了第 3 个索引的地址numbers[2]
即 1008(内存中的下一个 int var)。现在p
指向numbers
的第三个指数,所以*p=30
再次numbers[2]=30
p = numbers + 3; *p = 40;
做类似的事情,即将数字的基址分配给 3 个索引(1000 + 3*sizeof(int) =1012 ==>1000 + 3*4 =1012)到p
并为此分配 40。 所以它变得等同于numbers[3]=40
.
然后p = numbers; *(p+4) = 50;
将 1000 分配给p
,并使用()
将4
添加到p
的地址,并使用*()
将 50 分配给该值,该值是大括号内地址的值(1000+ 4*4 = 1016)。
在 C++: 中使用这样的指针:p = numbers
使 p 指向数组的第一个元素。因此,当你做p++
时p
你是在指向第二个元素。
现在,执行*p = 10
10
分配给p
指向的任何内容,就像在您的情况下p
指向数组的第一个元素一样,则*p = 10
与numbers[0] = 10
相同。
如果你以后看到这个:*(p + i) = 20
,这是指针算术,与p[i] = 20
相同。这就是为什么p[0] = 10
等同于*(p + 0) = 10
,等同于*p = 10
。
关于您的问题:How do you do p=p+1 when p is an address?
:由于C++中的数组按顺序存储在内存中,如果元素p
指向内存地址6400010
则p++
指向6400014
假设每个元素指向p
占用 4 个字节。如果你想知道为什么p++
是6400014
而不是6400011
,原因是C++有点神奇:当增加指针时,它不会增加1 byte
而是增加1 element
所以如果你指向整数,每个整数都占据4 bytes
,那么p
将增加4
而不是1
。
让我们分解一下:
int numbers[5];
int * p;
将数组变量分配给指针意味着指针将指向第一个元素:
p = numbers; // p points to the 1st element
*p = 10; // 1st element will be 10
p++; // go to next location i.e. 2nd element
*p = 20; // 2nd element will be 20
您可以进行指针算术,它根据类型工作。递增32-bit
计算机上的int
指针将在内存中跳转4
个字节。在64-bit
计算机上,这将是8
字节。请记住,不能使用void
指针执行此操作。
p = &numbers[2]; // assign the address of 3rd element
*p = 30; // 3rd element will be 30
p = numbers + 3; // numbers + 3 means the address of 4th element
*p = 40; // 4th element will be 40
p = numbers; // p points to the 1st element
*(p + 4) = 50; // p + 4 means the address of 5th element
// dereference 5th location and assign 50
// 5th element will be 50
网络上有很多关于指针如何工作的页面。但有几件事需要快速指出。
int* p;
上面的行表示 p 是指向 int 的指针。 为其分配某些内容不会改变它是什么。它是指向 int 的指针,而不是 int 数组。
int number[5];
p = number;
此赋值采用存储数组的地址,并将其分配给 p.p 现在指向该数组的开头。
p++;
p 现在指向数组中的第二个整数。指针按指针指向的对象的大小递增。因此,实际地址可能会增加 4 或 8,但它会转到 int 的下一个地址。
*p = 30;
这是一个作业,而不是比较。它并没有说 p 指向的是 30,而是将 30 复制到 p 指向的地址中。说"等于"在编程术语中通常令人困惑,因此使用"分配"或"比较"以明确。
1>p=numbers;
指针p
现在指向数组的开头,即第一个元素。
2>*p=10;
第一个元素现在变成 10,因为p
指向第一个元素。
3>p++;
这会将指针移动到数组的下一个元素,即第二个元素
因此,*p=20;
再次second element=20
4>p = &numbers[2];
此语句意味着p
现在指向数组的第 3 个元素。
因此,*p = 30;
将3rd element=30
5>p = numbers + 3;
Wen 我们这样做p=numbers+1;
它指向第二个元素,所以p=numbers+3;
现在将指向数组的第 4 个元素。*p = 40;
使fourth element=40
6>p = numbers;
再次p
指向数组
的第一个元素*(p+4) = 50;
现在将产生5th element=50
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 常量指针上的混乱
- 数组和指针使算术混乱
- C++智能指针混乱
- 指针混乱char* and int*
- 链接列表插入,指针混乱
- 指针地址和参考混乱
- 链表中的指针算术混乱
- 交换功能 - 指针 - 混乱
- C ,向量,指针和对象混乱
- 指针,矢量列表=大混乱
- 指向数组混乱的指针
- 使用 std::sort 对指针向量进行排序,导致地址混乱
- 我有一些混乱的指针删除和分配指针到类