Arrays 为什么*间接运算符在二维数组中给出地址? #包括 int main() { int s[5][3]={{1,2,6},{7,3,4},{8,5,6},{2555,7,8},{766,9,0}; printf(“%u%u%u%u%u\n”),(s+0),*(s+1),*(s+2),*(s+3),*(s+4)); 返回0; }
C语言代码 在printf语句中,当我使用(s+0)时,它会打印上面代码中的地址。所以如果我使用*运算符Arrays 为什么*间接运算符在二维数组中给出地址? #包括 int main() { int s[5][3]={{1,2,6},{7,3,4},{8,5,6},{2555,7,8},{766,9,0}; printf(“%u%u%u%u%u\n”),(s+0),*(s+1),*(s+2),*(s+3),*(s+4)); 返回0; },arrays,c,pointers,Arrays,C,Pointers,C语言代码 在printf语句中,当我使用(s+0)时,它会打印上面代码中的地址。所以如果我使用*运算符 i、 e.*(s+1)它应该在地址(s+1)处给我值。但它还是给了我一个地址 所以我的问题是: 为什么*不在地址上赋予值 (s+0)与*(s+0)相同吗 ps.对于1D数组int s[]={1,2,3};s给出第0个元素的值,*(s+i)给出数组s的元素i的值。对于数组声明,像这样的表达式s+i #include <stdio.h> int main() { int s
i、 e.*(s+1)它应该在地址(s+1)处给我值。但它还是给了我一个地址 所以我的问题是:
ps.对于1D数组int s[]={1,2,3};s给出第0个元素的值,*(s+i)给出数组s的元素i的值。对于数组声明,像这样的表达式
s+i
#include <stdio.h>
int main()
{
int s[5][3] = { {1,2,6}, {7,3,4}, {8,5,6}, {2555,7,8}, {766,9,0} };
printf("%u %u %u %u %u\n", (s+0), *(s+1), *(s+2), *(s+3), *(s+4));
return 0;
}
给出指向数组第i个元素的指针。元素的类型为int[3]
。因此表达式s+i
的类型为int(*)[3]
取消对指针的引用,您将获得第i个元素的左值,即,您将获得类型为int[3]
的对象,即数组
表达式中使用的数组指示符(很少有例外)再次转换为指向其第一个元素的指针。即int[3]
类型的对象被转换为指向数组第一个元素的int*类型
例如,使用表达式
int s[5][3] = { {1,2,6}, {7,3,4}, {8,5,6}, {2555,7,8}, {766,9,0} };
您将获得指向原始数组第二“行”的第一个元素的指针
请注意,表达式*(s+1)
相当于具有数组类型int[3]
的表达式s[1]
如果要输出二维数组中每个“行”的第一个元素,则需要应用间接运算符。比如说
*(s+1)
1 7 8 2555 766
要使用指针算法输出整个数组,可以编写以下示例
*(s+1)
1 7 8 2555 766
首先,
s
不是指针,而是数组。对其应用指针算法将迫使其衰减为指针。在2D数组的情况下,衰减的s
具有int(*)[3]
-指向三个整数数组的指针。只有外部阵列会衰减
s+0==s
/*decayed*/s==&s[0]//数组衰减到指向其第一个元素的指针
&s[0][0]==&s[0]==s//来自前两个(地址运算符不堆叠)
s+1==&s[1]//指向{7,3,4}的指针
*(s+1)==s[1]//数组{7,3,4}
*(s+1)+0==s[1]+0=&s[1][0]//数组{7,3,4}衰减到指向其第一个元素的指针
*(*(s+1)+0)=**(s+1)==7//数组s[1]的第一个元素
作为练习,试着确定两边表达的类型
要回答您的问题:
s[0]
值,它本身是一个数组,衰减为一个指针,因此可以得到一个地址。这也与s
本身的地址相同,因为s==(s[0]+0)
>printf(“%u%u%u%u%u%u\n”,**(s+0),**(s+1),**(s+2),**(s+3),**(s+4));
1 7 8 2555 766
三个简单步骤:
是一个由5个数组组成的数组,其中3个s
int
是*(s+1)
的元素1。因为s
是数组的数组,所以其中的一个元素是数组;它是一个由3个s
组成的数组int
- 在表达式中使用数组时,它将转换为其第一个元素的地址。1
*(s+1)
或s[1]
将打印s[1]
的第一个元素的地址,即&s[1][0]
但是,%u
不是用于打印地址或int
的正确规范。要打印地址,请使用%p
,同时将地址转换为void*
:
1 2 6
7 3 4
8 5 6
2555 7 8
766 9 0
要打印int
,请使用%d
,而不是%u
<代码>%u表示无符号整数
脚注
1除非数组是
sizeof
的操作数,是一元&
的操作数,或者是用于初始化数组的字符串文字,否则它不会转换为地址。当您访问数组s
时,它会衰减为指向int
的数组指针,长度为3,或者int(*)[3]
。加上1意味着衰减指针现在指向下一个由3个元素组成的数组。当您取消引用该指针时,您将得到一个指向int
的指针,向该指针添加1,您将使该指针递增,指向下一个int
如果您有一个无符号字符数组
和这样的指针(很抱歉没有使用与您相同的数组,但是使用无符号字符
更容易解释)
printf("%p\n", s[1]);
此数组的数据将像这样存储在内存中(每个|
之间有一个字节):
如果您现在访问s
并向其中添加一些内容,如p=*(s+2);
(与p=s[2];
).s
将以2个数组元素的长度添加,在本例中它是2*3
,因为s在长度为3的数组中衰减。指针p现在将指向s
中索引2处数组的索引0处的无符号字符
:
1| 2| 6| 7| 3| 4| 8| 5| 6|255| 7| 8| 14| 9| 0
^ p will point to here
如果在取消引用后向它添加了一些内容,指针算法现在将对单个无符号字符
元素起作用。使用p=*(s+2)+1;
(与p=&s[2][1];
),s
将添加2个数组元素的长度,在本例中为2*3
,然后在取消引用后添加1个数组元素,在本例中为1,这意味着p
现在指向5
:
1| 2| 6| 7| 3| 4| 8| 5| 6|255| 7| 8| 14| 9| 0
^ p will now point to here
s[0][0]
从地址0xffff089(无论什么)开始。s+0
将指针指向数组的第一个元素。*(s+0)
将指针指向[][]数组的第一个元素,该元素仍然是值1的指针<
1| 2| 6| 7| 3| 4| 8| 5| 6|255| 7| 8| 14| 9| 0
^ p will now point to here
1| 2| 6| 7| 3| 4| 8| 5| 6|255| 7| 8| 14| 9| 0
^ p will now point to here