第十二讲 函数(1)

      关于昨天的问题,不知道大家是不是已经吃透了,不过就算是吃透了,我想大家一定会觉得那样做太过麻烦了,今天在说尼科彻斯定理之前,我们再来看看另一个比较简单的方法,昨天我们用的C语言来实现,今天我们用C++来实现吧,虽然说现在还没正式开讲C++,但是让那些还没接触过C++的同学可以对比一下两者的区别。
今天,我们不要那么麻烦,不用返回那些奇奇怪怪的东西了,我们直接使用STL里的vector容器来实现,但是今天我们不说vector,留在C++部分再讲。
————————————-
#include <iostream>#include <vector>using namespace std;

int main()
{
vector<int>age;

int n,m,a[10]={0 },s[10]={0 };

long sum1,sum2;

for(int i=0;

i<25;

i++)
{
sum1 = i*i*i;

sum2 = i*i*i*i;

if(sum1 >1000 &

&

sum1 <10000 &

&

sum2 >100000 &

&

sum2 <1000000)
{
age.push_back(i);

}
}
int size = age.size();

n = age[0];

m = age[size-1];

do
{
sum1 = n*n*n;

for(int i=3;

i>=0;

i–)
{
a[i] = sum1%10;

sum1 = sum1/10;

}
sum2 = n*n*n*n;

for(int i=9;

i>3;

i–)
{
a[i] = sum2%10;

sum2 = sum2/10;

}
for(int i=0;

i<=9;

i++)
{
s[a[i]]++;

}
for(int i=0;

i<=9;

i++)
{
if(s[i] == 1)
{
if(i == 9)
cout<<“这位同学的年龄是:”<<n<<endl;

}
else
break;

}
n++;

}while(n!=m);

cin.get();

return 0;

}
————————————-
今天的设计思路是将同时满足sum1和sum2的数值存放在age容器里面,然后分别取出第一个数和最后一个数来做do while循环,在do while循环和昨天实现的一样,所以没什么好说的,现在我们来看看输出和昨天的有没有区别:
第十二讲 函数(1)
结果和昨天的一样,大家是不是发觉C/C++是无所不能的啊,解决的方案还有很多,大家有兴趣的话可以自己去探索,现在回到我们今天的主题——函数。
说到函数,现在想必大家都比较熟悉了,但是为什么大家都熟悉的函数我们现在还要搬出来讲呢?因为在C/C++里,函数是完成特定任务的程序代码的自包含单元,所以,所以无论我们想要实现什么功能,都需要一个个的函数来实现。就好比昨天我们留下的尼科彻斯定理的证明就可以用一个函数来实现,下面我们先分析一下要实现这个问题的关键。
解决这个问题的关键,首先我们要确定这一连串的奇数的最大值的范围,我们声明一个int对象sum来储存一个数的立方,sum的一半n如果是奇数的话,那么 n+n+2的值就大于sum了,所以,我们可以得出一个结论,  这一连串中的奇数的最大值不会大于n,那么n是偶数的情况怎么办呢?我们应该+1还是-1?我们选择+1,那么另一个奇数就是n-1,n+n+1-1刚好等于sum,所以当n为偶数的时候,最大奇数的取值范围不会超过n+1,在确定范围后,接下来的是就好办了,我们直接从最大值开始用while来循环穷举:
———————————-
#include <stdio.h>#include <stdlib.h>int main()
{
int i, j, k ,a, n, m, sum,flag=1;

printf(“请输入一个数:n”);

scanf(“%d”, &

a);

sum = a*a*a;

n = sum / 2;

if (n % 2 == 0)
n = n + 1;

while (flag==1&

&

n >= 1)
{
m = 0;

k = 0;

while (1)
{
m += (n – 2 * k);

k++;

if (m == sum)
{
printf(“%d*%d*%d=%d=”, a, a, a, sum);

for (j = 0;

 j <k – 1;

j++)
printf(“%d+”, n – j * 2);

printf(“%dn”, n – (k – 1) *2);

flag=0;

break;

}
if (m >sum)
break;

}
n -= 2;

}
system(“PAUSE”);

return 0;

}
——————————————–
这个函数不难看懂,我们现在来看这个函数的输出:
第十二讲 函数(1)
大家可以多验证一下,那么现在我们来分析一下这个函数的结构:
#include <stdio.h>
 #include <stdlib.h>
这是我们每次写函数的时候都会在最开头添加的两句代码,大家想必都很熟悉了,但是我想对于初学者来说这个问题可能让大家觉得有些疑惑,这到底是干嘛呢?
这是函数的预处理,也就是包含相关的头文件,何为头文件?就是一个以“.h”结尾的文件,这个文件里面包含有相关的函数接口,我们要使用的标准IO都是在stdio.h这个文件里声明的,所以,我们只要包含了这个头文件就可以在接下来的代码里面使用里面的相关接口。所以如果我们需要包含什么相关文件,需要使用#include预处理命令。
除了#include命令之外,我们还会看到其他命令,如同下面这些:
#define PI 3.1415926
这是一个宏定义,就是把PI定义为3.14.5926,只要在函数开头添加了这个预处理命令,在接下来的代码中,凡是遇到PI他就表示3.1415926,所以,如果想要定义一个常量,可以使用#define 命令,记住这个命令的用法是后面只能用一个数字:
———————————
#define PI 3.1415926;//错误的方式
#define PI  3.1415929  3.1415927//错误
#define PI  2 * 3.1415926//正确的方式
#define PI  3.1415926 //正确
———————————–
当然,如果只是定义一个常量的话,我们以后会用const来定义,const的效率要比#define的高。
在函数开头使用#XXX的一般都是程序的预处理命令,大家可以多了解一些,这里就不多说了。
接下来是主线程的入口:main(),main()是控制台函数的入口,我们之所以能够看到那个黑乎乎的窗口,就是通过这个main()呼唤出来的,还记得在第一讲的时候我们说过吗?当函数执行到main()下面的左花括号({)的时候那个黑乎乎的窗口就出现了。
在SDK程序里,应用程序的窗口的入口函数是WinMain(),同时也是MFC程序的窗口入口函数,不过我们暂时不说这个函数,留待讲SDK程序的时候再说。
那么大家是不是还记得在第一讲里面我们在main()的前面使用的是void,而后来我们都用int,而细心的同学可能也注意到了,我们用void的程序没有return,而用int的都有一句
return 0
;的语句,这是为什么呢?
在c99以前,其实我们是可以不用在main()前面添加什么关键词的,因为那时候的默认情况就是void,有void修饰的函数是不需要返回的,所以我们那时候就没有使用return语句。
在标准里面,main可以定义为int/void,所以大家会看到这两种情况,但大家通常见到的都是int,带一个默认返回值,返回值一般是用来检验错误的,但是对于main来说几乎没这个必要,所以void也成了他的标准。
一个修饰词说了这么多,有点过分了,我们接着说下一点,定义一个函数,除了函数名和类型外,还需要参数和代码段的实现。
说道参数,还记得第十一讲里面我们自定义的power(int n,int m)函数吗?括号里面的n,和m便是这个函数的两个参数,但是我们又经常遇到一些没带参数的函数,没带参数的函数可以这么定义,fun(void),但是void是可以省略的,所以我们经常会看到这样的类型fun()。
每一个函数都有他的用处,那么我们怎么拿出来用呢?我们怎么把他引入主线程main()中来呢?这就关乎着函数的接口了。
说到函数的接口,大家应该不会默认,相信大家已经想到了,函数的接口就是参数和返回值。今天说得好像不少了,微信学习讲究的是轻松越快,每天花几分钟的时间就好即可,所以关于参数和返回值留待明天再说。

发表评论