作者game0416 (凤狼)
看板NTUE-CS102
标题Re: [闲聊] 程设作业
时间Wed Dec 9 22:58:44 2009
.....
不抄不问自己翻课本做得出来的应该没几个(汗)
这里先重新说明函式用法,在解题前一样会留个防雷页的
是说这次解题应该是可以抄的境界(?),虽然没什麽人看,大概也不太需要在意(?)
int f ()
{
...
}
"宣告"一个函式大致可以分成这四个部份
注意是宣告,先想成像宣告变数一样去做跟使用就好
int表示回传值的型态,大多是只有用int float bool void而已,其他大多先不在乎
f是函式名称,相关限制与注意事项与宣告变数名称时的限制相同
()是摆参数的地方,用来把特定数值/位址传达给函式内使用
详细用法会在接下来一小段简单的示范code说明
这段code是 输入两个数值,将其相乘後的结果印出来
左边是使用函式的方法;右边是不使用的对照组
#include<iosream> #include<iosream>
using namespace std;
using namespace std;
int multiple(
int x ,
int y)
int main()
{ {
return
x*
y;
int x,
y;
} cin >>
x >>
y;
cout <<
x*
y;
int main() }
{
int x,
y;
cin >>
x >>
y;
cout <<multiple(
x,
y);
}
像这样就是个简单的对照,当然通常不干这种小事就把code变长
这里注意两件事情
1.左边使用函式的这边,颜色不同的x.y表示的是"不同"的变数,虽然同样称作x.y
这个在写code时没做出明确分别很容易搞混,也是常见的问题
2.multiple(
x,
y) 在main()内,等同於程式码中 x*y 的"数值"
因此,可以有
int i = multiple(x,y) 这样的用法存在
再来,解题前先说明大概有几种作法,供完全没概念的人一点方向
1.将判断摆在函式内,回传xAyB的x.y ;这大概是老师最希望看到的...?
2.把整段while内的判断摆在函式内,包含印出xAyB的行为 ;这是大部分人选的事情
3.全域变数 ;元品那边好像大多都用这个方法?
4.指标 ; 现阶段没事干不要做这种事情。
5.假主函式 ; 这个不知道算不算不合题意(逃远)
大原则上,作法内容都差不多,只是数值从主函式到函式的方法差别而已
以下开始进入防雷
--
请记得,如果你现在什麽都还没有写请稍微思考再往下看
如果你有写完觉得有问题,请往下找到你自己的写法看看有些什麽样的问题可以参考
不然期末考应该很难过的。
--
开头,先摆上一个不使用函式的范例code做为基本对照组
如果需要抄这个code当作业,我会建议不如先回头独立作完过去的作业
或是另外向翔风ㄉㄉ要一点基本题目来写,不然明年学弟妹可能会跟你一起修了
a系列变数是输入的答案,in系列是猜的数字,a.b就是正确与错误位置的数目了
#include<iosream>
using namespace std;
int main()
{
sdgasgsdafasdfasdfasdfasdfasdfasdfasf
sdint a1,a2,a3,in1,in2,in3,a,b;
ascin >>a1 >>a2 >>a3;
aswhile (1)
asdasdasdasdasdasdasdasgfsagawrerehwe
ty{
qwarwgtawergwaeftawef
a=b=0;
asdasdgaehsretyulkertyju[4k
cin >>in1 >>in2 >>in3;
if (a1==in1) a++;
if (a1==in2 || a1==in3) b++;
qweqweqwewasdgadefh
ererif (a2==in2) a++;
if (a1==in1 || a1==in3) b++;
wqwearykenhp;ln45
if (a3==in3) a++;
if (a1==in1 || a1==in2) b++;
ergypwekhmrg['w
cout <<a <<'A' <<b <<'B';
if (a==3) break;
}
}
--
1.将判断摆在函式内,回传xAyB的x.y
2.把整段while内的判断摆在函式内,包含印出xAyB的行为
其实1.跟2.差不多,都还在目前交授范围内,只是一两步不同的差异
大体上都是while内大部分东西放到函式内,以下函式通用test表示判断、测试部份
只是摆多少的差别,比如说
1.只把A.B判断後的xAyB中x.y传回,然後在主函式印出来
2.连同输出都摆在里面,所以连return都不太用
先举出两者在函式中代表的范围,共通部份大致是以下这段
if (a1==in1) a++;
if (a1==in2 || a1==in3) b++;
qweqweqwewasdgadefh
ererif (a2==in2) a++;
if (a2==in1 || a2==in3) b++;
wqwearykenhp;ln45
if (a3==in3) a++;
if (a3==in1 || a3==in2) b++;
ergypwekhmrg['w
依照使用者习惯决定要不要连同cin >>in1 >>in2 >>in3;一起置入
为了与大部分人思维相同,以不摆进为主..不然函式参数太长很容易乱掉
同时,避免让人搞混,这里参数名称也会与主函式宣告的变数拼字不太一样
下一页是函式与其宣告内容
--
int testA(
int aa1,
int aa2,
int aa3,
int iin1 ,
int iin2
,int iin3)
{
int aa=0;
if (aa1==iin1) aa++;
er
if (aa2==iin2) aa++;
wqwearykenhp;ln45
if (aa3==iin3) aa++;
ergypwekhmrg['w
return aa;
}
int testB(
int aa1,
int aa2,
int aa3,
int iin1 ,
int iin2
,int iin3)
{
int bb=0;
if (aa1==iin2 || aa1==iin3) bb++;
erif (aa2==iin1 || aa2==iin3) bb++;
if (aa3==iin1 || aa3==iin2) bb++;
ergypwekhmrg['w
return bb;
}
会这样做只是我想不到怎样可以用现在教的范围去做到"在一个函式输入并回传两个值"
所以就是在输入猜测数值後,才判断并输出,下页摆上main的内容,再正式说明
--
int main()
{
int a1,a2,a3,in1,in2,in3;
cin >>a1 >>a2 >>a3;
while (1)
{
cin >>in1 >>in2 >>in3;
cout <<testA(a1,a2,a3,in1,in2,in3)<<'A'<<testB(a1,a2,a3,in1,in2,in3) <<'B';
if (testA(a1,a2,a3,in1,in2,in3)==3)
break;
}
嗯,我也觉得那个参数引用的乱恶心的-____-
这边我想提一下,可以的话,用函式就善加练习参数使用与回传的应用比较好
不然哪天会像我一样改个code快死在地上(倒)
嗯..这边就先拿testA(a1,a2,a3,in1,in2,in3)说明就好
前三个参数,是要把正确答案传达进函式使用,後三个是要把猜测的数传进去使用
所以说aa1会相等成a1的数值,其余比照处理
然後我们用跟原本写法一样的判断去决定有几个在正确的位置上,并且将其回传给主函式用
--
像是以下这一小段:
cout <<testA(a1,a2,a3,in1,in2,in3) <<'A'
就是这样的用法,还记得前面说有return的话可以把整串认知是return的值吗?
假设现在是完全正确的答案,return的aa就会是3
这一小段就可以看作是
cout <<3 <<'A'
这样的内容,虽然其实它原本长的很恶心。
往下看主函式的内容
if (testA(a1,a2,a3,in1,in2,in3)==3)
break;
这段的原因是我在前面让他重复执行的地方是采用无限回圈
所以在这里让3A发生时会离开回圏,自然的结束这个程式
这段要不要存在或内容摆什麽端看怎麽写回圈判断式...
比如你可以把这个判断就放在while之中...应该是不会发生一开始预设值就相等的状况
--
再来是看到蛮多的函式用法,这种主要问题就只是如何离开回圏
内容很直接,这边稍微美化一点...今天大多使用参数都使用了很多无意义的宣告
void test(int aa1,int aa2,int aa3)
{
int in1,in2,in3,a=0,b=0;
cin >>in1 >>in2 >>in3;
if (aa1==in1) a++;
if (aa1==in2 || aa1==in3) b++;
if (aa2==in2) a++;
if (aa1==in1 || aa1==in3) b++;
if (aa3==in3) a++;
if (aa1==in1 || aa1==in2) b++;
cout <<a <<'A' <<b <<'B';
}
int main()
{
int a1,a2,a3;
cin >>a1 >>a2 >>a3;
while (1)
test(a1,a2,a3);
}
--
这就是很单纯把while内原有的东西都塞在里头的范例
简单有效,只是这个回圈终止不了而已
这边大概是有三种作法...
1.把void改成会在3A时回传一个特定值,在while里判断回传的是不是特定值。
是的话break out
int test(int aa1,int aa2,int aa3)
{
int in1,in2,in3,a=0,b=0;
cin >>in1 >>in2 >>in3;
if (aa1==in1) a++;
if (aa1==in2 || aa1==in3) b++;
if (aa2==in2) a++;
if (aa1==in1 || aa1==in3) b++;
if (aa3==in3) a++;
if (aa1==in1 || aa1==in2) b++;
cout <<a <<'A' <<b <<'B';
if (a==3)
return 102;
else return 0;
}
--
(中略)
while (1){
int d=test(a1,a2,a3)
if (d==102)
break;
}
像这样利用回传值去做要不要跳出函式的判断就可以了
或是说,也能这样用函式,函式内的事情还是会执行,也同样会回传值而不影响
while (1){
if (test(a1,a2,a3)==102)
break;
}
这个会延伸造成那个在翔风ㄉㄉ的文章里头提的今天另外一个问题
判断式做一次,叙述又做一次这样的状况发生
更为乾脆、简化的作法是3A回传0或改成bool传false,放在while判断式里头
while (test(a1,a2,a3)) ;
不过呢,新手这种事情都少干,因为只会把程式搞的更复杂到自己搞不懂
--
第三种作法是blue不知不觉用的作法...之後应该会提到的递回
这里我要提句名言"递回只应天上有,凡人应当用回圈"
因为容易在思绪上乱掉,大多时候回圈还是比较容易的
int test(int aa1,int aa2,int aa3)
{
int in1,in2,in3,a=0,b=0;
cin >>in1 >>in2 >>in3;
if (aa1==in1) a++;
if (aa1==in2 || aa1==in3) b++;
if (aa2==in2) a++;
if (aa1==in1 || aa1==in3) b++;
if (aa3==in3) a++;
if (aa1==in1 || aa1==in2) b++;
cout <<a <<'A' <<b <<'B';
if (a!=3)
return test(aa1,aa2,aa3);
else return 0;
}
int main()
{
int a1,a2,a3;
cin >>a1 >>a2 >>a3;
test(a1,a2,a3);
}
--
看起来很复杂,其实递回是种自体呼叫的方法
也就是说在函式内使用自己,此部分名范例就费波纳契数列、递回等
像是这样写的话,当a不是3的时候,就会再一次进入test里头
重新输入猜测数字、判断
当猜到3A时,就会回传0,然後这个0会一路往上传到第一次用的test()
随即结束程式这样
嘛...没事不要这样用(远目)
--
再来是第三种,全域变数
以下可以都当茶余饭後看看就好,不然一个比一个恶心....
好吧,第五项可以看看(茶)
之前我们知道,每个变数只会在
宣告时的那组{ }之间可以使用
: 就是为什麽main跟函式间的x.y不能共用这样的感觉
那如果说,把整个.cpp档想成有个范围很大的{ }的话
那麽连main()都会在这个 { }之中
也就是说,我们在跟main同样的位置上宣告变数,那这个变数是不是就能用在很多函式中?
这就是全域变数,在所有的区域中都能使用的变数。
与之对比就是区域变数,只能在特定范围使用的变数。
用这个方法,就能避免掉不会使用函数中的参数的问题
在初学来说是把双面刃这样...它可以让你更容易完成作业,相反的也减少练习参数的机会
再来,一样是code
只是这个更好抄-_______-
--
#include<iosream>
using namespace std;
int a1,a2,a3,in1,in2,in3,a,b;
bool test()
{
if (a1==in1) a++;
if (a1==in2 || a1==in3) b++;
if (a2==in2) a++;
if (a1==in1 || a1==in3) b++;
if (a3==in3) a++;
if (a1==in1 || a1==in2) b++;
cout <<a <<'A' <<b <<'B';
if (a==3)
return 0;
else return 1;
}
int main()
{
cin >>a1 >>a2 >>a3;
while (test()) ;
}
大概就是这样,因为变成全域....所以写起来感觉就跟都在main里宣告一样
也不用麻烦的去设函数的参数什麽的
--
再来是我自己用的指标...
我只是想练习一下而已(拖走
老师今天有提过,从函式传值的方法
也就是那个pass by value;pass by address什麽的(?)
指标就是後者这种,将变数存在的"位址"传给函式中
让改变数值是改变这个"位址"的数值
因此便能利用函式去改变主程式中的变数
其中pass by address分成 取值与给值..这里范例用取值
在於这次的作业里,大体上就是像模拟全域变数而已
只是利用指标能比较节省程式执行中记忆体 (吧?)
因为不到必要是不会去宣告一个变数摆在那里不使用
然後一般写程式应用也算广,只是还没教到的东西...就看看就好
可以不用急着搞懂怎麽用,有兴趣先翻课本吧(跑远)
--
#include<iosream>
using namespace std;
void test(
int *a1,
int *a2,
int *a3,
int *in1,
int *in2,
int *a3,
int *a,
int *b)
{
if (*a1==*in1) *a+=1;
if (*a1==*in2 || *a1==*in3) *b+=1;
if (*a2==*in2) *a+=1;
if (*a1==*in1 || *a1==*in3) *b+=1;
if (*a3==*in3) *a+=1;
if (*a1==*in1 || *a1==*in2) *b+=1;
}
int main()
{
int a1,a2,a3,in1,in2,in3,a,b;
cin >>a1 >>a2 >>a3;
while (cin >>in1 >>in2 >>in3)
{
a=b=0;
test(a1,a2,a3,in1,in2,in3,a,b);
cout <<a <<'A' <<b <<'B';
if (a==3)
break;
}
}
--
看完很多莫名奇妙的东西,最後一个就稍微轻松一点,算是走在边缘上的作法
我们把所有东西都写在函式,然後让主函式呼叫,这样就是都不在主函式了
#include<iosream>
using namespace std;
void fake_main()
{
sdgasgsdafasdfasdfasdfasdfasdfasdfasf
sdint a1,a2,a3,in1,in2,in3,a,b;
ascin >>a1 >>a2 >>a3;
aswhile (1) {
qwarwgtawergwaeftawef
a=b=0;
asdasdgaehsretyulkertyju[4k
cin >>in1 >>in2 >>in3;
if (a1==in1) a++;
if (a1==in2 || a1==in3) b++;
qweqweqwewasdgadefh
ererif (a2==in2) a++;
if (a1==in1 || a1==in3) b++;
wqwearykenhp;ln45
if (a3==in3) a++;
if (a1==in1 || a1==in2) b++;
ergypwekhmrg['w
cout <<a <<'A' <<b <<'B';
if (a==3)
break;
}
}
int main(){
fake_main();
}
--
嗯,最後一个示范code要小小改了才能交,不然是不合题意的(跑)
希望各位是不要用抄的这样(远目)
很多因为都没有拿去编译过,所以小疏忽什麽的很容易出现
不过写程式出错可以改,所以就不要太拘泥要一次对了(逃跑
--
红白本命
○楽园の巫女
博丽 霊梦 职业:博丽神社の巫女さん
Hakurei Reimu 能力:主に空を飞ぶ程度の能力
@东方project系列
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 115.43.39.145
1F:推 pk873:有较劲的意味?? 12/09 22:59
2F:→ game0416:强者的宿命就是..... (拖走 12/09 23:01
3F:推 CaptainWill:威... 12/09 23:03
4F:推 Arashinoon:为什麽知道我是用全域变数 囧 太强大了 12/09 23:12
5F:→ game0416:八卦来的消息,加上你那附近大部分也这样用啊 XD 12/09 23:14
6F:推 CaptainWill:你们都不说中文... 12/09 23:15
7F:→ CaptainWill:凤狼不用怕被说自肥,M了这篇吧 12/09 23:15
8F:推 Arashinoon:话说 最後一个方法应该不能用ˊˋ 最後老师说不能在 12/09 23:22
9F:→ Arashinoon:函数中用while 12/09 23:22
10F:→ game0416:那就递回....(拖走 12/09 23:23
11F:推 gcobc12632:不能在函数中用while?那在while里面塞函数OK吧? 12/09 23:43
12F:→ j2612280:OK 12/09 23:49
13F:→ j2612280:只是要记得在while的()放函数的话函数也是会跑的唷! 12/09 23:50
14F:推 gcobc12632:那还好没写错…只不过好像多写了很多东西(?) 12/10 00:00
15F:→ j2612280:可能吧...慢慢来就会改善滴~ 12/10 00:03
16F:推 ip3311:第163行最後面的B打错了欧 = = 无意间看到XD 12/11 00:37
※ 编辑: game0416 来自: 115.43.39.145 (12/11 00:39)