表示指向数组的指针的不同方式

时间:2013-10-27 14:11:41

标签: c++ arrays pointers

我看过pointer to array c++ 并进行了一些实验。

#include <iostream>
using namespace std;
int main()
{
    int g[] = {9,8};
    int (*j)[2] = &g;
    int *i = g;

    int n = (*j)[0];
    int m = *(i + 0);
    cout << "n:" << n << endl;
    cout <<"m:" << m << endl;
    cout << "=============" << endl;
    cout << "*(j):" << *(j) << endl;//9's address ???
    cout << "j:" << j << endl;//9's address ???
    cout << "&j:" << &j << endl;//what it is???
    cout << "&(*j)" << &(*j) << endl;//9's address ???
    cout << "=============" << endl;
    cout << "*(i):" << *(i) << endl;//get the value pointered by i
    cout << "i:" << i << endl;//i's value store g's address
    cout << "&i:" << &i << endl; //i's address
    cout << "&(*i):" << &(*i) << endl;//9's address
    cout << "=============" << endl;
    cout << "*(g):" << *(g) << endl;//get the value pointered by g
    cout << "g:" << g << endl;//g's value store 9's address
    cout << "&g:" << &g << endl;//9's address???
    cout << "&(*g):" << &(*g) << endl;//9's address
    return 0;
}

结果是:

n:9
m:9
=============
*(j):0x7fff56076bbc
j:0x7fff56076bbc
&j:0x7fff56076bb0
&(*j)0x7fff56076bbc
=============
*(i):9
i:0x7fff56076bbc
&i:0x7fff56076ba8
&(*i):0x7fff56076bbc
=============
*(g):9
g:0x7fff56076bbc
&g:0x7fff56076bbc
&(*g):0x7fff56076bbc
[Finished in 0.3s]

我想问的是:

1.为什么

    int (*j)[2] = &g;
    int *i = g;

如果我将&g更改为g,或将g更改为&g,则会产生编译错误,有什么区别?

(我认为数组名是一个指针,所以为什么我不能使用int (*j)[2] = g &g的含义是什么,它已经是一个指针,为什么再次获取地址?)

2。 由于&gg,他们的地址是相同的,为什么不能交换?

3。 为什么&g的值为9的地址?它存储自己的地址吗?

4。 你能解释j变量部分吗? 我无法理解为什么j存储9的地址,*(j)获取9的地址,&(*j)获取{ {1}}的地址也是?

我现在很困惑。我完全理解的是关于9变量部分, i变量部分对g感到困惑,&g变种部分全都混淆了。 j部分也很混乱。

3 个答案:

答案 0 :(得分:1)

  1. g是变量(在本例中是数组),&amp; g是变量的地址(在这种情况下是数组开头的地址。你可能理解,但编译器没有,因此它会给你一个错误。

  2. 如果你愿意做类型转换,它们可能会被交换,但在这种情况下这不是一个好主意。

  3. 因为g是整数数组,并且该数组的第一个(第0个)元素的地址恰好是整个数组的地址。这有道理吗?

  4. j在你的情况下是一个指向数组的指针,当然它也是一个指向该数组的第0个元素的地址的指针(根据定义)

答案 1 :(得分:1)

(*j)[2]是指向2个整数数组的指针。换句话说,它(几乎)与指向int的指针等效。行int (*j)[2] = g;尝试将int*分配给(int**)这是一种类型不匹配。行int *i = &g;尝试将int**分配给int*,这又是类型不匹配。

(I think that the array name is a pointer, so why cannot I use int (*j)[2] = g and what is the meaning of &g, it is a pointer already, why get address again?)

地址是什么?在类型检查中,C ++区分不同类型的变量的地址,因此即使int*int**都是地址(指针),它们也指向不同的类型。

答案 2 :(得分:1)

您可以查看此信息,了解为什么g&g拥有相同的地址:

How array name has its address as well as its first element in it?

当您将g更改为&g时,编译器会抱怨,因为类型不匹配。这意味着在语义上,g&g具有不同的含义,即使它们可能引用相同的东西:g,当在表达式中使用时,衰减为指向int的指针({{ 1}}),但int *是指向2个int数组的类型指针。这些是不兼容的类型;你不能将一个指向int数组的指针赋给一个指向int的指针(反之亦然)。

您声称&g已经是指针是错误的:g是一个数组。在表达式中使用时,它会衰减为指向数组第一个元素的指针。指针只是一个包含地址的东西;数组地址(第一个元素的地址)。使用g,您将获得指向数组的指针,您不会获得指向指针的指针,因为当使用引用运算符时,数组不会衰减为指针。可以这样想:如果数组是一个地址,那么应用“地址”运算符 - &g - 会产生相同的地址,按照惯例,它是第一个元素的地址。如果不在表达式中应用&运算符,则数组会衰减为指向第一个元素的指针,然后再次 - 指向第一个元素,相同的地址为&