C++预习 二维指针

初步掌握visual studio 2013 中控制台c程序的建立。结合课本讲解指针概念;指针上机练习。讲解动态分配和释放。 malloc/free.

一维指针动态分配和释放练习。

二维指针概念讲解。二维指针动态分配和释放练习。
作业:矩阵乘法
用户输入矩阵1行数、列数,然后提示用户输入各元素;
用户输入矩阵2行数、列数,然后提示用户输入各元素;

输入后计算相乘结果矩阵。

在这次作业中,题目要求用户输入矩阵的行数列数和两个矩阵的各个元素,然后计算两个矩阵相乘的结果并输出。因为数组的大小是用户输入的,是一个动态数组,因此有两种方法:“

(1)     事先定义足够大的矩阵,用户直接输入各个矩阵元素。理论上可行,不过浪费资源;

(2)     用C语言的动态内存分配函数malloc 向系统申请内存并返回给一个int类型的指针,这样能够实现动态数组;

如何用指针表示一个二维数组?一个二维数组可以看出如下表示

a[0][0]

a[0][1]

a[0][2]

a[0][3]

a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[2][0]

a[2][1]

a[2][2]

a[2][3]

我在第一次实验中,a矩阵的每个二维数组元素用a[0]a[1]a[2]三个一维数组元素表示,因此采用了一维指针,即表示成*p[i]+j的形式,即用行指针指向每个行矩阵的首元素,

后面的元素采用+1的形式获得,这样做的优点是难度比较小,但是从程序运行的角度来说,确定了行地址再逐个相加,效率比较低;

在《C语言数值算法大全》的Page18,关于指针与二维数组有如下表示:

 

所以在接下来的实验中,我采用了二维指针的形式,即二维数组的每个元素都可以用二维指针**p[i][j]来进行访问,提高了运行速度。


第一次使用了一维指针

#include<stdio.h>
#include<stdlib.h>
void InputArrayA(int *p1, int m1, int n1);
void InputArrayB(int *p2, int m2, int n2);
void OutputArray(int *p1, int *p2,int m1, int n1, int m2, int n2 );
void main()
{
	int *p1 = NULL;
	int *p2 = NULL;
	int m1, n1, m2, n2;
	printf("请输入矩阵A的行数m1和列数n1\n");
	scanf_s("%d,%d", &m1, &n1); /*用户输入矩阵A的行数m1和列数n1*/
	p1 = (int*)calloc(m1*n1, sizeof(int));/*申请内存*/
	InputArrayA(p1, m1, n1);
	printf("请输入矩阵B的行数m2和列数n2\n");
	scanf_s("%d,%d", &m2, &n2); /*用户输入矩阵B的行数m2和列数n2*/
	p2 = (int*)calloc(m2*n2, sizeof(int));/*申请内存*/
	InputArrayB(p2, m2, n2);
	OutputArray(p1, p2, m1, n1, m2, n2);
	free(p1);
	free(p2);

}
void InputArrayA(int *p1, int m1, int n1)
{
int i,j;
	for (i = 0; i < m1; i++)
	{
		printf("请输入矩阵A第%d行每一个元素\n", i + 1);
		for (j = 0; j < n1; j++)
		{
			scanf_s("%d", &p1[i*n1 + j]);
			//printf("%d\n", p1[i*n1 + j]);
		}
	}
}
void InputArrayB(int *p2, int m2, int n2)
{
	int i, j;
	for (i = 0; i < m2; i++)
	{
		printf("请输入矩阵B第%d行每一个元素\n", i + 1);
		for (j = 0; j < n2; j++)
		{
			scanf_s("%d", &p2[i*n2 + j]);
			//printf("%d\n", p2[i*n2 + j]);
		}
	}
}
void OutputArray(int *p1, int *p2, int m1, int n1, int m2, int n2)
{
	int s, ai, aj, bi, bj;
	printf("运算结果如下:\n");
	for (ai = 0; ai < m1; ai++)
	{
		for (bj = 0; bj < n2; bj++)
		{
			s = 0;
			aj = 0;
			for (bi = 0; bi < m2;bi++)
			{
				s = s + p1[ai*n1 + aj]*p2[bi*n2 + bj];
				//printf("%d", p1[ai] + aj);
				//printf("%d", p2[bi] + bj);
				aj++;
			}
			printf("%d", s);
			printf("   ");
		}
		printf("\n");
	}
}




第二次使用了二维指针

#include<stdio.h>
#include<stdlib.h>
void InputArrayA(int **p1, int m1, int n1);
void InputArrayB(int **p2, int m2, int n2);
void OutputArray(int **p1, int **p2, int m1, int n1, int m2, int n2);
void main()
{
	int m1, n1, m2, n2;
	printf("请输入矩阵A的行数m1和列数n1\n");
	scanf_s("%d,%d", &m1, &n1); /*用户输入矩阵A的行数m1和列数n1*/
	int**p1 = (int**)malloc(m1 * sizeof(int*));/*申请内存*/
	for (int i = 0; i < n1; ++i)
	{
		*(p1 + i) = (int *)malloc(n1 * sizeof(int));
	}

	InputArrayA(p1, m1, n1);
	printf("请输入矩阵B的行数m2和列数n2\n");
	scanf_s("%d,%d", &m2, &n2); /*用户输入矩阵B的行数m2和列数n2*/
	int**p2 = (int**)malloc(m2 * sizeof(int*));/*申请内存*/
	for (int i = 0; i < n2; ++i)
	{
		*(p2 + i) = (int *)malloc(n2 * sizeof(int));
	}
	InputArrayB(p2, m2, n2);
	OutputArray(p1, p2, m1, n1, m2, n2);
	free(p1);
	free(p2);

}
void InputArrayA(int **p1, int m1, int n1)
{
	int i, j;
	for (i = 0; i < m1; i++)
	{
		printf("请输入矩阵A第%d行每一个元素\n", i + 1);
		for (j = 0; j < n1; j++)
		{
			scanf_s("%d", p1[i] + j);
			//printf("%d\n", p1[i*n1 + j]);
		}
	}
}
void InputArrayB(int **p2, int m2, int n2)
{
	int i, j;
	for (i = 0; i < m2; i++)
	{
		printf("请输入矩阵B第%d行每一个元素\n", i + 1);
		for (j = 0; j < n2; j++)
		{
			scanf_s("%d", p2[i] + j);
			//printf("%d\n", p2[i*n2 + j]);
		}
	}
}
void OutputArray(int **p1, int **p2, int m1, int n1, int m2, int n2)
{
	int s, ai, aj, bi, bj;
	printf("运算结果如下:\n");
	for (ai = 0; ai < m1; ai++)
	{
		for (bj = 0; bj < n2; bj++)
		{
			s = 0;
			aj = 0;
			for (bi = 0; bi < m2; bi++)
			{
				s = s + p1[ai][aj] * p2[bi][bj];
				aj++;
			}

			printf("%d", s);
			printf("   ");
		}
		printf("\n");
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值