二维数组与指针(杰哥强化版)

二维数组定义
例子:int a[2][3];
在谭浩强的《C语言程序设计》书中为描述简便,将下标志理解为两行三列,但实际上站在编译器的角度,世界上并不存在多维数组,所有的数组都是一维的,也不存在行列的行列。我们只是不想将此数组成为“由两个整型数组的数组”,才简称为二维数组。

内存是严格线性的!!!
在这里插入图片描述

注意左边的示意图,数组a[2]的两个元素是两个类型是int[3]小数组,这是一嵌套了数组的数组,实际内存部署如右图所示,一个关键的地方,每个元素之间都是紧密相连的,只能无间隙,左边那个红色粗体的只是个示意图。

对于数组a而言,其首元素是a[0],首元素的首元素是a[0][0]。

定义中文翻译:
int a[2][3];
定义了一个二维数组,数组名叫a,这个二维数组是由2个一维数组组成的,且每个一维数组是由3个int元素组成的数据。

拓展:
int b[3][4][5];
定义一个三维数组,数组名叫b,这个三维数组是由3个二维数组组成,且每个二维数组是由4个一维数组组成,且每个一维数组由5个int元素组成的数据。

二维数组的定义
最基本的数据类型 数组名[ 一维数组的个数][一维数组中元素的个数];
例子:int double_arr[3][4];

三维数组的定义:
最基本的数据类型 数组名[二维数组的个数][ 一维数组的个数][一维数组中元素的个数]
例子:int tri_arr[3][4][5];

一、赋初值
1、常规赋值
int double_arr[3][4] = {11,12,13,14,22,23,24,25,34,35,36,37};
int double_arr[3][4] = {{11,12,13,14},{22,23,24,25},{34,35,36,37}};

只要对部分元素进行赋值,其他元素值自动为0。
①int double_arr[3][4] = {11,12,13,14,22,23,24,25,34,35,36,37};
②int double_arr[3][4] = {{11,12},{22,23,24,25},{34,35,36,37}};
①和②是不同的!!!

①的等价写法
int double_arr[3][4] = {11,12,22,23,24,25,34,35,36,37,0,0};

②的等价写法
int double_arr[3][4] = {{11,12,0,0},{22,23,24,25},{34,35,36,37}};

整个数组清空:
int double_arr[3][4] ={0};

2、缺省元素个数定义法(二维数组的元素是一维数组,所以缺省的是一维数组的个数)
Int arr[ ] = {11,22,33};
int double_arr [ ] [4] = {11,22,33,44,55,66,77,88};
等价写法int double_arr [2] [4] = {{11,22,33,44,},{55,66,77,88}};

int double_arr [ ] [4] = {11,22,33,44,55,66,77,88,99};
等价写法int double_arr [3] [4] = {{11,22,33,44},{55,66,77,88},{99,0,0,0}};

二、重点
1、一维数组:
Int arr[3];
一维数组的名字arr,通常情况下表示首元素的地址 arr ==== &arr[0]

例外:
①&arr 表示整个一维数组的地址
②sizeof(arr) 得到的整个一维数组的大小

2、二维数组
Int arr[3][4];

二维数组的数组名arr通常情况下表示第一个一维数组的地址。
arr == &arr[0]

指针数组和数组指针
int p[2]是指针数组:[]的优先级比高,因此p先和[]结合,所以这是个数组

int (p)[2]是数组指针:()的优先级最高,因此p先和结合。

杰哥说看有没有小括号,小括号优先级最高,有小括号的一定是指针

在这里插入图片描述

(指针==地址)
&arr[0]的地址类型是 int (*)[4]类型 整个一维数组的地址。

&arr 表示整个二维数组的地址。
Sizeof(arr)得到的是整个二位数组的大小。

Int arr[3][4];
该二维数组是由3个一维数组组成,这3个一维数组的名字依次是arr[0] arr[1] arr[2]

其中
arr[0] == &arr[0][0]
arr[1] == &arr[1][0]
arr[2] == &arr[2][0]
都是int*地址。

对于数组a而言,首元素是a[0],首元素的首元素是a[0][0]。请你定义三个指针p1,p2,p3分别指向他们
在这里插入图片描述

#include <stdio.h>

//数组名是数组第一个元素的地址,所以a==&a[0],a[0]==&a[0][0]
指针数组和数组指针,
int main()
{
	int a[3][4]={0};
	int (*p1)[3][4]=&a;//数组指针p1指向整个数组a 
	int (*p2)[4]=a;//&a[0]数组指针p2指向数组第一个元素
	int *p3=a[0];//&a[0][0]指针p3指向数组第一个元素的第一个元素
	
	printf("p1:%p\r\n",p1);
	printf("p2:%p\r\n",p2);
	printf("p3:%p\r\n",p3);
	
//指针偏移看数据类型
	printf("p1+1:%p\r\n",p1+1);//p1+3*4*sizeof(int),p1是int(*)[3][4]型,每次+1是加上一个int(*)[3][4]
	printf("p2+1:%p\r\n",p2+1);//p2+4*sizeof(int),p2是int(*)[4]型,每次+1是加上一个int(*)[4]
	printf("p3+1:%p\r\n",p3+1);//p3+1*sizeof(int),p3是int*型,每次+1是加上一个(int*)

	return 0;
}

备注:杰哥看到的话要我删我一定删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值