C语言函数使用详解:分类、声明、调用与实战练习
C语言中函数是模块化编程的核心,分为标准库提供的库函数和开发者编写的自定义函数。理解形参与实参的区别至关重要:传值调用无法修改外部变量,而传址调用通过指针实现数据交换。本文将详解函数的声明、定义规则,并通过素数判断、闰年计算等典型代码示例,展示如何正确使用函数解决实际问题。
一、函数的基本概念与分类
在C语言开发中,函数主要用于封装可复用的代码逻辑。根据来源不同,函数主要分为两类:
1. 库函数(Library Functions)
库函数是由C语言标准库提供的基础函数集合,旨在提升开发效率并确保程序的可移植性。由于这些函数不属于用户自定义范畴,使用时必须引入对应的头文件(Header File)。
注意:所有库函数使用前均需通过 #include 语句包含其所在头文件,否则编译器可能报错或发出警告。
例如:使用字符串长度函数 strlen 时,需包含 <string.h>。
2. 自定义函数(Custom Functions)
自定义函数由程序员根据具体需求编写,拥有函数名、返回值类型和参数列表。其灵活性允许开发者设计复杂的业务逻辑,但因为是独立实现的,所以不需要也不依赖标准的库头文件。
3. 常见库函数分类
C标准库提供了丰富的功能模块,主要包括:
- IO函数:用于输入输出,如
printf,scanf,getchar,putchar。 - 字符串操作函数:处理文本数据,如
strcmp(比较),strlen(求长)。 - 字符操作函数:如
toupper(转大写)。 - 内存操作函数:涉及底层内存管理,如
memcpy(内存拷贝),memcmp(内存比较)。 - 时间/日期函数:获取系统时间,如
time。 - 数学函数:数值计算,如
sqrt(开方),pow(幂运算)。
二、函数的参数传递机制
函数调用时的数据传递方式直接影响外部变量的状态,主要包含传值调用和传址调用两种模式。
第1步:传值调用(Call by Value)
目的:仅将实参的副本传递给形参,确保函数内部操作不影响原始变量。
机制说明:在传值调用中,形式参数(形参)和实际参数(实参)分别占用不同的内存空间。对形参的任何修改仅限于该函数的作用域内,不会反映到主函数中的实参上。
#include<stdio.h>
void swap(int x, int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
int main()
{
int a = 10;
int b = 20;
printf("交换前=%d %d\n", a, b);
swap(a, b); // 仅传递a和b的值
printf("交换后=%d %d\n", a, b); // a和b保持不变
return 0;
}
第2步:传址调用(Call by Reference via Pointer)
目的:让函数能够直接访问和修改外部变量,建立函数内外部的真正联系。
机制说明:传址调用是将变量的内存地址作为参数传递给函数。函数接收的是指针,通过解引用操作符(*)可以间接访问并改变指针指向的内存地址中的值。
操作要点:定义指针类型的参数,并在调用时传入变量的地址(&运算符)。
#include<stdio.h>
// 参数接收的是地址
void swap(int * pa, int * pb )
{
int z = 0;
z = *pa; // 获取pa指向的值
*pa = *pb; // 将pb指向的值赋给pa指向的空间
*pb = z; // 恢复原pa的值到pb
}
int main()
{
int a = 10;
int b = 20;
printf("交换前=%d %d\n", a, b);
swap(&a, &b); // 传递a和b的地址
printf("交换后=%d %d\n", a, b); // a和b的值发生交换
return 0;
}
三、函数的声明与定义
正确区分函数的声明(Declaration)和定义(Definition)是避免链接错误的关键。
1. 函数声明
函数声明的作用是告诉编译器该函数的存在,明确其返回值类型和参数列表的具体形式。声明不包含函数体,通常位于函数的使用之前,习惯上放在头文件中,以满足“先声明后使用”的原则。
以下代码展示了在 main 函数前进行显式声明的情况:
#include<stdio.h>
int main()
{
int a = 10;
int b = 20;
// 函数声明 - 告知编译器存在Add函数,接受两个int返回int
int Add(int, int);
int c = Add(a, b); // 调用函数
printf("%d\n", c);
return 0;
}
// 函数定义 - 具体的实现逻辑
int Add(int x, int y)
{
return x + y;
}2. 函数定义
函数定义是函数的具体实现,包含了完整的函数体和逻辑代码。它既向编译器注册了函数,也提供了执行所需的代码块。定义是一种比声明更完整的实体描述。
#include<stdio.h>
// 函数定义
int add(int a, int b)
{
return a + b; // 返回两数之和
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b); // 获取用户输入
int c = add(a, b); // 函数调用
printf("%d\n", c); // 输出结果
return 0;
}四、形参与实参的辨析
清晰理解形式参数与实际参数的关系,有助于编写正确的函数接口。
1. 形式参数(Formal Parameter)
形参出现在函数定义部分,用于接收调用者传入的数据。它们只是函数内部的局部变量,仅在函数执行期间存在。
2. 实际参数(Actual Parameter)
实参出现在函数调用部分,可以是常量、变量或表达式。实参将具体的值或地址传递给形参。
五、函数应用实战练习
通过以下三个经典算法题目,巩固函数的定义、调用及逻辑处理能力。
练习1:求两个整数的较大值
难易程度:⭐(入门)
此题考察基本的条件判断与返回值使用。
#include<stdio.h>
// 函数定义:接收两个整数,返回较大值
int get_max(int score_one, int score_two)
{
// 三元运算符:若score_one大则返回前者,否则返回后者
return score_one > score_two ? score_one : score_two;
}
int main()
{
int score_one = 0;
int score_two = 0;
scanf("%d %d", &score_one, &score_two);
// 函数调用:传入实参,接收返回值
int max = get_max(score_one, score_two);
printf("max=%d\n", max);
return 0;
}练习2:打印100~200之间的素数
难易程度:⭐⭐(进阶)
素数(质数)是指大于1且除了1和本身外不能被其他自然数整除的数。我们需要一个辅助函数来判断单个数字是否为素数,并在主循环中调用。
#include<stdio.h>
// 判断是否为素数:是则返回1,否则返回0
int is_prime(int i)
{
int j = 0;
// 从2遍历到i-1,尝试除尽
for (j = 2; j < i; j++)
{
if (i % j == 0) // 若能被整除,说明不是素数
{
return 0;
}
}
// 遍历结束未找到因子,则为素数
return 1;
}
int main()
{
int i = 0;
int count = 0; // 统计素数个数
// 遍历100到200之间的所有整数
for (i = 100; i <= 200; i++)
{
// 调用函数判断
if (is_prime(i) == 1)
{
printf("%d ", i); // 打印素数
count++; // 计数器加1
}
}
printf("\ncount = %d\n", count);
return 0;
}练习3:打印1000~2000之间的闰年
难易程度:⭐⭐(进阶)
闰年的判定规则有两个: 1. 能被4整除且不能被100整除; 2. 或者能被400整除。
#include<stdio.h>
// 判断是否为闰年:是则返回1,否则返回0
int is_leap_year(int n)
{
// 满足第一个条件:能被4整除且不能被100整除
if (n % 4 == 0 && n % 100 != 0)
{
return 1;
}
// 满足第二个条件:能被400整除
else if (n % 400 == 0)
{
return 1;
}
// 均不满足
else
{
return 0;
}
}
int main()
{
int i;
int count = 0; // 统计闰年个数
// 遍历1000到2000
for (i = 1000; i <= 2000; i++)
{
// 调用函数判断
if (is_leap_year(i) == 1)
{
printf("%d ", i); // 打印闰年
count++; // 计数器加1
}
}
printf("\ncount = %d\n", count);
return 0;
}以上就是C语言函数使用方法(分类、调用、声明定义及实例)的详细内容,更多关于C语言函数教程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









