【C语言】二维数组和数组指针

(一)二维数组的定义

类型名 数组名[行数][列数](行数、列数必须是常量表达式)

(二)二维数组的本质

例如:

int arr[5][2] = {
    
    1 ,2, 3, 4, 5, 6, 7, 8, 9, 10};

逻辑图如下:
在这里插入图片描述

  • 实质上是由五个一维数组(一维数组下有两个元素)组成。
  • 存放方式:行优先存放

那我们试想一下三维数组,当然并不建议使用,二维数组基本可以满足我们的编程需求。

三维数组的逻辑图:
实际是由行、列、高组成,比如arr[2][3][3]也可以理解成由两个二维数组arr[3][3]组成。
在这里插入图片描述

(三)使用数组指针访问二维数组

(1)数组指针访问一维数组

在访问二维数组之前我们先回顾下数组指针访问一位数组。

#include <stdio.h>

int main()
{
    
    
	int arr[5];
	int (*s) = &arr;
	return 0;
}

分析:s是指向数组地址的指针,指针大小4字节,若想使用数组指针访问一维数组的下的每一个元素是不可能的,因为s的类型是int[5]*,指向的对象arr类型是int[5] 每次移动操作移动的步长是sizeof(arr) = 4 * 5 = 20字节,而访问arr数组中每一个元素是int类型 四字节,显然是不可能的

(2)数组指针访问二维数组

#include <stdio.h>

int  main()
{
    
    
	int arr[5][2] = {
    
    1 ,2, 3, 4, 5, 6, 7, 8, 9, 10};
	int (*p)[2] = arr; //首元素地址
	//int (*p)[2] = &arr[0]; //首元素地址
	
	//输出arr[1][1]
	printf("%d \n", *(*(p + 1) + 1));	
	printf("%d \n", *(p[1] + 1));
	printf("%d \n", p[1][1]);
}

定义分析:

  • arr是int[5][2]类型,arr对应的地址是二维数组的首元素地址
  • &arr是int[5][2]*类型
  • 数组指针p是int[2]* 的类型, 数组首元素地址&arr[0]也是int[2]*类型

在这里插入图片描述
访问分析:输出arr[1][1] = 4

  • p是一个int[2]*类型的数组指针,指向了二维数组arr的首元素arr[0]的地址,即&arr[0],也可以直接使用arr
    在这里插入图片描述

      通过对比类型可以发现*(*(p + 1) + 1))演变成p[1][1]的过程
    

输出结果:
在这里插入图片描述

(3)数组指针作为函数参数输出二维数组所有元素

在理解了(2)分析的基础上,下面代码就很简单了

  1. 第一种打印方式:
#include <stdio.h>
//传入二维数组的首元素地址&arr[0]或者arr, rows行数,col列数
void ShowArr(int (*p)[2], int rows, int col)
{
    
    
	if(p == NULL) return;
	int i;
	int j;
	for( i = 0; i < rows; i++)
	{
    
    
		for(j = 0; j < col; j++)
		{
    
    
			//printf("%d \n", *(*(p + i) + j));	
			//printf("%d \n", *(p[i] + j));
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
	
}
int main()
{
    
    
	int arr[5][2] = {
    
    1 ,2, 3, 4, 5, 6, 7, 8, 9, 10};
	//ShowArr(arr, 5, 2);
	ShowArr(&arr[0], 5, 2);
	return 0;
}

运行结果1
在这里插入图片描述
2. 第二种打印方式

void ShowArr(int p[][2], int rows, int col)
{
    
    
	if(p == NULL) return;
	int i;
	int j;
	for( i = 0; i < rows; i++)
	{
    
    
		for(j = 0; j < col; j++)
		{
    
    
			//printf("%d \n", *(*(p + i) + j));	
			//printf("%d \n", *(p[i] + j));
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
	
}

分析:
这里的int p[][2]退化成int(*p)[2]数组指针,而不是二级指针更不能直接使用int** p来传递二维数组
结果:
在这里插入图片描述

(4)一道练习题

#include <stdio.h>
int main()
{
    
    
	int arr[5][2] = {
    
    1 ,2, 3, 4, 5, 6, 7, 8, 9, 10};
	int (*p)[2] = &arr[1];  	//p是int[2]*类型
	int* s = arr[1];			//s是int*类型
	
	printf("%d\n", p[1][3]);
	printf("%d\n", s[3]);
	return 0;
}

分析:
在这里插入图片描述

输出结果:
在这里插入图片描述


  1. 在线运行工具https://tool.lu/coderunner/ ↩︎

おすすめ

転載: blog.csdn.net/xiaoxiaoguailou/article/details/121340583