Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 多阵列和多阵列[0]和&;多数组[0]相同吗?_C_Multidimensional Array - Fatal编程技术网

C 多阵列和多阵列[0]和&;多数组[0]相同吗?

C 多阵列和多阵列[0]和&;多数组[0]相同吗?,c,multidimensional-array,C,Multidimensional Array,在第6行,而不是在多数组[0]中,当我编写多数组时,程序仍然可以工作。我不明白为什么。我之前认为multiArray是指向multiArray[0]的指针,它是指向multiArray[0][0]的指针。所以multiArray本身就是指向指针的指针。multiArray[0]是指向4元素整数数组的指针。因此,似乎multiArray和multiArray[0]必须是不同的。但在下面的代码中,这两种方法都有效。我编写的Print函数需要一个指向4元素int数组的指针。因此,只有multiArra

在第6行,而不是在多数组[0]中,当我编写多数组时,程序仍然可以工作。我不明白为什么。我之前认为multiArray是指向multiArray[0]的指针,它是指向multiArray[0][0]的指针。所以multiArray本身就是指向指针的指针。multiArray[0]是指向4元素整数数组的指针。因此,似乎multiArray和multiArray[0]必须是不同的。但在下面的代码中,这两种方法都有效。我编写的Print函数需要一个指向4元素int数组的指针。因此,只有multiArray[0]必须工作,而multiArray不能工作。但两者都有效。我不明白

#include <stdio.h>

void printArr(int(*ptr)[4]);

int i, k;

int main(void){

int multiArray[3][4] = { { 1, 5, 2, 4 }, { 0, 6, 3, 14 }, { 132, 4, 22, 5 } };

int(*point)[4] = multiArray[0];

for (k = 0; k < 3; k++)
{  
    printArr(point++);

}

getchar();

}

void printArr(int(*ptr)[4]){

int *temp = (int *)ptr;

for (i = 0; i < 4; i++)
{
    printf("%d ", *temp);
    temp++;
}

puts("\n");
}
#包括
无效打印阵列(int(*ptr)[4]);
int i,k;
内部主(空){
int多数组[3][4]={{1,5,2,4},{0,6,3,14},{132,4,22,5};
int(*点)[4]=多数组[0];
对于(k=0;k<3;k++)
{  
printArr(point++);
}
getchar();
}
无效打印阵列(int(*ptr)[4]){
int*temp=(int*)ptr;
对于(i=0;i<4;i++)
{
printf(“%d”,*temp);
temp++;
}
卖出(“\n”);
}
int(*点)[4]=多数组[0]

这是因为
multiArray[0]
multiArray
都指向相同的地址,即数组的第一个元素的地址:
multiArray[0][0]

但是在这种情况下,您可能会从编译器得到警告,因为
multiArray[0]
的类型是
int*
,而
点的类型是
int[4]*
(指向
4
整数数组的指针)。

int(*point)[4]=multiArray[0]

这是因为
multiArray[0]
multiArray
都指向相同的地址,即数组的第一个元素的地址:
multiArray[0][0]


但是在这种情况下,您可能会从编译器得到警告,因为
多数组[0]
的类型是
int*
,而
点的类型是
int[4]*
(指向
4
整数数组的指针)。

多维数组
var\u t arr[size\y][size\x]
提供以方便的方式声明和访问数组元素(内存)的方法。但所有多维数组都是内部连续的内存块

您可以说
arr[y][x]=arr[y*cols+x]

就指针级别而言,指针
multiArray
multiArray[0]
是相同的,它们是
int*
——尽管arr的形式类型是
int(*)[2]
。使用该类型可以利用所有指针机制(指针上的++会将地址移动8个字节,而不是4个字节)

试试这个:

void t1(int* param)
{
  printf("t1: %d\n", *param);
}

void t2(int** param)
{
  printf("t2: %d\n", **param);
}

int main(void) {
  int arr[2][2] = { { 1, 2 } , { 3, 4 } };
  t1(arr);    // works ok
  t1(arr[0]); // works ok
  t2(arr);    // seg fault
  t2(arr[0]);
}

多维数组
var\u t arr[size\u y][size\u x]
提供了以一种方便的方式声明和访问数组元素(内存)的方法。但所有多维数组都是内部连续的内存块

您可以说
arr[y][x]=arr[y*cols+x]

就指针级别而言,指针
multiArray
multiArray[0]
是相同的,它们是
int*
——尽管arr的形式类型是
int(*)[2]
。使用该类型可以利用所有指针机制(指针上的++会将地址移动8个字节,而不是4个字节)

试试这个:

void t1(int* param)
{
  printf("t1: %d\n", *param);
}

void t2(int** param)
{
  printf("t2: %d\n", **param);
}

int main(void) {
  int arr[2][2] = { { 1, 2 } , { 3, 4 } };
  t1(arr);    // works ok
  t1(arr[0]); // works ok
  t2(arr);    // seg fault
  t2(arr[0]);
}
还有人写道“多维数组是一维数组的语法糖”

这有点像是说
int
只是
无符号字符[4]
的语法糖。您可以去掉像
4+5
这样的表达式,并通过操作4字节的数组获得相同的结果

你甚至可以说C只是通用图灵机脚本的语法糖,如果你想进一步理解这个概念的话

事实上,多维数组是C中类型系统的一部分,它们具有与之相关联的语法。剥猫皮的方法不止一种

接下来,C排列我们称之为多维数组的方式是:“数组只能有一个维度,但元素类型本身可能是另一个数组”。我们说“多维数组”是为了方便起见,但语法和类型系统实际上反映了数组的一维性质

因此,
int multiArray[3][4]
是一个由3个元素组成的数组。这些元素中的每一个都是由4个
整数组成的数组

在内存中,数组的元素是连续存储的——不管元素类型是什么。因此,内存布局是一个4
int
数组,紧接着是另一个4
int
数组,最后是另一个4
int
数组

内存中有12个连续的
int
,在C类型系统中,它们被分成3组,每组4个

您会注意到,12组中的第一个
int
,也是第一组4组中的第一个
int
。这就是为什么我们发现,如果我们问“第一个int的内存位置是什么?”,“第一组4个int的内存位置是什么?”,以及“整个12个int组的内存位置是什么?”,我们每次都会得到相同的答案。(在C语言中,多字节对象的内存位置被视为从其第一个字节的位置开始)

现在,我们来谈谈指针语法和表示法。在C语言中,指针告诉您在内存中可以找到对象的位置。这有两个方面:对象的内存位置和对象的类型。(对象的大小是该类型的必然结果)

有些演讲只关注其中的第一个,他们会说“指针只是一个数字”。但这意味着忘记了类型信息,它是指针的关键部分

使用
%p
打印指针时,会丢失类型信息。您只是将第一个字节的位置放在内存中。所以它们看起来都一样,尽管三个指针指向不同大小的对象