为什么代码不打印指针指向的值?

时间:2014-01-14 17:53:20

标签: c pointers

这是源代码

int main()
{
int s[4][2]={
            {1,2},
            {3,4},
            {5,6},
            {7,8},
          };
printf("%d\n",*(s+2);
return 0;
}

上述代码打印s [2]或(s + 2)数组的基地址,即元素5的地址 但为什么它不打印价值      5

5 个答案:

答案 0 :(得分:4)

s是指向数组s的第一个元素(在衰减之后)的指针,即数组s的第一行。它是int (*)[2]类型,即指向2元素数组的指针。 s=2是指向数组s的第3行的指针。

另一方面,*s的类型为int [2],即2 int的raay,这是因为*正在取消引用指针表达式s(衰减到指向第一行的指针),这会导致2 int的数组。由于8s也是一个数组,它将衰减到指向其第一个元素的指针,即s[0][0]

现在*(s+2)取消引用数组s的第3行。它还会提供一系列2 int s。此外,它将衰减到指向其第一个元素的指针,即s[0][2] 因此,在上面的讨论之后,你可以说s是一个指向所有衰减执行后指针的指针(不完全正确)。

取消引用指向int 的指针的指针(在衰减后)将为您提供指向int 指针。您需要再次derefernce *(s+2)来获取它指向的值。

printf("%d\n",*(*(s+2));  

注: s*s&s&s[0]&s[0][0]都指向同一位置,但全部属于不同类型的。

(s+2)是指向数组s的第3行的指针。它会给你第3行的起始地址。 *(s+2)是指向第3行第一个元素的指针,即它将为您提供元素s[0][2]的地址。虽然这两者在打印时给你的位置值相同但两者都有不同的类型。

答案 1 :(得分:1)

*(s+2)指向“子阵列”{5,6},其第一个元素是5

 *(s+0) ---> {1,2},
 *(s+1) ---> {3,4},
 *(s+2) ---> {5,6},
 *(s+3) ---> {7,8}

因此,要从指针中获取值指向,您必须再插入另一个“*”到 deference 指针。这应该有效:

/* Dereference s+2 two times, to get the value 5: */
printf("%d\n",*(*(s+2)));

你可以这样想。

*(s+2)是指向子数组{5,6}的指针。

引入一个新的中间变量int * a,等于*(s+2)

现在a是指向数组{5,6}的(简单的,单级别的间接)指针,实际上是指该数组的第一个元素。

如果你想要值5,你必须使用*a 取消引用指针(就像你对普通指针和一维数组所做的那样)。 / p>

现在,如果您将a替换为*(s+2)*a将变为*(*(s+2))(来自s的双重引用)。

答案 2 :(得分:1)

在大多数情况下,请记住,调用数组的名称会返回数组的第一个元素的地址,也称为数组的基址,例如

    int arr={0,1,2,3};
    int *p=arr

在此代码中,指针p具有arr的第一个元素的地址,其类型为int *。

现在让我们一步一步地实现*(s+2)返回的内容,首先调用数组的名称s返回数组的第一个元素的地址,以防万一也是类型{ {1}},因此返回的地址将是int [2]类型,现在向此地址添加2将通过简单的指针算法累加给出数组的第3个元素的地址,并且在取消引用地址后得到{{} 1}},你显然无法打印数组。

并且还值得知道编译器通过指针算术访问所有数组,因此在int (*)[2] int [2] array元素中s[4][2]访问[3][0],您可以使用相同的方式访问任何元素。 如果你想通过*(*(s+2)+0)引用第3个元素,你可以(s+2),你可以明确地转换*((int *)s+2)返回的地址,实际上是s类型的地址int (*)[2]。你不必要地使用演员表并不是一个好主意,它可能导致不必要的复杂化。

使用指针时要小心,并始终专注于事先使用它所指的地址类型。

答案 3 :(得分:0)

此处s是指向指针的指针,因此您可以期望*(s+2)打印指针。

尝试此操作以获取5*(*(s+2))

答案 4 :(得分:0)

sint**,指向int的指针。 *(s+2)int*,指向int的指针。 *(*(s+2))**(s+2)是您要找的int。 如果您想访问6,则需要*(*(s+2)+1)