指向数组元素地址的指针

Pointer to the Address of Element of an Array

int s[4][2]= {
             {1234,56},
             {1212,33},
             {1434,80},
             {1312,78}
             };
int i,j;
for(i=0;i<=3;i++)
{
    printf("\n");
    for(j=0;j<=1;j++)
    {
        printf("%d  ",*(s[i]+j));
    }
}

输出显示为

1234,56
1212,33
1434,80
1312,78

正如我们所知,*(&Variable) 将打印变量的值但是当我们在上面的程序中实现相同的概念时...

int s[4][2]= {
             {1234,56},
             {1212,33},
             {1434,80},
             {1312,78}
             };
int i,j;
for(i=0;i<=3;i++)
{
    printf("\n");
    for(j=0;j<=1;j++)
    {
        printf("%d  ",*(&s[i]+j));
    }
}

输出显示数组每个元素的地址。

为什么会这样? 为什么输出不等于数组元素的值??

你的数组是二维的。所以,s[i] 是行 i 的地址(即 s[i] 是类型 int *),而 &s[i] 是地址的地址(即类型int **)。当你在上面应用 * 时,你会得到一个地址(即 int *)。

确实,运算符&表示"address-of",*(&x)表示x的值。

注意这里s是一个二维数组,在某些情况下,数组名衰减为指向第一个元素的指针。

这里s[i]是数组类型,两个int的数组。

然后,引用 C11,章节 §6.3.2.1,

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. [...]

因此,

  • 第一种情况,

    *(s[i]+j)
    

    s[i]int [2] 类型,它退化为 int *,用于指针运算,产生另一个 int *。取消引用后,你会得到一个 int.

  • 第二种情况,

    *(&s[i]+j)
    

    由于上述相同的原因,在&s[i]的情况下,s[i]不会衰减,类型为"pointer to int [2]"并且指针算法适用于此。所以,在这种情况下,加法的结果也是 "pointer to int [2]" 并且在最终取消引用之后,它变成 int *,这是 %d 的不匹配,这就是你的编译器报告的结果.

第一种情况

你的打印语句是这样的。

printf("%d  ",*(s[i]+j));

这里s[i]+j是地址

让我们考虑 i=0,j=1 ,第一个 i 循环,第二个 j 循环。

这里的s[i]就是值1234所在的地址。假设它是 489000。 所以 s[i]+j ,这里 s[0]+1 将是值 56 所在的地址。可以说是 489004

所以,*(s[i]+j),即;这里 *(s[0]+1) 将给出地址 489004 处的值。即 56。 所以在这里它将打印值 1234、56、1212 等

第二种情况 你的打印声明是这样的。

printf("%d  ",*(&s[i]+j));

这里&s[i]+j是地址

让我们考虑 i=0,j=0 ,第 i 个循环,第 j 个循环。

这里的s[i]就是值1234所在的地址。 假设它是 489000。 所以 &s[i] 将是地址 489000 所在的地址。 假设它是 380000。 回忆指针的概念。

所以 &s[i]+j 将是 "address in which address 489000 is residing + j" 。 IE; 380000+j

我们正在对我们得到的这个特定的 'address' 应用运算符 * 的值。 *(&s[i]+j). 于是就变成了, 值在 ['address in which address 489000 is residing' + j]。 值在 [380000 + j].

当i=0,j=0时,会打印,Value At[380000],即; 489000.

因此它将打印存储值 1234、56、1212 等的地址。