Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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 二维数组名第一个元素_C_Arrays_Multidimensional Array - Fatal编程技术网

C 二维数组名第一个元素

C 二维数组名第一个元素,c,arrays,multidimensional-array,C,Arrays,Multidimensional Array,每天一小时的C编程有这样一句话: 与一维数组一样,多维数组的名称是指向第一个数组元素的指针 #包括 int m[2][4]; int main(){ printf(“%p\n”,m);//1 printf(“%p\n”&(m[0]);//2 printf(“%p\n”,m[0]);//3 printf(“%p\n”,&m[0][0]);//4 } 这将为所有语句打印相同的值。根据引文,1==2和3==4是有意义的。但我不明白2==3是怎么回事。m[0]的地址怎么可能与m[0]相同?第一个维度将

每天一小时的C编程有这样一句话:


与一维数组一样,多维数组的名称是指向第一个数组元素的指针

#包括
int m[2][4];
int main(){
printf(“%p\n”,m);//1
printf(“%p\n”&(m[0]);//2
printf(“%p\n”,m[0]);//3
printf(“%p\n”,&m[0][0]);//4
}

这将为所有语句打印相同的值。根据引文,1==2和3==4是有意义的。但我不明白2==3是怎么回事。
m[0]
的地址怎么可能与
m[0]
相同?

第一个维度将存储子阵列(行)的地址

例如,您有
m[2][4] 
,因此
m[0]
计算包含
m[0]中元素的第一行的地址[0]
m[0][3] 
m[1]
的计算结果是第二行的地址包含
m[1]中的元素[0]
m[1][3] 

如果您尝试打印
m[0]
m[1]
,您将看到地址差异是相隔
m[0]
字节的行的总大小。

当分配二维(或任意维)数组时,它只会占用其元素的内存。(内存不会分配给数组名或任何其他数组元素,如
m[0]
m[1]
,在您的情况下,它们的作用类似于常量指针)

因为不会有任何物理内存分配给这些(实际上甚至不需要),所以在尝试打印这些时,您将获得相同的地址。在您的情况下, 由于它是一个二维数组,因为
m
指向
m[0]
,而
m[0][0]
又指向
m[0]
,所有这些数组的获取地址将给出相同的值(同样对于
m[1]
m[1][0]

**为了更好地理解,请参见此(如果您打印这些内容,将是这样的)

*
value
是m[0][0]的值

这里,,
m
m[0]
的作用类似于指针,但不是物理实现的(不占用内存),编译器处理如何处理这些指针

*虽然我已经展示了
0x100
包含
0x100
对于
m
m[0]
0x100
实际上包含
m[0][0]
的数据/值,但是如果您执行任何操作,编译器就是这样处理它们的

**正因为如此,
int*p=malloc(n*sizeof(int))这是可能的,代码<>代码>代码占用内存,指向数组的起始地址。如果考虑<代码> P<代码>代码> int const *p/代码>,可以将其视为一个没有动态分配的正常数组。

数组只包含数据,不包含任何其他内容。此数据有地址。它从哪里开始-这是第一个元素的地址

“多维数组的名称是指向第一个数组元素的指针”过于简化,并不正确。数组不是指针,指针也不是数组

但是,无论何时在表达式中使用数组(任何维度)的名称,都会生成指向数组第一个元素的临时指针。这通常被称为“数组衰减为指针”

现在,这些行之间唯一不同的是指针的类型:

  • int[2][4]
    类型的数组衰减为指向第一个元素的指针。2D数组中的第一个元素是
    int[4]
    类型的1D数组。指向此类数组的指针是数组指针,
    int(*)[4]

  • &m[0]
    给出了第一个元素的地址,即第一个1D数组的地址。因此这完全等同于1)

  • m[0]
    给出第一个元素,仍然是1D数组。它衰减为指向其第一个元素的指针。
    int[4]
    的第一个元素是
    int
    ,因此我们得到一个指向该元素的指针,即
    int*

  • &m[0][0]
    给出指向第一个数组的第一个元素的指针,即
    int*
    。相当于3)

  • 所有这些指针类型都将具有相同的地址,这仅仅是因为2D数组从其第一项1D数组的相同地址开始。它的起始地址与它的第一个项相同,即第一个整数


    各种不同的指针类型只是高级语言语法。这些类型在机器代码中并不是持久存在的,在机器代码中,所有的东西都是原始地址。

    因为,这就是它的实现方式,也因为它的工作原理。
    int*p=malloc(n*sizeof(int))。尝试打印
    &m
    ,也会产生相同的结果。因为对于数组的情况,所有这些都没有实际实现,也不占用内存,但仍然可以用作指向数组(或地址)的指针:转换说明符
    %p
    仅为
    void
    -指针定义,因此代码应该类似于
    printf(“%p\n”,(void*)m)。对
    printf()
    的其他三个调用也是如此。否则将调用未定义的行为。亲爱的上帝,这个问题已经以多少种方式提出了?“与一维数组一样,多维数组的名称是指向第一个数组元素的指针。”-->否。数组不是指针。在选定的情况下,数组转换为第一个元素的指针,但是
    m
    仍然是一个数组。很好。对于另一个错误:“m[0]存储第一行的地址”,它实际上不存储它。发生的情况称为
    m[0]
    “衰减到”第一行的地址。我同意值m[0]不是从存储器读取的,而是在引用时计算出来的
    #include <stdio.h>
    
    int m[2][4];
    
    int main() {
        printf("%p\n", m);        // 1
        printf("%p\n", &(m[0]));  // 2
        printf("%p\n", m[0]);     // 3
        printf("%p\n", &m[0][0]); // 4
    }
    
          _____         _____         _____
         |0x100|  -->  |0x100|  -->  |value|
    0x100|_____|  0x100|_____|  0x100|_____|
           m            m[0]         m[0][0]