1.程序要求:实现对5个数(a[0]~a[4],数组元素从键盘读入)进行从大到小起泡法排序。输入第一组数据:1 2 3 4 5;输入第二组数据:3 5 4 1 2;验证程序的正确性。
#include <stdio.h>
int main()
{
int a[5],i,j,temp;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
for(i=0;i<5-1;i++)
{
for(j=0;j<5-1-i;j++)
{
if(a[j]<a[j+1])
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(i=0;i<5;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
2.程序要求:实现三阶方阵转置,并打印转置后的方阵。
测试主函数为:
int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
...//实现三阶方阵a的转置,并打印出来
return 0;}
5.用指针(首地址偏移法)实现将存放在数组中的一组数据按逆序重排,并打印重排后的数组。
测试主函数为:
#define N 7
int main( )
{int a[N]={1, 2, 3, 4, 11, 12, 13};
...
return 0;
}
#include <stdio.h>
#define N 7
int main()
{
int a[N]={1,2,3,4,11,12,13},i,temp;
for(i=0;i<N/2;i++)
{
temp=*(a+i);
*(a+i)=*(a+N-i-1);
*(a+N-i-1)=temp;
}
for(i=0;i<N;i++)
printf("%d ",*(a+i));
printf("\n");
return 0;
}
6.用指针移动法实现将存放在数组中的一组数据按逆序重排,并打印重排后的数组。
测试主函数为:
#define N 7
int main( )
{int a[N]={1, 2, 3, 4, 11, 12, 13};
...
return 0;
}
#include <stdio.h>
#define N 7
int main()
{
int a[N]={1,2,3,4,11,12,13},temp;
int *i=a,*j=a+N-1;
for(;i<a+N/2;i++,j--)
{
temp=*i;
*i=*j;
*j=temp;
}
for(i=a;i<=a+N-1;i++)
printf("%d ",*i);
printf("\n");
return 0;
}
7.用元素指针实现输出二维数组中的全部元素。
测试主函数为:
int main( )
{ int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
...
return 0;}
自己理解:元素指针就是例如&a[0][0],某一个元素的指针;行指针就是例如&a[0],某一行的指针;
#include <stdio.h>
#define N 7
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p=a[0];
for(;p<a[0]+12;p++)
printf("%d ",*p);
printf("\n");
return 0;
}
8.用行指针实现输出二维数组中的全部元素。
测试主函数为:
int main( )
{ int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
...
return 0;}
#include <stdio.h>
#define N 7
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4];
p=a;
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
printf("%d ",(*(p+i))[j]);//也可以写成*(*(p+i)+j)
}
printf("\n");
}
9.程序功能:fac函数通过指针返回n!,主函数定义指针,调用fac函数,打印结果。分别用两种方法实现fac,程序要求如下:
1)定义fac为有返回值函数,结果通过return语句返回主函数;
2)定义fac为无返回值函数,结果通过指针间接访问法访问主函数中的变量。
测试主函数为:
void main( )
{ int m;
float k;
printf("input m:");
scanf("%d",&m);
...fac(...);//要求fac函数实现k=m!
printf("result=%f",k);
}
1)
#include <stdio.h>
#define N 7
int fac(int m)
{
if(m==1)
return 1;//函数的递归必须有边界条件,这样才不会一直递归下去,也就是函数递归才会终止
m=m*fac(m-1);
return m;
}
void main( )
{
int m;
float k;
printf("input m:");
scanf("%d",&m);
k=fac(m);//要求fac函数实现k=m!
printf("result=%f",k);
printf("\n");
}
2)自己的理解:想要通过调用函数来改变主函数中变量的值,可以通过传递主函数中变量的指针来实现。
在求阶乘时,如果调用的函数没有返回值,则此时不用函数的递归来求,而是用最简单的循环来求。
#include <stdio.h>
#define N 7
void fac(int *p,float *q)
{
int i=*p;
*q=1;
for(;i>=1;i--)
{
*q=*q*i;
}
}
void main( )
{
int m;
float k;
printf("input m:");
scanf("%d",&m);
int *p=&m;
float *q=&k;
fac(p,q);//要求fac函数实现k=m!
printf("result=%f",k);
printf("\n");
}
10.编写函数strcat,实现两个字符串的连接,返回值为连接后字符串的首地址。
测试主函数为:
void main()
{ char str1[30] = "I learn ", *str2 = "C language.";
char *s;
s = strcat(str1,str2);//strcat函数的返回值是指针 printf("%s\n", s); }
#include <stdio.h>
#define N 7
char *strcat(char *str1,char *str2)
{
char *p=str1;
for(;;p++)
{
if(*p=='\0')
for(;*str2!='\0';p++,str2++)
*p=*str2;
if(*str2=='\0')
break;
}
return str1;
}
void main()
{
char str1[30]="I learn ",*str2="C language.";
char *s;
s=strcat(str1,str2);//strcat函数的返回值是指针
printf("%s\n",s);
}
11.一个机器人位于一个 m x n 网格的左上角(起始点在下图中标记为“Start”)。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?
示例 :
输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
测试主函数:
int uniquePaths(int m, int n) {
...//补充函数,返回路径数
}
int main(){
int m=3,n=2;
int k=uniquePaths(m,n);
printf("共有%d条路径",k);
return 0;
}
#include <stdio.h>
int uniquePaths(int m, int n)
{
if (m == 0 || n == 0)
return 0;
else if ((m == 2 && n == 1) || (m == 1 && n == 2))
return 1;
else
return uniquePaths(m - 1, n) + uniquePaths(m, n - 1);
}
int main()
{
int m = 4, n = 3;
int k = uniquePaths(m, n);
printf("共有%d条路径", k);
printf("\n");
return 0;
}
自己的理解:函数的递归,要有返回值,并且要有递归出口。(递归出口可以直接是return返回以结束递归。)
12.一个机器人位于一个 m x n 网格的左上角,机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1 和 0 来表示。
说明:m 和 n 的值均不超过 100。
示例 1:
输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
参考答案:
int uniquePathsWithObstacles(int* obstacleGrid, int obstacleGridRowSize, int obstacleGridColSize){
...//补充函数,返回路径数
}
int main(){
int a[3][3]={0,0,0,0,1,0,0,0,0};
int k=uniquePathsWithObstacles(a[0],3,3);
printf("共有%d条路径",k);
return 0;
}
#include <stdio.h>
int Pathnumber(int *p, int m, int n)
{
int q[m][n]; //新建一个二维数组,用这个二维数组来存放每到达一个地方,一共可以有的路径数
q[0][0] = 1;
//下面来看到达二维数组中每一步可以有的路径数,那么数组的最后一个元素(也就是终点的路径数就是我们要求的路径数
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
if (i == 0 && j == 0)
continue; //第0行第0列(也就是我们的起点,到达他的路径数为1,所以就不再进行别的循环,直接continue,否则会进入后面的if
else if (*(p + i * n + j) == 1)
q[i][j] = 0; //原数组元素为1,也就是有障碍物,则能到达它的路径数为0
else if (i == 0)
q[i][j] = q[i][j - 1]; //第0行除了第0列以外的元素,都和它前面那个元素的路径数相同
else if (j == 0)
q[i][j] = q[i - 1][j]; //第0列除了第0行
else
q[i][j] = q[i - 1][j] + q[i][j - 1]; //不是第0行也不是第0列也不是障碍的点,到达它的路径数为前面和上面路径数的和
}
return q[m - 1][n - 1];
}
int main()
{
int a[3][3] = {0, 0, 0, 0, 1, 0, 0, 0, 0};
int k = Pathnumber(a[0], 3, 3);
printf("共有%d条路径", k);
printf("\n");
return 0;
}
13.给定一个 n × n 的二维矩阵表示一个图像,将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
参考答案:
void rotate(int* matrix, int matrixRowSize, int matrixColSize){
...//补充函数,实现原地旋转功能
}
int main(){
int a[3][3]={1,2,3,4,5,6,7,8,9};
rotate(a[0],3,3);
int *p;
for(p=a[0];p<a[0]+9;p++)
{
if((p-a[0])%3==0) printf("\n");
printf("%4d",*p);
}
return 0;
}
#include <stdio.h>
void rotate(int *p, int m, int n) //整体思路:先上下颠倒,再转置
{
int temp;
for (int i = 0; i < m / 2; i++)
for (int j = 0; j < n; j++)
{
temp = *(p + i * n + j);
*(p + i * n + j) = *(p + (m - 1 - i) * n + j);
*(p + (m - 1 - i) * n + j) = temp;
}//上下颠倒
for (int i = 0; i < m; i++)
for (int j = 0; j <= i; j++)
{
temp = *(p + n * i + j);
*(p + n * i + j) = *(p + n * j + i);
*(p + n * j + i) = temp;
}//转置
}
int main()
{
int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
rotate(a[0], 3, 3);
int(*p)[3];
for (p = a; p < a + 3; p++)
{
for (int j = 0; j < 3; j++)
printf("%4d", (*p)[j]);
printf("\n");
}
return 0;
}
14.给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
参考答案:
int* spiralOrder(int* matrix, int matrixRowSize, int matrixColSize){
...//补充函数,返回结果(一维数组)的首元素指针
}
int main(){
int a[3][3]={1,2,3,4,5,6,7,8,9};
int matrixRowSize=3,matrixColSize=3;
int *returnnum=spiralOrder(a[0], matrixRowSize, matrixColSize);
int *p;
for(p=returnnum;p<returnnum+9;p++)
{
printf("%4d",*p);
}
return 0;
}
//给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
#include <stdio.h>
int res[100];
int *spiralOrder(int* matrix, int matrixRowSize, int matrixColSize)
{
;
int cl=0,rl=0,ch=matrixColSize-1,rh=matrixRowSize-1, count=0;
int i;
while(1)
{
for(i=cl; i<=ch; i++)res[count++] = *(matrix+rl*matrixColSize+i);//从左往右
if(++rl > rh) break; //若超出边界,退出
for(i=rl; i<=rh; i++) res[count++] = *(matrix+i*matrixColSize+ch);//从上往下
if(--ch < cl) break;
for(i=ch; i>=cl; i--) res[count++] = *(matrix+rh*matrixColSize+i);//从右往左
if(--rh < rl) break;
for(i=rh; i>=rl; i--) res[count++] = *(matrix+i*matrixColSize+cl);//从下往上
if(++cl > ch) break;
}
int *q=res;
return q;
}
int main()
{
int a[3][3]= {1,2,3,4,5,6,7,8,9};
int matrixRowSize=3,matrixColSize=3;
int *returnnum=spiralOrder(a, matrixRowSize, matrixColSize);
int *p;
for(p=returnnum;p<returnnum+9;p++)
{
printf("%4d",*p);
}
return 0;
}