C 复杂的字符串和数组声明
我正在学习C语言的基础知识,对字符串和数组感到困惑C 复杂的字符串和数组声明,c,arrays,C,Arrays,我正在学习C语言的基础知识,对字符串和数组感到困惑 #include<stdio.h> int main() { char arr[2][4] = {1,2,3,4,5,6,7,8}; printf("%u %u\n",arr,arr+1); printf("%d",*(*(arr+1)+2) ); return 0; } 此处,arr和&arr不应被视为相同(尽管它们打印相同的值,但此信息的含义完全不
#include<stdio.h>
int main()
{
char arr[2][4] = {1,2,3,4,5,6,7,8};
printf("%u %u\n",arr,arr+1);
printf("%d",*(*(arr+1)+2) );
return 0;
}
此处,arr和&arr不应被视为相同(尽管它们打印相同的值,但此信息的含义完全不同)。这就是为什么arr+1和&arr+1也不相同的原因&arr给出了一个数据类型的地址,该数据类型是一个包含7个整数的容器,这就是为什么&arr+1会转到后面的数组类型,该数组类型也是一个包含7个整数的容器。
所以
对于二维阵列,概念相同:
arr[2][4]={1,2,3,4,5,6,7,8};
现在,arr
这里还有一个指针,指向数组中的各个元素,因此arr
和arr+1
是其连续元素的地址(这些元素是{1,2,3,4}
和{5,6,7,8}
)_
同样地,&arr
和&arr+1
给出了两个具有2x4=8个元素的数组的基址,因此&arr
和&arr+1
是两个大小相似的数组的地址。
所以
现在我们可以看到,在二维数组中,每个元素都有两个相关的地址
1) ar
r(在两个内部数组中选择哪个元素)2)
*arr
(给出特定元素(数组)中的哪个元素)
因此,如果我们想要获得数据,我们需要取消引用两次
arr=5796(first array), *arr=5796(first element address), **arr = 1 (1st element)
arr+1=5812(second array), *(arr+1) = 5812(first element address), *(*(arr+1))=5(first element)
arr=5796,*arr=5796, *arr+1=5796+1(second element), *(*arr+1)=2 (second element)
现在介绍数组的语法:
*arr = arr[0]
**arr = arr[0][0]
*arr+1 = arr[0]+1
**arr+1 = arr[0][0]+1
*(*arr+1) = *(arr[0]+1) = arr[0][1]
*(*(arr+1)+1) = *(arr[1]+1) = arr[1][1]
还有其他一些写入数组的方法
3[arr[1]] = arr[1][3]
-3[arr[1]] = -arr[1][3]
*(1[arr]+2) = *(arr[1]+2) = arr[1][2]
这个概念也可以扩展到三维数组,但这是每个初学者应该了解的最低要求。如果我在概念上或语法上有任何错误,请纠正我。因为
arr
是一个二维数组
*(*(arr+1)+2))
相当于arr[1][2]
,因为arr
是一个二维数组
*(*(arr+1)+2))
相当于arr[1][2]
arr+1
和&arr+1
在此上下文中是完全相同的,因为arr
是一个数组,隐式降级为指针,或显式获取其地址,这相当于相同的事情
如您所知,向数组中添加1将转到其第二个元素。而arr
是一个数组数组,因此它的第二个元素是第二个子数组
如果您想要第一个子数组的第二个元素,请尝试
arr[0]+1
,这相当于&arr[0][1]
arr+1
和&arr+1
在这种上下文中是完全相同的,因为arr
是一个隐式降级为指针的数组,或者显式获取其地址,这是一回事
printf("%d",*(*(arr+1)+2) );
如您所知,向数组中添加1将转到其第二个元素。而arr
是一个数组数组,因此它的第二个元素是第二个子数组
如果需要第一个子数组的第二个元素,请尝试arr[0]+1
,这相当于&arr[0][1]
printf("%d",*(*(arr+1)+2) );
把它分成两个陈述
*(arr+1) means arr[1]
像这样
*(arr[1] + 2) means arr[1][2]
把它分成两个陈述
*(arr+1) means arr[1]
像这样
*(arr[1] + 2) means arr[1][2]
当访问
char arr[ROW\u COUNT][COLUMN\u COUNT]
时,arr[ROW][col]
相当于address\u of_arr[col+(ROW*ROW\u COUNT)]
。一旦你意识到这一点,一切都会变得更有意义
arr
和arr+1
不应该相邻,应该有4个字节的差异。你到底看到了什么结果?当访问char arr[ROW\u COUNT][COLUMN\u COUNT]
时,arr[ROW][col col]
相当于arr[col+(ROW*ROW\u COUNT)]的地址。一旦你意识到这一点,一切都会变得更有意义
arr
和arr+1
不应该相邻,应该有4个字节的差异。您到底看到了什么结果?您使用的数组是字符
,因此每个字段占用1个字节arr
和arr+1
将不在相邻位置
我想当你检查arr和arr+1的输出时,差是4,所以你要记住整数,告诉它在相邻的位置
&arr[0]
=第一行第一个元素的地址
&arr[1]
=第二行第一个元素的地址
将数据类型从char
更改为int
,您将了解更多信息
检查以下程序的输出
#include<stdio.h>
int main()
{
char arr[2][4] = { 1,2,3,4,
5,6,7,8 };
printf("%u\n", &arr[0][0]);
printf("%u\n", &arr[0][4]);
printf("%u\n", &arr[1][0]);
printf("%u\n", &arr[1][4]);
printf("%d\n",*(*(arr+1)+2) ); // equal to arr[1][2]
printf("%d\n", *(arr[1] + 2) );
printf("%d\n", arr[1][2]);
return 0;
}
上面的程序将给出一些警告,将%u替换为%p。您使用的数组是字符
,因此每个字段占用1个字节arr
和arr+1
将不在相邻位置
我想当你检查arr和arr+1的输出时,差是4,所以你要记住整数,告诉它在相邻的位置
&arr[0]
=第一行第一个元素的地址
&arr[1]
=第二行第一个元素的地址
将数据类型从char
更改为int
,您将了解更多信息
检查以下程序的输出
#include<stdio.h>
int main()
{
char arr[2][4] = { 1,2,3,4,
5,6,7,8 };
printf("%u\n", &arr[0][0]);
printf("%u\n", &arr[0][4]);
printf("%u\n", &arr[1][0]);
printf("%u\n", &arr[1][4]);
printf("%d\n",*(*(arr+1)+2) ); // equal to arr[1][2]
printf("%d\n", *(arr[1] + 2) );
printf("%d\n", arr[1][2]);
return 0;
}
上面的程序将给出一些警告,用%p替换%u。声明
char arr[2][4] = {1,2,3,4,5,6,7,8};
意味着
char arr[2][4] = {
{1,2,3,4}, // row 0
{5,6,7,8} // row 1
};
将数组名arr
传递给printf
意味着它将衰减为指向数组arr[2]
的第一个元素(行0
)的指针,类型为int(*)[4]
(将2D数组视为2个元素的1D数组,每个元素都是4个元素的数组)
我认为要转到第二个数组,它应该是&arr+1
arr+1
指向数组arr[2]
的第二个元素(行1
)(而不是数组arr[2][4]
的第二个元素)。通过执行arr+1
,您不仅仅是将1
添加到指针arr
(衰减后),而是添加存储行中元素所需的总字节数。
让我们理解