第十一周编程总结
这个作业属于哪个课程 | c语言程序设计 |
---|---|
这个作业的要求在哪里 | https://edu.cnblogs.com/campus/zswxy/computer-scienceclass1-2018/homework/3205 |
我在这个课程的目标是 | 能够正确理解递归函数,然后在适当的情况中去运用 |
这个作业在哪个具体方面帮助我实现目标 | 极大地锻炼了我的思维能力,加深了我对递归、结构的认识 |
参考文献 | 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
实验代码
void hano(int n,char x,char y,char z);
int main ()
{
int n;
char x,y,z;
scanf("%d\n",&n);
scanf("%c %c %c ",&x,&y,&z);
hano(n,x,y,z);
}
void hano(int n,char x,char y,char z)
{
if(n==1){
printf("%d: %c -> %c\n",n,x,y);
}
else{
hano(n-1,x,z,y);
printf("%d: %c -> %c\n",n,x,y);
hano(n-1,z,y,x);
}
}
实验思路
本题遇到的问题及解决方法
scanf("%c %c %c ",&x,&y,&z);
将这里写到一起了
scanf("%d %c %c %c ",&n,&x,&y,&z);
格式问题
后面几题由于还未补回来还不懂所以暂时没有做
预习作业
数组指针:
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("\n");
}
数组指针是指向数组地址的指针,其本质为指针
原网页https://baike.baidu.com/item/%E6%95%B0%E7%BB%84%E6%8C%87%E9%92%88/4177860?fr=aladdin
指针数组
int ix=0;
int i=0,j=0;
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int *p[3];
for(ix;ix<3;ix++) p[ix]=a[ix];
for(i;i<3;i++)
{
for(j=0;j<4;j++)//注意这里的j要赋值等于0,要不然只能输出第一行1234,达不到预期的效果
{
printf("%d",p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j)
}
printf("\n");
}
指针数组是数组元素为指针的数组,本质是数组。
原网页https://baike.baidu.com/item/%E6%95%B0%E7%BB%84%E6%8C%87%E9%92%88/4177860?fr=aladdin
指针函数
#include
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:\n",m);
p=find(score,m-1);
for(i=0;i<4;i++)
printf("%5.2f\t",*(p+i));
return 0;
}
float *find(float(*pionter)[4],int n)/*定义指针函数*/
{
float *pt;
pt=*(pionter+n);
return(pt);
}
原网页https://baike.baidu.com/item/%E6%8C%87%E9%92%88%E5%87%BD%E6%95%B0/2641780?fr=aladdin
函数指针
#include
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;
}
原网页https://baike.baidu.com/item/%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88
二级指针
1、先看一反例:
//目的:通过函数myMalloc改变指针p的值
#include
#include
void myMalloc(char *s) //我想在函数中分配内存,再返回
{
s=(char *) malloc(100);
}
void main()
{
char *p=NULL;
myMalloc(p); //这里的p实际还是NULL,p的值没有改变,为什么?
if(p) free(p);
}
以上例子中,p实际还是NULL,p的值没有改变,为什么?
答:我们的目的就是要改变指针p的值,因为p本身就是指针,传如myMalloc函数的实际上就是P的副本P1(副本改变,原来的P是不会改变),传入myMalloc函数的副本p1会改变了,p会改变吗?显然不会,跳出myMalloc函数后P1就被释放,P没有发生任何变化,所以P的值仍然是NULL。
2、请看下面这个可以改变P的值得程序:
//目的:通过函数myMalloc改变指针p的值
#include
#include
void myMalloc(char **s) //我想在函数中分配内存,再返回
{
*s=(char *) malloc(100);
printf("%x\n",*s);
}
void main()
{
char *p=NULL;
myMalloc(&p);
printf("%x\n",p);
if(p) free(p);
}
3、用(void**)就更具有一般性了,哈哈
//目的:通过函数myMalloc改变指针p的值
#include
#include
void myMalloc(void **s) //我想在函数中分配内存,再返回
{
*s=(char *) malloc(100);
printf("%x\n",*s);
}
void main()
{
char *p=NULL;
myMalloc((void **)&p); //这里的p实际还是NULL,p的值没有改变,为什么?
printf("%x\n",p);
if(p) free(p);
}
原网页https://www.cnblogs.com/yexuannan/p/3514488.html
单向链表
单向链表必须要防止内存泄漏
步骤
- 创建
- 输出
- 排序
- 插入
- 删除
- 清空
链表是一种重要的数据结构,它是动态地进行储存分配的一种结构,并且链表必须用指针变量才能实现(重点!)。
首先,建立动态链表
建立动态链表,就是在程序运行中根据需求向系统申请储存空间,类似int *m = new int[n]的方式构造动态数组,概念是一种从无到有地建立新节点,并将各节点连接形成链表。
原网页https://blog.csdn.net/sinat_41657218/article/details/79535130