简体   繁体   English

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

[英]why the code is not printing the value pointed by the pointer?

this is the source code 这是源代码

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

the above code is printing the base address of s[2] or (s+2) array ie address of element 5 but why it is not printing the value 5 上面的代码正在打印s [2]或(s + 2)数组的基地址,即元素5的地址,但是为什么不打印值5

s is a pointer to first element of the array s (after decay), ie, the first row of array s . s是指向数组s第一个元素的指针(衰减后),即数组s的第一行。 It is of type int (*)[2] , ie, a pointer to an array of 2 elements. 它的类型为int (*)[2] ,即指向2元素的数组的指针。 s=2 is a pointer to 3rd row of array s . s=2是指向数组s第三行的指针。

On the other hand *s is of type int [2] , ie, an raay of 2 int s, this is because * is dereferencing the pointer expression s (which decays to the pointer to first row) which results in an array of 2 int's. 另一方面, *s的类型为int [2] ,即raay为2 int s,这是因为*正在取消引用指针表达式s (其衰减为指向第一行的指针),从而导致数组2 INT的。 Since 8s is also an array, it will decays to the pointer to its first element, ie, s[0][0] . 由于8s也是一个数组,它将衰减到其第一个元素即s[0][0]的指针。

Now *(s+2) is dereferencing the 3rd row of the array s . 现在*(s+2)取消引用数组s的第三行。 It will also give an array of 2 int s. 它还将给出2 int的数组。 Further it will decays to the pointer to its first element, ie, s[0][2] . 此外,它将衰减到指向其第一个元素的指针,即s[0][2]
So , after the above discussion you can say that s is a pointer to pointer after all decay performed (not exactly). 因此,在上述讨论之后,您可以说s是执行完所有衰减后的指针(不完全是)。

Dereferencing a pointer to pointer to int (after decay) will give you a pointer to int . 取消引用指向int指针 (在衰减之后)将为您提供指向int指针 You need to again derefernce *(s+2) to get the value it points to. 您需要再次取消引用*(s+2)以获得其指向的值。

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

NOTE: s , *s , &s , &s[0] , &s[0][0] all are pointing to the same location but all of the are of different types . 注意: s*s&s&s[0] &s[0][0]都指向相同的位置,但是所有都属于不同的类型

(s+2) is a pointer to the 3rd row of the array s . (s+2)是指向数组s第三行的指针。 It will give you the starting address of the 3rd row. 它将为您提供第三行的起始地址。 *(s+2) is the pointer to the first element of the 3rd row, ie, it will give you the address of the element s[0][2] . *(s+2)是指向第三行第一个元素的指针,即,它将为您提供元素s[0][2] Although these both are giving you the same location value on printing but both are of different types. 尽管它们在打印时都为您提供相同的位置值,但它们的类型不同。

*(s+2) points to the "subarray" {5,6} , whose first element is 5 : *(s+2)指向“子数组” {5,6} ,其第一个元素是5

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

So, to get the value pointed-to from the pointer , you have to insert another " * ", to deference one more time the pointer. 因此,要从指针获取指向 ,必须插入另一个“ * ”,以使指针再使用一次 This should work: 这应该工作:

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

You can think of it in this way. 您可以这样想。

*(s+2) is a pointer to the subarray {5,6} . *(s+2)是指向子数组{5,6}的指针。

Introduce a new intermediate variable int * a , equal to *(s+2) . 引入一个新的中间变量int * a ,它等于*(s+2)

Now a is a (simple, one-level-of-indirection) pointer to the array {5,6} , actually to the first element of this array. 现在, a是一个指向数组{5,6}指针(简单的一级重定向指针{5,6} ,实际上是该数组的第一个元素。

If you want the value 5 , you have to dereference the pointer, using *a (just like you do for ordinary pointers and one-dimensional arrays). 如果想要值5 ,则必须使用*a 解引用指针(就像处理普通指针和一维数组一样)。

Now if you substitute a with *(s+2) , *a becomes *(*(s+2)) (a double-dereference from s ). 现在,如果用*(s+2)替换a ,则*a变为*(*(s+2)) (从s的双重引用)。

Always remember in most cases , calling the name of the array returns the address of the first element of the array which is also referred as base address of the array, for instance 请记住,在大多数情况下,调用数组的名称会返回数组的第一个元素的地址,例如,也称为数组的基地址

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

in this code, pointer p have the address of first element of arr which is of type int *. 在此代码中,指针p具有int *类型的arr第一个元素的地址。

Now let's go step by step what actually *(s+2) returns , first calling the name of the array s returns the address of first element of the array , which in case is also an array of type int [2] ,consequently address returned will be of type int (*)[2] , now adding 2 to this address will add up to give address of 3rd element of the array by simple pointer arithmetic , and after dereferencing the address you get int [2] array , you obviously cannot print an array. 现在,让我们一步一步地了解*(s+2)返回的内容,首先调用数组s的名称将返回数组的s一个元素的地址,在这种情况下,它也是int [2]类型的数组,因此地址为返回的将是int (*)[2] ,现在在此地址上加2将通过简单的指针算术加起来得出数组的第3个元素的地址,并且在解引用该地址后,您将得到int [2] array ,显然无法打印数组。

And its also worth knowing that compiler access all arrays by pointer arithmatic , thus in s[4][2] element at [3][0] is accessed as *(*(s+2)+0) , you can use same way to access any element. 同样值得一提的是,编译器通过指针arithmatic访问所有数组,因此在[3][0] s[4][2]元素中以*(*(s+2)+0) ,您可以使用相同的值访问任何元素的方式。 and if you want to refer to 3rd element by (s+2) , you can do *((int *)s+2) , in this you are explicitly casting address returned by s which is actually of type int (*)[2] to int * . 如果要用(s+2)引用第3个元素,则可以执行*((int *)s+2) ,在这种情况下,您将显式转换s返回的地址,该地址实际上是int (*)[2]int * Thou using cast unnecessarily is not a good idea,it can lead to unnecessary complications. 不必要地使用Cast并不是一个好主意,它可能导致不必要的并发症。

Always be careful while using pointers and always concentrate on the type of address it is referring to beforehand using it. 使用指针时请务必小心,并始终专注于其在使用之前所指的地址类型。

Here s is a pointer to a pointer, so you can expect *(s+2) to print a pointer. 这里s是指向指针的指针,因此可以期望*(s+2)打印指针。

Try this to get the 5 : *(*(s+2)) 试试看得到5*(*(s+2))

s is an int** , a pointer to a pointer to an int. s是一个int** ,一个指向int的指针。 *(s+2) is an int* , a pointer to an int. *(s+2)是一个int* ,它是一个指向int的指针。 *(*(s+2)) or **(s+2) is the int you're looking for. *(*(s+2))**(s+2)是您要查找的int If you want to access the 6 , you'll need *(*(s+2)+1) . 如果要访问6 ,则需要*(*(s+2)+1)

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

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