对于第一次接触指针的小伙伴而言,指针的存在似乎过于抽象,我们不知道在什么时候使用指针,对它的意义也没有一个大体的了解,下面笔者将用一道题目来解释什么是指针,什么时候用指针,以及存在的意义。
7-77 方阵循环右移
本题要求编写程序,将给定n×n方阵中的每个元素循环向右移m个位置,即将第0、1、⋯、n−1列变换为第n−m、n−m+1、⋯、n−1、0、1、⋯、n−m−1列。
输入格式:
输入第一行给出两个正整数m和n(1≤n≤6)。接下来一共n行,每行n个整数,表示一个n阶的方阵。
输出格式:
按照输入格式输出移动后的方阵:即输出n行,每行n个整数,每个整数后输出一个空格。
输入样例:
2 3
1 2 3
4 5 6
7 8 9
输出样例:
2 3 1
5 6 4
8 9 7
代码长度限制
16 KB
时间限制
400 ms
这样一道题目,我们第一反应是用模拟的思路,按照题目所给一步步做下去,毫无疑问这是可以实现的。
可以整理模拟思路如下:
核心(解决重复问题-- for循环或while)
要移动m次 --------》 m次移动 一次
要移动n列 ---------》 n次移动 一次
如此只需要实现n个数的向后移动即可
我们只需要保存第n个数 n-1个数往后走一位 再给第一个数赋值即可
模拟思路叙述完成,下面来看看指针的实现形式。
为什么可以想到指针呢?因为我们对数据本身没有进行任何处理,由此可以想到我们进行的模拟思路操作本质上浪费了效率(动了我们不需要动的东西)
所以想到了指针,指针就是指向,要实现移动命令,我们不需要真实移动数据本身,我们需要的仅仅是改变指向。
i=0; t=(10*m-n) % m;
for (j=1;j<=m;j++)
{
c[i]=t;
i++;
t=(t+1) % m;
}
这里我们把c数组作为指针 这样原本的第i列变成指向第c[i]的存在
我们不再需要一次次往后走(从中我们发现指针便于处理)
直接让 t=(10*m-n) % m; 就可以一步到位(这里10*m的作用是取正)
而与之对应的,就是输出的时候,我们需要输出 a[i][c[j]]
到这里为止,我们就完成了这道题目的指针思路了,简单明了快捷。
程序如下
#include<stdio.h>
int main()
{
int i,j,k,n,m,t;
int a[10][10];
int c[10];
scanf("%d%d",&n,&m);
for (i=0;i<=m-1;i++)
for (j=0;j<=m-1;j++)
scanf("%d",&a[i][j]);
i=0; t=(10*m-n) % m;
for (j=1;j<=m;j++)
{
c[i]=t;
i++;
t=(t+1) % m;
}
for (i=0;i<=m-1;i++)
{
for (j=0;j<=m-1;j++)
printf("%d ",a[i][c[j]]);
printf("\n");
}
return 0;
}
整理一下思路,指针便于处理,往往适用于原有数据不进行改变的时候(相当于只对指针进行操作即可)
笔者饿了,收笔。