简体   繁体   English

指向数组c ++的指针

[英]pointer to array c++

What is the following code doing? 以下代码在做什么?

int g[] = {9,8};
int (*j) = g;

From my understanding its creating a pointer to an array of 2 ints. 从我的理解,它创建一个指向2个int数组的指针。 But then why does this work: 但是为什么这会起作用:

int x = j[0];

and this not work: 这不起作用:

int x = (*j)[0];

The parenthesis are superfluous in your example. 在您的示例中,括号是多余的。 The pointer doesn't care whether there's an array involved - it only knows that its pointing to an int 指针不关心是否涉及数组 - 它只知道它指向一个int

  int g[] = {9,8};
  int (*j) = g;

could also be rewritten as 也可以改写为

  int g[] = {9,8};
  int *j = g;

which could also be rewritten as 也可以改写为

  int g[] = {9,8};
  int *j = &g[0];

a pointer-to-an-array would look like 指向数组的指针看起来像

  int g[] = {9,8};
  int (*j)[2] = &g;

  //Dereference 'j' and access array element zero
  int n = (*j)[0];

There's a good read on pointer declarations (and how to grok them) at this link here: http://www.codeproject.com/Articles/7042/How-to-interpret-complex-CC-declarations 这里有一个很好的读指针声明(以及如何理解它们): http//www.codeproject.com/Articles/7042/How-to-interpret-complex-CC-declarations

int g[] = {9,8};

This declares an object of type int[2], and initializes its elements to {9,8} 这声明了一个int [2]类型的对象,并将其元素初始化为{9,8}

int (*j) = g;

This declares an object of type int *, and initializes it with a pointer to the first element of g . 这声明了一个int *类型的对象,并使用指向g的第一个元素的指针对其进行初始化。

The fact that the second declaration initializes j with something other than g is pretty strange. 第二个声明用g以外的东西初始化j的事实很奇怪。 C and C++ just have these weird rules about arrays, and this is one of them. C和C ++只是有关于数组的这些奇怪的规则,这就是其中之一。 Here the expression g is implicitly converted from an lvalue referring to the object g into an rvalue of type int* that points at the first element of g. 这里,表达式g被隐式地从引用对象g的左值转换为指向g的第一个元素的类型int*的右值。

This conversion happens in several places. 这种转换发生在几个地方。 In fact it occurs when you do g[0] . 事实上,当你执行g[0]时会发生这种情况。 The array index operator doesn't actually work on arrays, only on pointers. 数组索引运算符实际上不在数组上,只在指针上工作。 So the statement int x = j[0]; 所以语句int x = j[0]; works because g[0] happens to do that same implicit conversion that was done when j was initialized. 之所以有效,是因为g[0]碰巧执行了j初始化时所做的相同的隐式转换。

A pointer to an array is declared like this 指向数组的指针就像这样声明

int (*k)[2];

and you're exactly right about how this would be used 而且你对如何使用它是完全正确的

int x = (*k)[0];

(note how "declaration follows use" , ie the syntax for declaring a variable of a type mimics the syntax for using a variable of that type.) (注意“声明跟随使用” ,即声明类型变量的语法模仿使用该类型变量的语法。)

However one doesn't typically use a pointer to an array. 但是,通常不使用指向数组的指针。 The whole purpose of the special rules around arrays is so that you can use a pointer to an array element as though it were an array. 围绕数组的特殊规则的全部目的是,您可以使用指向数组元素的指针,就像它是一个数组一样。 So idiomatic C generally doesn't care that arrays and pointers aren't the same thing, and the rules prevent you from doing much of anything useful directly with arrays. 因此,惯用的C通常不关心数组和指针是不是一回事,规则阻止你做任何直接对数组有用的东西。 (for example you can't copy an array like: int g[2] = {1,2}; int h[2]; h = g; ) (例如,您不能复制数组,如: int g[2] = {1,2}; int h[2]; h = g;


Examples: 例子:

void foo(int c[10]); // looks like we're taking an array by value.
// Wrong, the parameter type is 'adjusted' to be int*

int bar[3] = {1,2};
foo(bar); // compile error due to wrong types (int[3] vs. int[10])?
// No, compiles fine but you'll probably get undefined behavior at runtime

// if you want type checking, you can pass arrays by reference (or just use std::array):
void foo2(int (&c)[10]); // paramater type isn't 'adjusted'
foo2(bar); // compiler error, cannot convert int[3] to int (&)[10]

int baz()[10]; // returning an array by value?
// No, return types are prohibited from being an array.

int g[2] = {1,2};
int h[2] = g; // initializing the array? No, initializing an array requires {} syntax
h = g; // copying an array? No, assigning to arrays is prohibited

Because arrays are so inconsistent with the other types in C and C++ you should just avoid them. 因为数组与C和C ++中的其他类型非常不一致,所以应该避免使用它们。 C++ has std::array that is much more consistent and you should use it when you need statically sized arrays. C ++的std::array更加一致,你需要在需要静态大小的数组时使用它。 If you need dynamically sized arrays your first option is std::vector. 如果你需要动态大小的数组,你的第一个选项是std :: vector。

j[0]; dereferences a pointer to int , so its type is int . 取消引用指向int的指针,因此其类型为int

(*j)[0] has no type. (*j)[0]没有类型。 *j dereferences a pointer to an int , so it returns an int , and (*j)[0] attempts to dereference an int . *j取消引用指向int的指针,因此它返回一个int ,而(*j)[0]尝试取消引用int It's like attempting int x = 8; x[0]; 这就像尝试int x = 8; x[0]; int x = 8; x[0]; .

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

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