int main () { char str[] = "almost every programmer should know memset!"; memset (str,'-',6); printf("%sn",str); return 0; }
------ every programmer should know memset!
由此我们可以知道字符串中前num个字符将被中间赋予的值所覆盖
*****2:自定义函数:自我设置的函数,和库函数一样都有函数名、返回值类型、函数参数等
(1):自定义函数的组成
(2):例题
1:用函数找出两个整数的最大值
#include<stdio.h> int get_max(int x, int y) { if (x > y) { return x; } else { return y; } } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); int c = get_max(a, b); printf("%dn", c); return 0; }
输入:3 7
输出:7
2 :用函数交换两个整型变量的内容
错误:
#include<stdio.h> void Swap(int a, int b)//void表示无返回值 { int tmp = 0;//创建临时变量tmo tmp = a;//将a值赋给tmp a = b;//将b值赋给a b = tmp; }
int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:a=%d,b=%dn", a, b); Swap(a, b); printf("交换后:a=%d,b=%dn", a, b); return 0; }
若输入34 56
交换前:a=34,b=56
交换后:a=34,b=56
明显没有发生交换,是错误的。
正确示:
#include<stdio.h> void Swap(int* pa, int* pb)// { int tmp = 0; tmp = *pa; *pa = *pb; *pb = tmp; } int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:a=%d,b=%dn", a, b); Swap(&a, &b); printf("交换后:a=%d,b=%dn", a, b); return 0; }
int main() { int a = 0; int b = 0; scanf("%d %d", &a, &b); printf("交换前:a=%d,b=%dn", a, b); Swap(&a, &b); printf("交换后:a=%d,b=%dn", a, b); return 0; }
由于通过址调用,所以在跳出Swap后,仅销毁指针变量,而实参已经发生改变,达到交换数值的目的。
3:练习
(1):写一个函数可以判断一个数是不是素数
#include<stdio.h> #include<math.h> int is_primer(int n) { int j = 0; for (j=2;j<n;j++) { if(n%j == 0) return 0; /* else return 1; 是不能再加上这个的,我们需要的事是从2到n-1均判断。如当n等于9时就出错了 */ { return 1; } int main() { //打印100~200之间的素数 int i = 0; for (i = 100; i <= 200; i++) { //判断i是否为素数 if (is_primer(i) == 1) { printf("%d ", i); } } return 0; }
(2):写一个函数判断一年是不是闰年
int is_leap_year(int y) { if (((y%4==0)&&(y%100!=0)) || (y%400==0)) return 1; else return 0; } int main() { int year = 0; int count = 0; for (year=1000; year<=2000; year++) { //判断y是不是闰年 if (is_leap_year(year) == 1)//leap year就是闰年 { count++; printf("%d ", year); } } printf("ncount = %dn", count); return 0; }
(3):写一个整形有序数组的二分查找
//int right = sizeof(arr)/sizeof(arr[0]) - 1;//right一直是0 //上面的那一行代码是有逻辑错误的, //数组的传参,传递的是数组首元素的地址 //所以sizeof(arr)/sizeof(arr[0])=1,所以1-1=0
#include<stdio.h> int binary_search(int arr[], int a, int sz)//形参为数组、需要查找的整数、数组的元素个数 //本质上arr是一个指针,所以是4个字节 { int left = 0; int right = sz-1; int mid = 0; while (left<=right) { int mid = (right+left)/2;//找中间的元素 if (arr[mid] > a)//中间元素大于查找值,说明在左边 { right = mid - 1; } else if (arr[mid] < a)//中间元素小于查找值,说明在右边 { left = mid + 1; } else { return mid;//中间值等于查找值 } } if (left>right) { return -1;//找不到,返回-1 } } int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10}; //只能在主函数里面定义sz变量,sizeof(arr)在主函数里使用不需要传递地址 int sz = sizeof(arr) / sizeof(arr[0]);//元素的个数 int k = 7; scanf("%d", &k); int ret = binary_search(arr, k, sz);//再多加一个sz变量,传到形参上去 if (-1 == ret) { printf("找不到n"); } else { printf("找到了,下标是:%dn", ret); } return 0; }
(4):写一个函数,每调用一次这个函数,就会将 num 的值增加1
#include<stdio.h> void Add(int* p) { (*p)++;//解引用找到变量再加1,注意这个括号不能忘 } int main() { int num = 0; Add(&num);//因为函数内部需改变外部的值,所以用传址调用 printf("num= %dn",num); Add(&num); printf("num= %dn",num); Add(&num); printf("num= %dn",num); return 0; }
五:函数的嵌套调用和链式访问
函数和函数之间是可以有机的组合的
1.嵌套调用
函数可以根据需要进行相互调用。
#include <stdio.h> void new_line() { printf("hehen"); } void three_line() { int i = 0; for (i = 0; i < 3; i++) { new_line(); } } int main() { three_line(); return 0; }
注:函数不能嵌套定义,但可以嵌套调用
2.链式访问
(1)把一个函数的返回值作为另一个函数的参数。
#include<stdio.h> #include<string.h> int main() { //int len = strlen("abcdef"); //1 //printf("%dn", len); //2 printf("%dn", strlen("abcdef"));//链式访问,把strlen("abcdef")的值作为printf函数的参数 return 0; }
//方法一:递归法 #include<stdio.h> int Fib(int n) { /* if (n == k)//算第k个斐波那契数被计算了多少次 { count++; }*/ if (n<=2) return 1; else return Fib(n - 1) + Fib(n - 2); } //int count = 0; int main() { int n = 0; scanf("%d", &n); int ret = Fib(n);//定义一个ret来接受上面函数的返回值 printf("%d", ret); //printf("count=%dn", count); return 0; }
//方法二:迭代 #include<stdio.h> int Fib(int n) { int a = 1; int b = 1;//前两个数都是1 int c = 1;//不能使c=0,当n小于2时会输出0 while (n>2) { c = a + b; a = b; b = c; n--;//这一步别忘了 } return c; } int main() { int n = 0; scanf("%d", &n); int ret = Fac(n); printf("%d", ret); return 0; }
注意:当我们使用递归的方法时,如果n大时,由于大量的函数调用使得非常容易栈溢出
(2)求n的阶乘:
//非递归法: int Fac1(int n) { int i = 0; int ret1 = 1;//阶乘初始化必然为1 for (i=1; i<=n; i++) { ret *= i; } return ret1; }
//递归法: int Fac2(int n) { if(n<=1) return 1; else return n*Fac*(n-1) } int main() { int n = 0; int ret1 = 0; scanf("%d", &n); int ret = Fac(n);//定义一个ret来接受上面函数的返回值 printf("%d", ret1); return 0; }