重温c语言之,7天开整,就是随便的写写,第七天
一:素数又见素数
但这次不一样,这次需要用到函数,利用函数来将素数区分出来,直接上代码
1 #include <stdio.h> 2 #include<math.h> 3 int prime_num(int num) 4 { 5 for (int i = 2; i < sqrt(num); i++) 6 { 7 if (num % i == 0) 8 { 9 return 0; 10 } 11 } 12 return 1; 13 } 14 15 int main() 16 { 17 int num = 0; 18 printf("请随机写一个数字.\n"); 19 scanf("%d", &num); 20 if ((prime_num(num)) == 1)//其实这里可以不用写等于的,因为在判断里面,非0为true,0为false 21 { 22 printf("这个数字是素数:%d\n", num); 23 } 24 else 25 { 26 printf("这个数字不是素数:%d\n", num); 27 } 28 return 0; 29 }
我这里用到了sqrt()这个函数,因为在这里面,偶数是不能当素数的,所以直接就是更加高效的进化程序
二:这里是强调函数的高内聚低耦合的观点
题目:写一个函数,判断一年是否是闰年,打印1000~2000之间的闰年
直接上代码:
1 #include <stdio.h> 2 int leap_year(int year) 3 { 4 if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) 5 { 6 return 1; 7 } 8 else 9 { 10 return 0; 11 } 12 } 13 int main() 14 { 15 for (int i = 1000; i < 2000; i++) 16 { 17 if (leap_year(i)) 18 { 19 printf("%d ", i); 20 } 21 } 22 }
这个直接让判断闰年函数功能变得单一,不去依赖其他函数,自己就可以完成功能,这里我没有在这个函数内部输出闰年,因为可能下一次的时候,我不想输出,我只想判断,那我就用不了这个函数的功能,如果让这个函数变得单一的话,那我所有的想用到这个判断是否是闰年相关的地方,我都可以用到这个函数
三:函数
1、函数可以嵌套调用,但不能嵌套定义
2、函数递归
题目是:
接收一个整形值,按照顺序打印每一位
//例如:
//输入:1234 输出: 1 2 3 4
先直接上代码,
1 #include<stdio.h> 2 void print(unsigned int num) { 3 if (num > 9) { 4 print(num / 10); 5 } 6 printf("%u ", num%10); 7 } 8 9 //递归的实现 10 int main() 11 { 12 //%d打印有符号的整数,包括正负数 13 //%u打印无符号的整数 14 unsigned int num1 = 0; 15 16 scanf("%u", &num1);//1234 17 //1 2 3 4 18 19 print(num1); 20 return 0; 21 }
一开始我还没有真正明白这体式什么意思,知道我知道了这个题目:递归,是吧大的问题化成小的问题,就比如这个
这里就是从键盘上面收到:1234,而我们想要的结果是:1 2 3 4 ,那怎么解决呢?
这个时候我们想到了:求余运算,它能展现想要的位置上的数字,那这个输出的递归函数该怎么理解呢?
键盘先输入:1234,计算机收到了数字,随着程序的运行,把1234这个数字转入到了print()递归函数中,之后因为这个数字要大于9(为什么是9呢?因为想要个位上的数字,求余10就可以得出个位上的数字,所以要把十位以上的数字全部去除),之后就是数字大于9,
开始了第一次print()递归函数重运行,这个时候传入的数字是:123,因为里面的数字是:先进行num/10运算再输入的,123>9,
所以第二次运行print()递归函数重运行,这个时候传入的数字是:12,方法同上:123/10=12,12>9
最后一次运行print()函数,这个时候传入的数字是:1,12/10=1,1<9,所以这里运行printf(),1%10=1 ,并输出:1 ,屏幕上有:1
再倒回来,输出printf()函数,12%10=2,并输出:2 ,屏幕上有:1 2
再次倒回来,运行printf()函数,123%10=3,并输出:3 ,屏幕上有:1 2 3
最后,再次运行printf()函数,1234%10=4,并输出:4,屏幕上有:1 2 3 4
最终的屏幕上显示:1 2 3 4
如果这里不写if(num>9),则会造成栈溢出,因为每一次函数调用,都会在栈区申请空间
所以递归存在限制条件,当满足这个限制条件的时候,递归不再继续;每次递归调用之后,越来越接近这个条件
if(num>9) num/10
再来一题:编写函数不允许创建临时变量,求字符串长度
先来个创建临时变量的:
1 #include<stdio.h> 2 #include<string.h> 3 int my_strlen(char* str) { 4 int cout = 0;//计数,临时变量 5 while (*str != '\0') { 6 cout++; 7 str++; 8 } 9 return cout; 10 } 11 int main() 12 { 13 char arr[] = "abc"; 14 int len = my_strlen(arr); 15 printf("%d\n", len); 16 }
再来个不创建临时变量的(用到了函数递归):
1 #include<stdio.h> 2 #include<string.h> 3 int my_strlen(char* str) { 4 if (*str != '\0') { 5 return 1 + my_strlen(str+1); 6 } 7 else 8 { 9 return 0; 10 } 11 } 12 int main() 13 { 14 char arr[] = "abc"; 15 int len = my_strlen(arr); 16 printf("%d\n", len); 17 }
my_strlen("abc");
1 + my_strlen("ab");
1 + 1 + my_strlen("a");
1 + 1 + 1 + my_strlen("");
这个就用到了调用,这里为什么是str+1,而不是str+4/str+8呢,因为是str是一个指针变量,操作系统根据自身多少位来分配给指针变量多少字节,用来存放指针所指向的地址的,这里是不会变动的。
而str+1是因为str这个指针变量所指向的数据类型是char,是占1个字节,所以才+1,往后移动1个字节;如果是int,则+4,往后移动4个字节