简体   繁体   English

从指针更改数组中的值?

[英]Changing values in an array from a pointer?

I've been playing around with pointers to help get a better understanding. 我一直在玩指针,以帮助更好地理解。 I have declared a as a pointer to an array of integers of length 3 and b as an array of integers of length 3. I then point a at b . 我已宣布a作为指针,以长度为3和的整数的数组b为长度为3的整数的数组,然后我点ab

int main()
{
    int (*a)[3];
    int b[3] { 2, 4, 6 };
    a = &b;
    a[0][0] = 8;
    // This prints out 8 and 8.
    std::cout << a[0][0] << "\t" << b[0];

    // This prints out 0x28fecc and 8.
    std::cout << a[0] << "\t" << b[0];

    return 0;
}

To access an element of b through the pointer a , I have to do a[0][0] as if a were an array of arrays. 要通过指针a访问b的元素,我必须做a[0][0] ,好像它是一个数组数组。 This is compared to declaring a pointer to an array of integers using the new keyword where I can just output c[0] . 这与使用new关键字声明指向整数数组的指针进行比较,我只能输出c[0]

int* c = new int[3] { 2, 4, 6 };
std::cout << c[0];

Why is this? 为什么是这样?

Many thanks, George 非常感谢,乔治

I have to do a[0][0] as if a was an array of arrays. 我必须做a[0][0] ,好像是一个数组数组。

Indeed, a is a pointer to an array, so the array itself is *a , and the first element of the array would be (*a)[0] or, equivalently, a[0][0] . 实际上, a是指向数组的指针,因此数组本身是*a ,数组的第一个元素是(*a)[0]或等效地a[0][0]

You probably want a to be a pointer to the first element of the array (just as c is a pointer to the first element of a dynamic array): 您可能希望a成为指向数组第一个元素的指针(就像c是指向动态数组的第一个元素的指针):

int * a = b;

and now a[i] will be element i of the array as expected. 现在a[i]将是预期的数组的元素i

a is a pointer to a single array, so you really should do (*a)[0] . a是指向单个数组的指针,所以你真的应该做(*a)[0] And when you do a[0] , that's the same thing as *a , so you get the array, which in the output decays to a pointer, which is why you see an address printed. 当你执行a[0] ,这与*a相同,所以你得到的数组在输出中衰减为指针,这就是你看到打印地址的原因。

Whereas c is a pointer to an integer, and known to point to the first element of an array, so simple array notation works. c是指向整数的指针,并且已知指向数组的第一个元素,因此简单的数组表示法有效。

The normal declaration of a would be 正常申报a

int *a;

Then you could use 然后你可以使用

a = b;
std::cout << a[0];

Will print 会打印

8

It is because you defined another type. 这是因为你定义了另一种类型。 Consider one more the statement 再考虑一下这个陈述

int* c = new int[3] { 2, 4, 6 };

In the left side you use int *c. 在左侧,您使用int * c。 So you could write the same for your local array 所以你可以为你的本地数组编写相同的内容

int *a;
int b[3] { 2, 4, 6 };
a = b;

In this case you could access each element of the array simply by using one subscripting: 在这种情况下,您只需使用一个下标即可访问数组的每个元素:

a[0] = 8;

In this expression statement 在这个表达式声明中

a = b;

array b is implicitly converted to a pointer to its first element, that is subexpression b in the right side has type int * 数组b被隐式转换为指向其第一个元素的指针,即右侧的子表达式b具有类型int *

Declaration reflects use. 宣言反映了使用。

b is declared as int b[3] ; b被声明为int b[3] ; you access (the first element of) it as b[0] . 你访问(第一个元素)它作为b[0]

a is declared as int (*a)[3] ; a声明为int (*a)[3] ; the equivalent access would be (*a)[0] . 等效访问将是(*a)[0]

If you break down that "equivalent access", you can see that it has two operations. 如果您分解“等效访问”,您可以看到它有两个操作。 First, it uses the dereference operator "unary star" -- *a . 首先,它使用解除引用运算符“一元星” - *a a itself, remember, is a pointer. 记住,它本身就是一个指针。 Dereferencing a returns the value pointed to. 取消引用返回指向的值。 So once a = &b , then *a == b . 所以一旦a = &b ,那么*a == b

So what's the deal with a[0][0] ? 那么a[0][0]的交易a[0][0]什么? Well, the array access operator [] actually works on general pointers (and, to make things weirder, arrays "decay" to pointers). 好吧,数组访问运算符[]实际上适用于通用指针(并且,为了使事情变得更奇怪,数组“衰减”到指针)。 a[N] is defined in C to be exactly the same as *(a + N) ; a[N]在C中定义为与*(a + N)完全相同; so a[0] is the *a that we already discussed. 所以a[0]是我们已经讨论过的*a Basically, using a[0][0] in this context instead of (*a)[0] is using a pun based on the definition of operator [] to hide that declaration should reflect use. 基本上,在此上下文中使用a[0][0]而不是(*a)[0]使用基于operator []定义的双关语来隐藏该声明应该反映使用。

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

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