C 为什么代码不打印指针指向的值?
这是源代码C 为什么代码不打印指针指向的值?,c,pointers,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这里s是指向指针的指针,因此您可以期望*(s+2)打印指针 尝试此操作以获得5:*(*(s+2))
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这里
s
是指向指针的指针,因此您可以期望*(s+2)
打印指针
尝试此操作以获得
5
:*(*(s+2))
s
是指向数组s
的第一个元素(衰减后)的指针,即数组s
的第一行。它的类型为int(*)[2]
,即指向2
元素数组的指针s=2
是指向数组s
第三行的指针
另一方面,*s
的类型是int[2]
,即2
int
s,这是因为*
正在取消引用指针表达式s
(它衰减到指向第一行的指针),这将导致2
int的数组。由于8s
也是一个数组,它将衰减到指向其第一个元素的指针,即s[0][0]
现在*(s+2)
正在取消对数组s
第三行的引用。它还将给出一个2
int
s数组。此外,它将衰减到指向其第一个元素的指针,即s[0][2]
因此,在上面的讨论之后,您可以说,
s
是执行所有衰减后的指针(不完全是)
取消引用指向int
(衰减后)的指针将为您提供指向int
的指针。您需要再次删除引用*(s+2)
,以获取它所指向的值
printf("%d\n",*(*(s+2));
注意:
s
,*s
,&s
,&s[0]
,&s[0][0]
都指向同一位置,但都属于不同类型的
(s+2)
是指向数组s
第三行的指针。它会给你第三行的起始地址*(s+2)
是指向第三行第一个元素的指针,即它将为您提供元素s[0][2]
的地址。虽然它们在打印时提供相同的位置值,但它们的类型不同 s
是一个int**
,一个指向int的指针。
*(s+2)
是一个int*
,一个指向int的指针。
*(*(s+2))
或*(s+2)
是您要查找的int
。
如果你想访问6
,你需要*(*(s+2)+1)
*(s+2)
指向“子数组”{5,6}
,它的第一个元素是5
:
*(s+0) ---> {1,2},
*(s+1) ---> {3,4},
*(s+2) ---> {5,6},
*(s+3) ---> {7,8}
因此,要从指针中获取指向的值,必须插入另一个“*
”,以再次遵从指针。这应该起作用:
/* 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
(与普通指针和一维数组一样)取消对指针的引用
现在,如果将
a
替换为*(s+2)
,*a
将变成*(*(s+2))
(从s
中双重取消引用)。请记住,在大多数情况下,调用数组的名称会返回数组的第一个元素的地址,例如,该元素也称为数组的基地址
int arr={0,1,2,3};
int *p=arr
在此代码中,指针p
具有int*类型的arr
的第一个元素的地址
现在让我们一步一步地看*(s+2)
实际返回的内容,首先调用数组的名称s
返回数组的第一个元素的地址,在这种情况下,该元素也是int[2]
类型的数组,因此返回的地址将是int(*)[2]
,现在,通过简单的指针算法,将2添加到这个地址,将得到数组第三个元素的地址,并且在解引用您得到的地址int[2]array
之后,您显然无法打印数组
同样值得一提的是,编译器通过指针算术访问所有数组,因此在s[4][2]
元素中[3][0]
作为*(*(s+2)+0)
访问,您可以使用相同的方法访问任何元素。
如果您想通过(s+2)
引用第三个元素,您可以执行*((int*)s+2)
,在这里,您显式地将s
返回的地址强制转换为int*
,它实际上是int(*)[2]
类型。不必要地使用石膏不是一个好主意,它会导致不必要的并发症
在使用指针时一定要小心,在使用指针之前一定要注意它所指的地址类型。因为你需要取消引用两次!但是*(s+2)表示(s+2)元素处的值,即(s+2)处的值是数组,而不是整数。(请记住,这是一个数组数组)因此它应该打印(s+2)基址处的值,(s+2)和*(s+2)之间的区别。
s
是一种数组类型。请记住,数组不是指针!我无法得到(s+2)基址处的概念*(s+2)表示值,即5,因此它应该打印5(s+2)和*(s+2)之间的区别是解引用运算符。它取消引用(返回内容)正在操作的对象。所以*(s+2)
返回地址s+2
处的内容。为什么要取消引用两次。。*(s+2)的意思是什么……它不是意味着……基本价值增加吗