目录
- 函数调用
- 传值调用
- 传址调用
- 练习题
- 嵌套调用
- 链式访问
函数调用
函数调用分为传值调用和传址调用
传值调用
传值调用时,函数的形参和实参分别有着自己的内存空间,形参的改变不会影响实参。在上文中说到的利用一个函数实现两个整数的交换的错误写法就是因为我们将它传值调用。
传址调用
传址调用是把函数外部创建的变量的地址传递给函数参数(也就是通过指针访问函数外部的变量)。这样的方式可以让函数与函数外部的变量建立起真正的联系,可以在函数内部直接操作函数外部的变量。在上文中说到的利用一个函数实现两个整数的交换的正确写法就是因为我们将它传址调用。房子里面的内容会变,但房子本身并不会变。
练习题
1.写一个函数判断一个数是不是素数。
#include<stdio.h>
#include<math.h>int is_prime(int x)
{for (int j = 2; j <= sqrt(x); j++) //方法不唯一{if (x % j == 0)return 0; //不是素数返回0}return 1; //是素数返回1
}
int main()
{int i = 0;int n = 0;scanf("%d", &n);for (i = 2; i <= n; i++) //最小的素数是2{if (is_prime(i) == 1)printf("%d ", i);}return 0;
}
2.写一个函数判断某一年是不是闰年。
#include<stdio.h>int is_leap_year(int x)
{return ((x % 4 == 0) && (x % 100 != 0)) || (x % 400 == 0);//满足条件则为真
}
int main()
{int year_start = 0;int year_end = 0;scanf("%d %d", &year_start, &year_end);for (int i = year_start; i <= year_end; i++){if (is_leap_year(i) == 1)printf("%d ", i);}return 0;
}
3.写一个函数,实现整型有序数组的二分查找。
#include<stdio.h>int binary_search(int arr[], int n, int sz)
{int left = 0;int right = sz - 1;while (left <= right){//int mid = (left + right) / 2; //不建议这样,容易导致溢出int mid = left + (right - left) / 2;if (arr[mid] < n){left = mid + 1;}else if (arr[mid] > n){right = mid - 1;}else return mid;}return -1;
}
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int n = 0;scanf("%d", &n);int sz = sizeof(arr) / sizeof(arr[0]);int result = binary_search(arr, n, sz);if (result == -1)printf("没找到\n");else printf("找到了,下标是%d", result); return 0;
}
嵌套调用
函数与函数之间可以互相调用。
示例:
#include<stdio.h>void fx1()
{printf("hello world\n");
}void fx2()
{for (int i = 0; i < 3; i++){fx1();}
}
int main()
{fx2();return 0;
}
注意:函数可以嵌套调用,但是不能嵌套定义
//错误示范伪代码
int add() //定义add函数
{int x = 0;int y = 0;return x + y;void pt() //定义pt函数{printf("hello world\n");}
}
链式访问
链式访问是把一个函数的返回值作为另外一个函数的参数。
将库函数的返回值作为库函数的参数肯定是最简单的:
//求字符串长度
#include<stdio.h>
#include<string.h>int main()
{//int length = strlen("abcdefg");//printf("%d\n", length);printf("%d\n",strlen("abcdefg"));return 0;
}
我们再来看一个:
#include<stdio.h>int main()
{printf("%d", printf("%d", printf("%d", 43)));//没空格printf("\n");printf("%d ", printf("%d ", printf("%d ", 43)));//有空格return 0;
}
没空格和有空格这两行输出的结果一样吗?
我们发现结果并不一样,打开cpluspluss网站,搜索printf:
所以说,printf的返回值是打印在屏幕上字符的个数,分析一下: