刷题数5;
上午满课
学了指针的基本概念以及指针的赋初值
数学课学了函数的极值
感觉指针还是很抽象 用下面这个例题来理解吧
先要理解地址和数据,你可以想象有很多盒子,每个盒子有对应的号码,那个号码叫做“地址”,而盒子里放的东西叫做“数据”。
上面就段理解了,*p和p的区别就不难解释了。
p是指针变量,用来存放地址,你可以认为是上面所说的盒子的号码,“ * ”是解引用操作符,你可以把它理解成打开盒子,p就是打开p号盒子,取出里面的数据。
简单来说,你记住,p存放的是地址,而*p是让程序去那个地址取出数据。
#include<stdio.h>
void fun(char *a,char *b)
{
a=b;
(*a)++;
}
int main()
{
char c1='A',c2='a',*p1,*p2;
p1=&c1;
p2=&c2;
fun(p1,p2);
printf("%c%c\n",c1,c2);
return 0;
}
//程序运行后的输出结果是__A____
//A.Ab B.aa C.Aa D.Bb
一步一步来;
1.主函数中定义字符串指针p1,p2;
2.指针变量p1指向的是C1中的地址即c1中存放了'A'
3.指针变量p2指向的是C2中的地址即c1中存放了'a'
4.自定义函数输入*p1,*p2两个指针代表两个数据;
a=b即可以理解为将b指针的变量的名字赋给a指针变量;
即p1=p2;
此时再进行(*a)++就相当于没有进入自定义函数前的(*p2)++,即把p2中存放的元素加1;
5.输出c1,p1指向的c1地址中存放的'A'没有发生改变,所以输出A。
6.输出c2,p2指向的c2地址中存放的'a'发生了加一的改变,所以输出‘b’;
同理:在C语言中,有各种类型的变量,譬如:整形int, 浮点型float, 字符型char等等,所有的变量是不是有个地址,那么根据这个地址,我们就可以对变量进行操作了。同常,我们定义一个指针来指向某个变量,这样通过指针就可以操作变量了,举个例子吧
int a = 111;
int *p = &a;
这里p是指针,指向了变量a, 因为变量a存放在内存某个单元,是有地址的,指针变量p就是指向了这个内存单元。
今天还复习了一下递归因为不懂他的程序进行原理。用下面这个例题来说
问题 A: 皮皮扬爱吃芒果
描述
有一天,皮皮扬有钱了,就叫上了CC去吃一个榴芒,到了店里的时候,皮皮扬买了M个芒果班戟,她想把这些芒果班戟放在N个盘子里,允许盘子可以不放,不过皮皮扬的思维不好,不知道怎么放这些,现在就需要我们来帮皮皮扬算一下一共有多少种不同的分法?
格式
输入格式
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出格式
对输入的每组数据M和N,用一行输出相应的K。
样例
样例输入 Copy
1
7 3
样例输出 Copy
8
提示
5,1,1和1,5,1 是同一种分法。
代码
#include<stdio.h>
int YNB(int m,int n)
{
if(m==0 || n==1)
return 1;
if(n>m)
return YNB(m,m);
else
return YNB(m,n-1)+YNB(m-n,n);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int sum;
int m,n;
scanf("%d %d",&m,&n);
sum=YNB(m,n);
printf("%d\n",sum);
}
}
解题分析:
设f(m,n)为m个芒果,n个盘子的放法数目,则先对n作讨论,
- 当n>m:则必定有n-m个盘子永远空着,去掉它们对摆放芒果方法数目不产生影响。即 if(n>m) f(m,n) = f(m,m)
- 当n <= m:不同的放法可以分成两类:含有0的方案数,不含有0的方案数
- 含有0的方案数,即有至少一个盘子空着,即相当于 f(m,n)=f(m,n-1);
- 不含有0的方案数,即所有的盘子都有芒果,相当于可以从每个盘子中拿掉一个芒果,不影响不同放法的数目,即 f(m,n)=f(m-n,n).而总的放芒果的放法数目等于两者的和,即 f(m,n)=f(m,n-1)+f(m-n,n)
递归出口条件说明:
- 当n=1时,所有芒果都必须放在一个盘子里,所以返回1;
- 当m==0(没有芒果可放)时,定义为1种放法;