初步掌握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");
}
}