第一周 指针

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;
}

  • 11
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
大连理工大学的C语言慕课第六内容主要涵盖了指针和内存管理的相关知识。在这一的学习中,我们首先对指针进行了详细的介绍和讲解。 指针是C语言中非常重要的概念之一,它可以用来存储变量的地址。通过指针,我们可以实现对变量的直接访问和操作,从而能够更加灵活地处理数据。在慕课中,我们学习了如何声明指针变量、如何使用指针进行内存地址的引用和解引用等基本操作。 在理解了指针的基本概念后,我们进一步学习了指针的高级应用,比如指针与数组之间的关系。通过指针与数组结合使用,我们能够实现更加高效的数组遍历和操作,减少了程序的运行时间和空间开销。 同时,慕课中还介绍了指针指针指针的数组的概念。这些概念的学习使得我们能够更加灵活地处理多维数组和多级指针的情况,拓宽了我们的编程思路和解决问题的能力。 与指针相关的知识点之一就是内存管理。在慕课中,我们学习了动态内存分配的相关函数,比如malloc、calloc和realloc等。这些函数使得我们能够在程序运行过程中动态地分配和释放内存空间,提高了程序的灵活性和效率。 在大连理工大学的C语言慕课第六中,我们不仅学习了指针的基本概念和操作,还深入了解了指针的高级应用和内存管理的知识。通过学习这些内容,我们能够更加熟练地运用指针进行编程,提高程序的性能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值