【C语言初阶】函数调用
文章目录
- 【C语言初阶】函数调用
- 四、函数的调用
- 1 传值调用
- 2 传址调用
- 3 不同传参的比较
- 4 函数调用方式
- 4.1 表达式调用
- 4.2 语句调用
- 4.3 实参调用
- 5 练习题
- 5.1 练习1
- 5.2 练习2
- 5.3 练习3
- 5.4 练习4
- 总结:
四、函数的调用
使用函数的过程称为函数调用。
1 传值调用
实参传递的是普通的数值。
- 函数的形参和实参分别占有不同的内存块,形参的修改不会影响实参。
2 传址调用
实参传递的是函数外部变量的地址。
-
传址调用是把函数外部创建的变量的内存地址作为实参传递给形参的一种函数调用的传参方式。
-
这种实参是地址的传参方式让函数和其外部的变量建立起了联系,在函数内可以通过传递的地址间接操作函数外部的变量。
3 不同传参的比较
传址调用实际上也是传值调用的一种,只是传址调用中实参的值是地址。
本质上都是实参传递数值,函数用形参接收传递来的值。
4 函数调用方式
根据函数调用在程序中出现的位置,有下列三种函数调用方式:
-
表达式调用
-
语句调用
-
实参调用
4.1 表达式调用
将函数调用作为表达式,函数的返回值参与表达式的运算,此时要求函数必须有返回值。
int max = MAX(10, 20);//MAX()
4.2 语句调用
函数以语句的形式出现时,将函数调用作为一条语句。
printf("hehe\n");//printf()
4.3 实参调用
将函数调用作为一个函数的实参,要求该函数有返回值。
printf("max = %d\n", MAX(10, 20));//MAX()
5 练习题
5.1 练习1
函数实现,判断一个数是不是素数。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>//sqrt()
int is_prime(int num)
{
//试除法判断是否是素数
int i = 0;
//for (i = 2; i < num; i++)
for (i = 2; i <= sqrt(num); i++)
{
if (num % i == 0)
{
return 0;//不是素数,返回0
}
}
return 1;//是素数,返回1
}
int main()
{
//函数实现,判断一个数是不是素数
int num = 0;
//输入
printf("请输入数字:>");
scanf("%d", &num);
//判断
int ret = is_prime(num);
if (1 == ret)
printf("%d是素数!\n", num);
else
printf("%d不是素数!\n", num);
return 0;
}
解释说明:
1 试除法:把 num 作为被除数,被 2 ~ num-1 之间的每一个整数去除以,如果都不能被整除,那么 num 就是一个素数。
2 进一步优化:num 不必被 2 ~ num-1 之间的每一个数都整除,而只需被 2 ~ √num 之间的每一个数整除就可以了,减少了循环的次数。
5.2 练习2
函数实现,判断一年是不是闰年。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int is_leap_year(int y)
{
//方法一
//if (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0))
// return 1;//是闰年返回1
//else
// return 0;//不是闰年返回0
//方法二
return (((y % 4 == 0) && (y % 100 != 0)) || (y % 400 == 0));
}
int main()
{
//函数实现,判断一年是不是闰年。
int year = 0;
//输入
printf("请输入要判断的年份:>");
scanf("%d", &year);
//判断
int ret = is_leap_year(year);
if (1 == ret)
printf("%d年是闰年!\n", year);
else
printf("%d年不是闰年!\n", year);
return 0;
}
解释说明:
1 闰年判断规则:
(1)四年一闰百年不闰:即如果 year 能够被4整除,但是不能被100整除,则 year 是闰年。
(2)每四百年再一闰:如果 year 能够被400整除,则 year 是闰年。
5.3 练习3
函数实现,一个和整型有序数组的二分查找。
代码示例:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int binary_search(int arr[], int k, int sz)
{
int left = 0;//左下标
int right = sz - 1;//右下标
int mid = 0;//中间下标
while (left <= right)
{
mid = left + (right - left) / 2;//计算中间下标位置
if (arr[mid] > k)//目标数字可能在左半部分
{
right = mid - 1;//更新右下标
}
else if (arr[mid] < k)//目标数字可能在右半部分
{
left = mid + 1;//更新左下标
}
else//目标数字在mid下标位置
{
return mid;//找到目标数字,返回对应下标
}
}
return -1;//循环结束还没找到,返回-1(left > right)
}
int main()
{
//函数实现,一个和整型有序数组的二分查找。
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
int k = 0;
//输入
printf("请输入目标数字:>");
scanf("%d", &k);
//查找
int ret = binary_search(arr, k, sz);
if (ret != -1)
printf("目标数字在数组中的下标位置:>%d\n", ret);
else
printf("目标数字不在数组中!\n");
return 0;
}
解释说明:图示详见:5.3 练习3
本练习将二分查找(折半查找)封装成了一个函数。
5.4 练习4
写一个函数,每调用一次该函数,就将
sum的值增加1。
代码示例:
#include<stdio.h>
int test1(int n)
{
return (n + 1);
}
void test2(int* pi)
{
(*pi)++;
}
int main()
{
//写一个函数,每调用一次该函数,就将sum的值增加1。
int sum1 = 0;
int sum2 = 0;
//方法一
sum1 = test1(sum1);
printf("sum1 = %d\n", sum1);
sum1 = test1(sum1);
printf("sum1 = %d\n", sum1);
//方法二
test2(&sum2);
printf("sum2 = %d\n", sum2);
test2(&sum2);
printf("sum2 = %d\n", sum2);
return 0;
}
总结:
本节介绍了什么是函数调用以及函数调用使用的方式;讲解了什么是传值调用和传址调用,以及它们之间的区别和联系。
感谢您的阅读,如有任何错误,欢迎您的批评指正!
本文详细讲解了C语言中函数调用的基本概念,包括传值调用与传址调用的区别,以及表达式调用、语句调用和实参调用的使用。还通过实例演示了如何实现素数判断、闰年判断和二分查找,并展示了如何通过函数改变变量值的不同方式。
6963

被折叠的 条评论
为什么被折叠?



