【C语言】关机程序的实现以及函数
二.函数的应用
- 1.函数
- 2.函数调用
- 3.函数嵌套调用和链式访问
- 4.函数递归
一.关机程序
1.简述:
只要运作起来,电脑就在一分钟之内关机,如果输入我是猪则取消关机。
2.代码实现如下所示
shutdown -s -t 60-->关机
shutdown -a-->取消关机
C语言执行命令的函数-->system()
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("请注意,你的电脑将在1分钟内关机,如果输入:我是猪,则取消关机\n");
scanf("%s",input);
if (strcmp(input,"我是猪")==0)//两个字符串比较不能直接使用==,用strcmp并引入头文件string.h
{
system("shutdown -a");//引入stdlib.h
}
else
{
goto again;
}
getchar();
getchar();
return 0;
}
补充一个恶搞同学的:
将debug改成release,如下图
这时再运行程序,然后打开自己所保存的文件,如下会出现release:
点开后会有个.exe,这个表示可发布的,这个便可以放到同学电脑上嘻嘻~
对了,这个程序里最好不要用goto语句,goto适合循环的多层嵌套,有利于跳出。(不能跨界函数)
如图便会报错:
二.函数的应用
1.函数
分类:函数分成了库函数和自定义函数,库函数就是把开发的过程中每个程序员都可能用得到的函数存放在一个库中,为了方便程序员进行软件开发。
库函数
我们可以简单看看:或者,将en改成zh则改成了中文版。
自定义函数
自定义函数与库函数相同,返回类型,返回值,函数参数,但是不一样的是这袭人都由我们自己设定。
实参与形参
实参:真实传给函数的参数,在函数调用时,它们都必须有确定的值,以便把这些值传给形参。
形参:是指函数名后括号中的变量。形参只在该函数中有效
关系:改变形参不能改变形参!!!!
2.函数调用
传值调用与传址调用
传址调用能将函数内与函数外相联系起来
例题-->用函数调用打印100-200之间的素数
int text(int n)
{
int j = 0;
//从2->n
for (j = 2; j <= n - 1; j++)
{
if (n%j == 0)
return 0;
}
return 1;
}
int main()
{
for (int i = 100; i <= 200; i++)
{
//判断是否为素数
if (text(i) == 1)
printf("%d ",i);
}
return 0;
}
3.函数嵌套调用和链式访问
函数不可以嵌套定义,但是可以嵌套调用。
如下图:
链式访问:把一个函数的返回值作为另一个函数的参数。
如下:
int main()
{
printf("%d ", strlen("abc"));
getchar();
getchar();
return 0;
}
那我们思考下下面这个代码打印出来的是什么?
int main()
{
printf("%d",printf("%d",printf("%d",43)));
getchar();
getchar();
return 0;
}
答案是4321。为什么呢?因为printf函数返回的是打印在屏幕上字符的个数。
函数调用之前需要声明一下!!!
如下图:
因此需要在调用函数之前加int add(int,int);或者将被调函数放在之前。满足先声明后使用
例题-->写一个计算器
A-加法-->建立一个头文件用来声明函数add,再建立一个源文件来书写add函数的内容。
B-减法
C-乘法
D-除法
加法如下图:
4.函数递归
递归:即为函数自己调用自己。大事化小
迭代:重复做一件事情。(函数就是di'da)
例题-->接受一个整型值(无符号),按照顺序打印他的每一位。例如:输入1234,输出1 2 3 4
思维:1234%10=4
1234/10=123 %10=3
1234/100=12 %10=2
1234/1000=1
printf(1234)=printf(123) 4=printf(12)3 4=printf(1)2 3 4
代码如下:
void printf(unsigned int n)
{
if (n > 9)
{
printf(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%d", &num);
printf(num);
getchar();
getchar();
return 0;
}
递归满足的条件:
- 存在限制条件,当满足限制条件时,递归就不继续。
- 每次递归调用之后会越来越接近这个限制条件。
注意:1,不能有死递归,都需要有跳出条件。
2,递归层次不能太深,会出现效率低下的现象
例题-->编写函数,不允许创建临时变量,求字符串的长度。
"bit"-->my_strlen("bit")=1+my_strlen("it")=1+1+my_strlen("t")=1+1+1+my_strlen("")=1+1+1+0
代码如下:
int my_strlen(char *str)
{
if (*str != 0)
return 1 + my_strlen(str + 1);//str+1为下一个地址
else
return 0;
}
int main()
{
char arr[] = { "bit" };
printf("%d", my_strlen(arr));//传去的为arr的首地址
getchar();
getchar();
return 0;
}
注意:str+1不能写成str++,因为后置++为先使用再自加。不建议使用!!
例题-->求第n个斐波那契数(不考虑结果正确)
斐波那契数:1 1 2 3 5 8 13 21 34 55...(这个数等于前两个数之和)
int test(int n)
{
if (n >2)
return test(n - 1) + test(n - 2);
else
return 1;
}
int main()
{
int n = 0;
scanf("%d", &n);
printf("%d", test(n));
getchar();
getchar();
return 0;
}
当求第50个时候我们可以发现运行如下:
我们可以发现需要很长时间才能打印出结果,这表明了这因重复大量的计算效率太低了!!
这个我们是从后往前计算的,现在我们修改为从前往后计算,虽然结果是错的(因为整型中放的数字是有限的)但是速度会快很多,如下:
int test(int n)
{
int a = 1;
int b = 1;
int c = 1;
while (n > 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
递归了解题目:
好啦,函数这节课就讲到这里了。下课干饭!!!!!
最近更新时间会有点长(期末考试了www~~)
因篇幅问题不能全部显示,请点此查看更多更全内容