拳击哥提示:闲余时间记得锻炼身体哦 🤼
目录
5.4、写一个函数,输入一个数n,每调用一次,n的值增加1,调用10次(解析)
1.库函数
2.自定义函数
库函数,顾名思义就是C语言库中专门提供的函数,专业名词叫基础库。我们程序员都可以通过调用这些库函数来实现自己的一个意图。什么时候我们会用到呢?我来举两个例子:
1.当我们刚开始学习C语言想要将Hello World打印到黑框框上,这时候我们用到一个printf格式化输出函数,来实现打印。那么printf对应的头文件自然是#include
2.当我们想要比较两个字符串大小时候,我们用赋值(==)或大小于(>、<)是比较不出来的,这时候我们用到一个strcmp函数,来实现比较。那么strcmp对应的自然是#include
上面两个函数中第一个函数printf是我们编写程序时最常用的函数之一,第二个函数strcmp它不是那么常用,但是为了实现两个字符串的比较我们可以应用。所以为了我们编程的可移植性和编程的效率提供,C语言基础库中提供了一些库函数,方便我们程序员使用。他们大概分为哪些呢:
- 输入/输出支持函数:intput、output、scanf、printf、getchar、putchar等等
- 字符/字符串操作函数:strlen、strcmp等等
- 数学函数:sqrt、pow等等
- 内存操作函数:memcpy、memmove、memset等等
- 日期和时间工具函数:time等等
- 其他库函数
我们想要记住所有的库函数是不可行的,因此我们可以参考C语言手册:
C语言参考手册英语版
C语言参考手册中文版
注意:以上网站非商业广告纯学习用,大家可放心点击!!!
🤼函数的组成部分是什么呢,如下图:
- 语句项里面的类容是各种代码组成的功能
- 返回类型分为有返回值和无返回值
- 自定义函数名尽量采用大驼峰的形式RetType或每个单词之间加下划线is_ret_type
- 自定义函数的参数类型跟主函数类型保持一致
🤼下面程序中,函数的返回类型为void,函数的参数也是void。说明,这个函数无返回任何值。只是调用这个函数。
- #include
- void Test(void)
- {
- printf("Hello World\n");
- }
- int main()
- {
- Test();
- return 0;
- }
结果为:Hello World
🤼♀️再看一个程序输入一个数输出这个数加1:
- #include
- int Test(int x)
- {
- x = x + 1;
- return x;
- }
- int main()
- {
- int a = 0;
- scanf("%d", &a);
- printf("%d\n",Test(a));
- return 0;
- }
输入:5
输出:6
上述程序中,Test的返回类型是int,函数参数也是int。说明函数有返回值并且返回的类型是int,传来的类型也是int。
为什么要有自定义函数?上一个大标题我讲到了,C语言提供了大量的库函数。这些库函数的用法都已经固定了,那么如果我们想要做点新的东西怎么办呢我们可以自定义函数,函数里面来实现我们所想的。比如我要写一个小游戏,小游戏里面得有一个菜单,得有一个实现游戏的程序。那么我们可以自定义一个名为CaiDan()的函数和一个名为Game()的函数,这两个函数里面实现的就是这个小游戏的两个部分。我们可以在主函数main()函数里面调用这两个自定义的函数。
上面程序中主函数main里面调用了两个自定义函数CaiDan()和Game(),两个函数的类型就是void ,void就是无返回值。()里面什么都不填说明什么都不传过来也就是无传参。
下面四个程序依次列出了,实参的几个常用类型:
- //当实参是常量时候
- #include
-
- int get_max(int x,int y)
- {
- return(x > y ? x : y);
- }
- int main()
- {
- printf("%d\n", get_max(5, 3));
- return 0;
- }
-
- //当实参是变量时
- #include
-
- int get_max(int x,int y)
- {
- return(x > y ? x : y);
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- printf("%d\n", get_max(a,b));
- return 0;
- }
-
- //当时参是表达式时
- #include
-
- int ChuanCan(int x)
- {
- return x;
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- printf("%d\n", ChuanCan(a+b));
- return 0;
- }
-
- //当实参是函数时
- int get_max(int x,int y)
- {
- return(x > y ? x : y);
- }
- int main()
- {
- printf("%d\n", get_max(get_max(5, 3), 10));
- return 0;
- }
上述程序分别是实参为常量、变量、表达式、函数的四种情况,您可以复制程序。打印一下,体验四种不同的情况。
函数的实参的形参分别占用不同的内存块,我们对形参的修改是不会影响到实参的。
- //方法一
-
- #include
-
- int Max(int x, int y)
- {
- if (x > y)
- {
- return x;
- }
- return y;
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- int max=Max(a, b);
- printf("%d", max);
- return 0;
- }
- ----------------------------
- //方法二
-
- #include
-
- int Max(int x, int y)
- {
- return (x > y ? x : y);
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- printf("%d", Max(a, b));
- return 0;
- }
以上两个程序的功能是一样的
输入:10 9 输出:10
输入:9 10 输出:10
🤼第一个程序图解:
🤼♀️第二个程序图解:
那么上面两个程序中,我们自定义了一个名为Max的函数,我们通过主函数来调用它的功能,实现了比较两数的大小然后返回一个最大值给主函数。
🤼有一程序,用函数实现输入两个数并交换这两个数:
- #include
- void Swap(int x, int y)
- {
- int tmp = x;
- x = y;
- y = tmp;
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- printf("交换前:a=%d b=%d\n", a, b);
- Swap(a, b);
- printf("交换后:a=%d b=%d\n", a, b);
- return 0;
- }
输入:5 6
输出:交换前:a=5,b=6
交换后:a=5,b=6
我们可以看到,它们并没有交换彼此。为什么会这样呢,那是因为Swap函数里面交换的仅仅是形参里面的x和y的值,也就是实参的临时拷贝的那两块地址里面的值,而实参里的a和b地址里面的值并未发生改变还是原来的值,所以传回的值还是5和6。我们可以借助下图理解:
我们可以这样改:
- #include
- void Swap(int* x, int* y)
- {
- int tmp = *x;
- *x = *y;
- *y = tmp;
- }
- int main()
- {
- int a = 0;
- int b = 0;
- scanf("%d %d", &a, &b);
- printf("交换前:a=%d b=%d\n", a, b);
- Swap(&a, &b);
- printf("交换后:a=%d b=%d\n", a, b);
- return 0;
- }
输入:5 6
输出:交换前:a=5,b=6
交换后:a=6,b=5
上面说到了,形参只是实参的一块临时拷贝。那么如果我把实参的地址给形参了,那么你临时拷贝的地址是不是就与实参的地址一致了,那交换的值也就一致了。
那么上述程序范围类型是void也就是无返回值,它们只是修改了内存中值。
下面一个截图我们可以很清楚的观察到,实参传值给形参后它们在内存中存放的地址是不同的。
下面截图中,实参把地址传给形参后,它们的地址是一致的,所以最后实现了交换。
那么如何监视程序呢,下面我就来介绍:
第一步:按F10打开调试当程序左方出现箭头证明可以开始调试
第二步:打开调试窗口,任选一个监视。
第三步:按F10代码会往下走,你可以在监视窗口输入你想监视的内容。注意:监视窗口里面的内容是要输入的,你输入a则输出a的值,你输入&a则输出a的地址。
第四步:当你箭头指向scanf时你按F10然后输入a和b的值,a和b的值会自动变成你所输入的值。
第五步:当箭头来到Swap函数的时候按F11,自动跳转到函数里面
第六步:分别在监视窗口输入x,y,tmp,以便观察它们的变化
正在发生变化
最后一步停止调试
以上就是监视窗口的六个步骤,耐下心来一步步实现,相信你能成为一个调试高手!!!
- #include
- #include
-
- int PanDuan(int n)
- {
- for (int i = 2; i <= sqrt(n); i++)
- {
- if (n % i == 0)
- {
- return 0;
- }
- }
- return 1;
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- if (PanDuan(n))
- {
- printf("这是一个素数\n");
- }
- else
- {
- printf("这不是一个素数\n");
- }
- return 0;
- }
输入:9输出:这是一个素数
解析:
素数满足条件是除1和本身之外都没有任何因子被它整除,上述程序中主函数传参到形参里面PanDan函数里面主要做的是从2开始直到n的开方数依次做为除数用传过去的参数,n依次从2除到n的开方数。如果能整除说明该数不是素数返回0,如果不整除则返回1。返回的值由if判断语句来执行,判断为真输出这是一个素数,否则这不是一个素质。
- #include
-
- int LeapYear(int n)
- {
- if (n % 400 == 0 || n % 4 == 0 && n % 100 != 0)
- {
- return 1;
- }
- return 0;
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- if (LeapYear(n))
- {
- printf("这是一个闰年\n");
- }
- else
- {
- printf("这不是一个闰年\n");
- }
- return 0;
- }
输入:2000输出:这是一个闰年
解析:
首先闰年的满足条件为:能被400整除或能被4整除但不能被100整除,这个程序跟第一个程序类似,都是传一个参数过去传一个参数回来,那么LeapYear里面的功能主要是判断n是否为闰年如果是返回1,否则返回0。返回的值再交给if语句来判断满足1则输出这是一个闰年否则这不是一个闰年。
- #include
-
- int Find(int arr2[],int key2,int str)
- {
- int left = 0;
- int right = str-1;
- int mid = 0;
- while (left<=right)
- {
- mid = (left + right) / 2;
- if (arr2[mid] > key2)
- {
- right = mid - 1;
- }
- else if (arr2[mid] < key2)
- {
- left = mid + 1;
- }
- else
- {
- return mid;
- }
- }
- return -1;
- }
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
- int key1 = 0;
- scanf("%d", &key1);
- int str1 = sizeof(arr1);
- int rat = Find(arr1, key1,str1);
- if (rat==-1)
- {
- printf("没有这个数\n");
- }
- else
- {
- printf("有这个数,下标为%d\n", rat);
- }
- return 0;
- }
解析:
首先我们主函数要初始化一个有序数组,然后输入一个数,求出这个数组的元素个数,分别把数组,输入的数,数组元素个数传给形参。Find拿到这三个值后。设置一个左下标left为最左的下标0,设置一个右下标right为最右的下标数组元素的个数-1,和一个中间下标mid。然后进入循环,循环里就是进行查找。
第一种情况:输入的数比中间那个数大,假设我输入的key1为8,传给key2。下图为初始状态
第一步、arr2[mid]
第二步、 arr2[mid]=8,返回mid给主函数并结束Find函数里面的程序,传回mid值给主函数。然后输出:有这个数,下标为:7。
第二种情况,输入的数比中间的数小,假设我输入的数key1是3传给key2,下图为初始状态
第一步、 arr2[mid]>key2,就使right=mid-1,此时left=0,mid=1,right=3。
第二步、arr2[mid]
第三步、arr2[mid]=3,返回mid给主函数并结束Find函数里面的程序,传回mid值给主函数。然后输出:有这个数,下标为:2。
- #include
- int BigOne(n)
- {
- return (n + 1);
- }
- int main()
- {
- int n = 0;
- scanf("%d", &n);
- for (int i = 0; i < 10; i++)
- {
- n=BigOne(n);
- printf("%d ", n);
- }
- return 0;
- }
输入:5输出:6 7 8 9 10 11 12 13 14 15
解析:
这个函数就比较简单,输入一个数,把这个数传给形参,主函数里面for语句控制传参十次,BigOne函数里面每次传参过来,返回参值加1 。然后输出每次一传回来的参值。
-
- #include
- #include
//rand()函数、cls清理屏幕函数都用此头文件 - #include
//time时间戳 - void caidan()//这是一个菜单
- {
- printf("*********************\n");
- printf("***** 开始:1 *****\n");
- printf("***** 退出:0 *****\n");
- printf("*********************\n");
- }
- void game()//这是游戏函数
- {
- int rat = rand()%100+1;
- int num = 0;
- while (1)
- {
- printf("请输入你的数字:>");
- scanf("%d", &num);
- if (rat < num)
- {
- printf("你猜大了\n");
- }
- else if (rat >num)
- {
-
- printf("你猜小了\n");
- }
- else
- {
- printf("恭喜你,你猜对了\n");
- break;
- }
- }
- system("cls");
- }
- int main()
- {
- int n = 0;
- srand((unsigned)time(NULL));
- do
- {
- caidan();
- printf("请选择:>");
- scanf("%d", &n);
- switch (n)
- {
- case 0:printf("你已退出游戏\n"); break;
- case 1:game(); break;
- default:printf("请输入正确的数字\n");break;
- }
- } while (n);
- return 0;
- }
那么本期博客就到这里了,感谢大家的耐心观看,如有收获请三连,万分感谢!!!
每次学习都要像打拳一样全神贯注,这样才不会被对手(困难)击倒