首页 > C语言二维数组名问题

C语言二维数组名问题

#include <stdio.h>
int main(int argc, const char *argv[])
{
	int a[2][3] = {
		{1, 2, 3}, 
		{4, 5, 6}
	}; 
	
	printf("%p\n", a);
	printf("%p\n", *a);
	return 0;
}

打印的结果是,一样的指针.

a究竟是怎么存储的,怎么会出现a和*a是一样的呢?


int a[10]

这里的数组其实是个指针,a就是指向第一个元素,如果那个元素是一个数组的话(多维数组),也就是说a指向一个指针


一个数组类型的变量,所占空间也就是数组中元素所占的空间,没有其它占用。

关键的两点是 C 语言规定:

  1. 除了作为 sizeof 和单目 & 操作符的操作数时,表达式中的数组均转化为指向数组首元素的指针。(也就是常说的:退化)
  2. 操作符 [] 是语法糖,使得 a[n] 等价于 *(a + n)

套用到你的代码里:

  1. aint [2][3] 类型数组,单独出现在表达式中,转化为 int (*)[2][3] 类型,指向数组 a 的首地址。
  2. *aint [3] 类型数组,单独出现在表达式中,转化为 int (*)[3] 类型,指向数组 *a 的首地址。

前面也有说到 *a 其实和 a[0] 等价的,所以 *a 就是第一个子数组,所以其首地址和整个数组的地址是相同。


int a[1][2][3] = {
        1, 2, 3,
        4, 5, 6
    };
    printf("%p\n", a);
    printf("%p\n", *a);
    printf("%p\n", **a);
    printf("%d\n", ***a);
    return 0;

其中a,*a,**a都是一样的. 最后一行打印的是1

写了一个文章来理解这个问题 : http://hit9.github.io/oldblog/blog/C/posts/24.html


cut the crap,看图:

http://instagram.com/p/RJpP5puqv0

之前看的一篇文章:Learning C using GDB,你可以看看 https://www.hackerschool.com/blog/5-l...

#include<stdio.h>

int main(){
    int a[] = {1,2,3};
    printf("a[0]=%d\n", a[0]);
    printf("*(a+0)=%d\n", *(a+0));
    printf("a[1]=%d\n", a[1]);
    printf("*(a+1)=%d\n", *(a+1));
    return 0;                                                             
}

array的index access在C里只是对指针操作的一个语法糖。a[n]完全等价于*(a+n)

回到你的问题。

  1. C语言里int a[10]的话,a是一个指针指向a[0]的指针
  2. C语言里int a[2][3]的话,a[0]是一个指向a[0][0]的指针,a[1]是一个指向a[1][0]的指针

在你的代码里,int a[2][3]

  1. *a指向a[0][0]这个int
  2. a指向a[0] = {1, 2, 3}这个array。只不过在C里面,array的地址就是array第一个元素的地址,所以在这里a = a[0] = a[0][0]
  3. a*int[3]的指针,对其进行+1操作,内存指针往后移动sizeof(int[3])个位置
  4. *aint指针,对其进行+1操作,内存指针往后移动sizeof(int)个位置

你可以运行下面代码测试下

#include<stdio.h>

int main(){
    int a[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };
    printf("%p\n", a);
    printf("%p\n", a+1);
    printf("%p\n", (*a+1));
    return 0;                                                             
}
【热门文章】
【热门文章】