多维数组的本质和指针数组

 


 

1 多维数组本质

多维数组名的本质是指向一维数组的指针

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void make_array(int(*a)[5], int row, int col)
//void make_array(int a[3][5])
{
	int i = 0;
	int j = 0;

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			a[i][j] = i + j;
		}
	}
}

void print_array(int(*a)[5], int row, int col)
//void print_array(int a[3][5]) // print_array:a[3][5]  = main:a[3][5]
{
	int i = 0;
	int j = 0;

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			printf("a[%d][%d]: %d  ", i, j, a[i][j]);

		}
		printf("\n");
	}
	printf("\n");
}

typedef int(ARRAY_5_6)[5][6];

void make_array2(ARRAY_5_6 *b, int row, int col, int height)
//void make_array2(int b[3][5][6], int row, int col, int height)
//void make_array2(int(*b)[5][6], int row, int col, int height)
{
	int i = 0, j = 0, k = 0;

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			for (k = 0; k < height; k++) {
				//b[i][j][k] = i + j + k;
				*(*(*(b + i) + j) + k) = i + j + k;
			}
		}
	}
}

void print_array2(ARRAY_5_6 *b, int row, int col, int height)
{
	int i = 0, j = 0, k = 0;

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			for (k = 0; k < height; k++) {
				printf("b[%d][%d][%d]:%d  ", i, j, k, b[i][j][k]);
			}
			printf("\n");
		}
		printf("\n");
	}
	printf("\n");
}

void print_array3(int *p, int num)
{
	int i = 0;
	for (i = 0; i < num; i++) {
		printf("%d ", p[i]);
	}
	printf("\n");
}



int main(void)
{
	int a[3][5]; //数组无论是几维数组, 都是一块连续的内存空间

	int b[3][5][6];

	int(*pArray)[5];
	pArray = a;
	make_array(pArray, 3, 5);
	print_array(pArray, 3, 5);
	printf("--11111111111111111----\n");

	make_array(a, 3, 5);
	print_array(a, 3, 5);

	printf("------\n");

	make_array2(b, 3, 5, 6);
	print_array2(b, 3, 5, 6);
	printf("------\n");


	print_array3((int *)a, 15);

	return 0;
}

2【】---》 *

【】的优先级是从左到右,a[i][j] 先是工a[i]

3 多维数组的退化问题

 

//void make_array(int(*a)[5], int row, int col)
void make_array(int a[][5], int row, int col)
//void make_array(int a[3][5], int row, int col)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < row; i++) {
		for (j = 0; j < col; j++) {
			a[i][j] = i + j;
		}
	}
}

 

4 多维数组的内存存储是线性的

 

我们为了好理解这样认为

 

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void printArray(int* p, int num)
{
	for (size_t i = 0; i < num; i++)
	{
		printf("%d\n", p[i]);
	}
}

int main(void)
{
	int a[3][5] = { {1, 2, 3, 4, 5}, { 1, 2, 3, 4, 5 }, { 1, 2, 3, 4, 5 } }; 
	//数组无论是几维数组, 都是一块连续的内存空间
	// a[i][j]
	int* p = *(a + 0) ;

	for (size_t i = 0; i < 15; i++)
	{
		printf("%d\n", *(p++));
	}

	printf("***************************\n");


	int* pn = &*(*(a + 0) + 0);

	for (size_t i = 0; i < 15; i++)
	{
		printf("%d\n", pn[i]);
	}

	printf("***************************\n");
	printArray(*a, 15);
	return 0;
}

把二维数组当一维数组来打印就可以证明是线性存储的。

 

#include <stdio.h>

void pr(int *ar, int num)
{
	for (int i=0; i<num; i++)
	{
		printf("%d\n",ar[i]);
	}
}

int main()
{
    int a[3][5] = {0};
	for (int i = 0; i<3; i++)
	{
		for (int j = 0; j<5; j++)
		{
			a[i][j] = i+j;
		}
	}
	pr((int *)a, 15);
return 0;
}

5 为什么会这样

 

6 指针数组的应用

 

 

 

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
#define	NUM(a)	(sizeof(a)/sizeof(*a))
char*	keywords[]	=	{
"while",
"case",
"static",
"do"
};
int	searcheKeyTable(const char*	table[],	const int	size,
const char*	key,	int	*pos);
*/


int	searcheKeyTable(const char*	table[], const int	size, const char*	key, int	*pos)//table = keywords
{
	int i = 0;
	int ret = 0;

	if (table == NULL || key == NULL || pos == NULL) {
		return -1;
	}

	//(sizeof(table)/sizeof(*table)) 间接证明数组做函数参数的退化
	for (i = 0; i < size; i++) {
		if (strcmp(table[i], key) == 0) {
			//找到了匹配的key
			*pos = i;
			ret = i;
			break;
		}
	}

	if (i == size) {
		//没找到key
		*pos = -1;
		ret = -1;
	}

	return ret;
}


int main(void)
{
	char*	keywords[] = {  // char* keywords[4]  (char*)[4]  ==> 16
		"while",
		"case",
		"static",
		"do",
		NULL
	};

	int i = 0;
	int num = 0;
	int pos = 0;

	/*
	num = sizeof(keywords) / sizeof(*keywords); //16 / 4 = 4;

	searcheKeyTable(keywords, num, "do", &pos);

	if (pos < 0) {
		printf("未找到 while \n");
		return -1;
	}
	printf("do 在 第%d 个位置\n", pos+1);
	*/
	for (i = 0; keywords[i] != NULL; i++) {
		printf("%s\n", keywords[i]);
	}


	return 0;
}

 

7 main的命令行参数

main(int argc, char** argv) 参数的含义

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[], char **env)
{
	int i = 0;

	printf(" ------- argv -------\n");
	for (i = 0; i < argc; i++) {
		printf("%s\n", argv[i]);
	}
	printf(" ------- ---- -------\n");

	printf(" ------ evn ------\n");

	for (i = 0; env[i] != NULL; i++) {
		printf("evn[%d]: %s\n",i,  env[i]);
	}
	printf(" ------- ---- -------\n");


	return 0;
}

知道是在怎样的框架下工作,谁调用谁,谁分配了空间。

 

8 数组的组我约束能力

三种情况一个意思

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值