第十一周总结

这个作业属于那个课程 C语言程序设计II
这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/computer-scienceclass1-2018/homework/3205
我在这个课程的目标是 1,理解何为递归并学会运用相关知识 2,学习宏的使用
这个作业在那个具体方面帮助我实现目标 运用递归的思路简化问题和宏的概念
参考文献 《C语言程序设计》

7-1 汉诺塔问题* (10 分)
汉诺塔是一个源于印度古老传说的益智玩具。据说大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘,大梵天命令僧侣把圆盘移到另一根柱子上,并且规定:在小圆盘上不能放大圆盘,每次只能移动一个圆盘。当所有圆盘都移到另一根柱子上时,世界就会毁灭。

请编写程序,输入汉诺塔圆片的数量,输出移动汉诺塔的步骤。
输入格式
圆盘数 起始柱 目的柱 过度柱
输出格式
移动汉诺塔的步骤
每行显示一步操作,具体格式为:
盘片号: 起始柱 -> 目的柱
其中盘片号从 1 开始由小到大顺序编号。
输入样例
3
a c b
输出样例
1: a -> c
2: a -> b
1: c -> b
3: a -> c
1: b -> a
2: b -> c
1: a -> c

一,实验代码

#include<stdio.h>
void hanio (int n,char a,char b,char c);
int main()
{
    int n;
    char a,b,c;
    scanf ("%d
",&n);
    scanf ("%c %c %c",&a,&b,&c);
    hanio (n,a,b,c);
    return 0;
}
void hanio (int n,char a,char b,char c)
{
    if (n==1)
    {
        printf ("%d: %c -> %c
",n,a,b);
    } 
    else
    {
        hanio (n-1,a,c,b);
        printf ("%d: %c -> %c
",n,a,b);
        hanio (n-1,c,b,a);
    }
} 

二,设计思路

用递归的思路,可以将该问题简化。步骤分为三部分:一,n-1个盘子从起始柱搬到过渡柱。二,将第n号盘子从起始柱搬到目地柱。三,n-1个盘子从过渡柱搬到目的柱。以下是流程图:

三,调试时遇到的问题及解决方法

如图,在运行时总是出现这种显示错误,原因是在输入数值到n的时候没有在后面补上 ,导致变量影响了后面的输入。所以在输入n的语句的后面加上 即可。以下是改正后的运行截图:

预习作业

数组指针来源

数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。

例子:

int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4];
p=(int(*)[4])a;
for(int i=0;i<3;i++)
{
    for(int j=0;j<4;j++) printf("%d",p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j)
    printf("
");
}

指针数组 来源

在C语言和C++语言中,数组元素全为指针的数组称为指针数组。

例子:

#include<stdio.h>
 
int main()
{
 
    int i;
  char *pch[6] = {"妹","妹","你","坐","船","头"};
    for(i=0;i<6;i++){
        printf("%s, ",pch[i]); 
    } 
    printf("
"); 
    for(i=5; i>=0; i--){ 
        printf("%s
",pch[i]); 
    }
    return 0;
}

指针函数来源

指针函数是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

例子

#include <stdio.h>
 float *find(float(*pionter)[4],int n);//函数声明
 int main(void)
 {
     static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
     float *p;
     int i,m;
     printf("Enter the number to be found:");
     scanf("%d",&m);
     printf("the score of NO.%d are:
",m);
     p=find(score,m-1);
     for(i=0;i<4;i++)
         printf("%5.2f	",*(p+i));
  
     return 0;
 }
 
float *find(float(*pionter)[4],int n)/*定义指针函数*/
 {
     float *pt;
     pt=*(pionter+n);
     return(pt);
 }

函数指针来源

函数指针是指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数。

例子

函数指针调用函数

#include<stdio.h>
int max(int x,int y){return (x>y? x:y);}
int main()
{
    int (*ptr)(int, int);
    int a, b, c;
    ptr = max;
    scanf("%d%d", &a, &b);
    c = (*ptr)(a,b);
    printf("a=%d, b=%d, max=%d", a, b, c);
    return 0;
}

做函数的参数

#include<stdio.h>
void FileFunc()
{
printf("FileFunc
");
}
void EditFunc()
{
printf("EditFunc
");
}
void main()
{
typedef void(*funcp)();
funcp pfun=FileFunc;
pfun();
pfun=EditFunc;
pfun();
}

二级指针来源

A(即B的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量.根据B的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针。

例子

#include <stdio.h>
 
int main(int argc, const char * argv[])
{
 
  //
  int a = 5;
  int *p1 = &a;
  //-打印地址-----地址相同---------------
  printf("&a = %p
", &a);//
  printf("p1 = %p
", p1);//
 
  int **p2 = &p1;
 
  //-打印地址---地址相同---------------
  printf("&p1 = %p
", &p1);//
  printf("p2 = %p
", p2);//
 
  //-打印值---------------------
  printf("a = %d
", a); // = 5;
  printf("*p1 = %d
", *p1); // = 5;
  printf("**p2 = %d
", **p2); // = 5;
 
  printf("
");
  return 0;
}

单向链表

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点

例子

#include <stdio.h>

#include <stdlib.h>

struct grade

{

int score;

struct grade *next;  

};
typedef struct grade NODE;

//typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。

//使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,

//另一个是简化一些比较复杂的类型声明。

struct grade *create();   //创建链表

void insert(NODE *head,NODE *pnew,int i);   //插入链表

void pdelete(NODE *head,int i);   //删除列表

void display(NODE *head);   //输出链表

void Pfree(NODE *head);    //销毁链表

int main(int argc, char *argv[])

{

struct grade *head,*pnew;

head=create(); 

if(head==NULL)

return 0;

printf("输出创建的链表:");

display(head);

pnew=(NODE *)malloc(sizeof(NODE));

if(pnew==NULL)

{

printf("创建失败!");

return 0;

}

pnew->score=88;

insert(head,pnew, 3);   //将新节点插入节点3的后面 

printf("插入后的链表:");

display(head);

pdelete(head,3);   //删除节点3 

printf("删除后的链表:");

display(head);

Pfree(head);

return 0;

}

struct grade *create()
{

NODE *head,*tail,*pnew;

int score;

head=(NODE *)malloc(sizeof(NODE));  //创建头节点.

if(head==NULL)  //创建失败返回 

{

printf("创建失败!");

return NULL;

}

head->next=NULL;  //头节点指针域置NULL

tail=head;  // 开始时尾指针指向头节点

printf("输入学生成绩:");

while(1)    //创建链表

{

scanf("%d",&score);

if(score<0)  //成绩为负是退出循环 

break;

pnew=(NODE *)malloc(sizeof(NODE));  //创建新节点

if(pnew==NULL)  //创建失败返回

{

printf("创建失败!");

return NULL;

}

pnew->score=score;  //新节点数据域存放输入的成绩 

pnew->next=NULL;   //新节点指针域置NULL 

tail->next=pnew;  //新节点插入到表尾 

tail=pnew;   //为指针指向当前的尾节点

}

return head;  //返回创建链表的头指针 

}

void insert(NODE *head,NODE *pnew,int i)

{

NODE *p;

int j;

p=head;

for(j=0;j<i&&p!=NULL;j++)  //p指向要插入的第i个节点

p=p->next;

if(p==NULL)  //节点i不存在

{

printf("与插入的节点不存在!");

return;

}



pnew->next=p->next;   //插入节点的指针域指向第i个节点的后继节点

p->next=pnew;    //犟第i个节点的指针域指向插入的新节点
}

void pdelete(NODE *head,int i)

{

NODE *p,*q;

int j;

if(i==0)  //删除的是头指针,返回

return;

p=head;

for(j=1;j<i&&p->next!=NULL;j++)

p=p->next;  //将p指向要删除的第i个节点的前驱节点

if(p->next==NULL)  //表明链表中的节点不存在

{

printf("不存在!");

return;

}

q=p->next;  //q指向待删除的节点 

p->next=q->next;  //删除节点i,也可写成p->next=p->next->next 

free(q);   //释放节点i的内存单元 

}

void display(NODE *head)

{

NODE *p;

for(p=head->next;p!=NULL;p=p->next)

printf("%d ",p->score);

printf("
"); 

}

void pfree(NODE *head)

{

NODE *p,*q;

p=head;

while(p->next!=NULL)    //每次删除头节点的后继节点 

{

q=p->next;

p->next=q->next;

free(q);

}

free (head);  //最后删除头节点 

}

void Pfree(NODE *head)

{

NODE *p,*q;

p=head;

while(p->next!=NULL)

{

q=p->next;

p->next=q->next;

free(q);

}

free(p);

}

学习进度统计和学习感悟

这次作业是真的难,除了第一题能写以外就没有会写的。让我见识到了自己有多菜,学海无涯苦做舟,今后要努力。

结对编程的感想

这次作业太难,我和搭档都不会,所以也没什么讨论。

原文地址:https://www.cnblogs.com/noacgnnolife/p/10846305.html