1.定义
C语言的函数是一段可被重复调用的代码块,可以执行特定的任务并返回一个值。每个函数由函数头、函数体和函数返回值组成。
2.函数的分类
C语言中的函数可以根据不同的特性进行分类,常见的分类如下:
(1)标准函数(库函数):这些函数是C语言提供的预定义函数,可以直接在程序中调用。标准函数包括输入输出相关函数(如printf、scanf)、字符串处理函数(如strlen、strcpy)以及数学函数(如sin、cos)等。
(2)用户自定义函数:这些函数由程序员根据需要自行定义,可以根据具体任务来划分和命名函数。用户自定义函数可以实现程序的功能模块化,提高代码可读性和重复利用性。
(3)递归函数:递归函数是指在函数的定义中直接或间接地调用自身的函数。递归函数通常用于解决具有递归结构的问题,比如计算阶乘、斐波那契数列等。
(4)内联函数:内联函数是一种在编译时将函数调用处替换为函数体的机制,用于提高函数调用的效率。内联函数通常用于执行简单、频繁调用的代码,减少函数调用的开销。
(5)回调函数:回调函数是一种通过函数指针作为参数传递给其他函数,并在特定事件或条件发生时被调用的函数。回调函数通常用于实现事件处理、回调机制等。
(6)函数指针:函数指针是指向函数的指针变量,可以将函数作为参数传递给其他函数、存储函数的地址以及通过指针调用函数。函数指针可以动态地选择和调用不同的函数。
这些是C语言中常见的函数分类,不同类型的函数可以根据具体需求和场景来选择和使用。
2.1库函数
在C语言中,库函数是指预定义的、提供给程序员使用的函数集合。这些函数由C语言标准库(也称为C标准库)提供,包括许多常用的功能,如输入输出、字符串处理、数学运算、内存管理等。库函数可以通过#include语句引入相应的头文件,然后在程序中直接调用。
以下是一些常见的库函数及其使用方法:
输入输出函数:C标准库提供了一系列用于输入输出的函数,如printf、scanf、getchar、putchar等。这些函数允许程序员在屏幕上进行输入和输出操作。例如,使用printf函数打印字符串到屏幕上:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
字符串处理函数:C标准库提供了一些用于处理字符串的函数,如strlen、strcpy、strcat等。这些函数可以用于字符串的拷贝、连接、比较等操作。例如,使用strcpy函数将一个字符串拷贝到另一个字符串中:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20];
strcpy(str2, str1);
printf("Copied string: %s\n", str2);
return 0;
}
除了上述示例外,C标准库还提供了许多其他函数,如内存分配函数(malloc、free)、文件操作函数(fopen、fclose)、日期和时间函数(time、strftime)等。可以通过查阅相关的C语言文档或参考书籍来了解更多库函数的使用方法。
2.2用户自定义函数
C语言中的用户自定义函数是指用户根据自己的需求定义的函数。通过自定义函数,用户可以将一些常用的代码封装在函数内部,方便重复使用。
用户自定义函数的定义与声明分为两部分:函数声明和函数定义。
函数声明用于告诉编译器该函数的存在和函数的参数类型和返回值类型。函数声明一般放在程序的开头,通常在头文件中进行声明。
函数定义是函数的具体实现,包括函数的参数列表、函数体和返回值。函数定义一般放在程序的其他函数之后。
以下是一个简单的用户自定义函数的例子:
#include <stdio.h>
// 函数声明
int add(int a, int b);
// 函数定义
int add(int a, int b) {
return a + b;
}
int main() {
int num1 = 5;
int num2 = 7;
int sum = add(num1, num2);
printf("The sum is %d\n", sum);
return 0;
}
在上面的例子中,我们定义了一个名为add的函数,它接受两个整数作为参数,并返回这两个整数的和。在main函数中,我们调用了add函数,并将num1和num2作为实际参数传递给add函数。最后,将add函数的返回值赋给sum,并打印出来。
通过使用用户自定义函数,可以使程序结构更加清晰,模块化,提高代码的复用性和可维护性。
自定义函数虽然理解起来感觉简单,但实际操作起来还是会有各种各样的问题,比如:
写一个函数可以交换两个整型变量的内容,代码如下:
#include<stdio.h>
void Swap(int x, int y)
{
int z = 0;
z = x;
x = y;
y = z;
}
int main()
{
int a = 0;
int b = 0;
scanf_s("%d %d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
Swap(a, b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
上面的代码看似没有问题,实际上是错误,运行结果如下:
从上面的运行结果来看,说明并没有交换变量a、b中的值,为了方便理解,我们使用调试功能看看是哪方面出错。
首先按F10进入调试,打开监视功能,观察a、b、x、y、&a、&b、&x、&y的值,如下所示:
按F11可依次运行代码,我们设定a=10,b=20,进入所写的函数程序后,我们可以看到,x=20,y=10说明两个变量的值已经交换,但是输出的结果仍然没有交换值,原因就在于地址&a和&x、地址&b和&y不同。
这里涉及另外一个知识点:实际参数和形式参数
在C语言中,实际参数(Actual Parameter)和形式参数(Formal Parameter)是在函数调用过程中使用的术语。
形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成后就自动销毁了,因此形式参数只有在函数中有效。
实际参数是函数调用时传递给函数的具体数值,也就是实际参与运算的值。实际参数可以是常量、变量、表达式或其他函数的返回值。在函数调用时,实际参数传递给形式参数,并且按照顺序进行对应。
通过将实际参数传递给形式参数,可以在函数内部使用这些实际参数进行计算和操作,从而实现函数的功能。
需要注意的是,形式参数和实际参数之间的数据传递是通过值传递(pass by value)进行的,这意味着在函数调用时,实参的值被复制到了对应的形参中,函数内对形参的修改不会影响到实参的值。
换句话说,当实际参数传递给形式参数时,形式参数只是实际参数的一份临时拷贝,对形式参数的修改不会影响实际参数。
接下来,回到写一个函数可以交换两个整型变量的内容,既然修改形式参数并不能影响实际参数,那么我们不妨考虑,设计一函数直接对实际参数进行修改,那么如何修改呢?这就要用到前面学到的指针的知识。
具体代码如下:
#include<stdio.h>
int Swap(int* x, int* y)
{
int z = 0;
z = *x;
*x = *y;
*y = z;
}
int main()
{
int a = 0;
int b = 0;
scanf_s("%d %d", &a, &b);
printf("交换前:a=%d b=%d\n", a, b);
Swap(&a, &b);
printf("交换后:a=%d b=%d\n", a, b);
return 0;
}
运行结果如下:
从上面的结果可知,a和b的值确实发生了交换。
需要注意的是,并不是所有的函数传递参数都要传递实际参数的地址,例如下面这个实现两个变量求和的代码:
#include <stdio.h>
// 函数定义
void add(int a, int b) {
int sum = a + b;
printf("The sum is %d\n", sum);
}
int main() {
int x = 5;
int y = 3;
// 函数调用,x和y作为实际参数传递给add函数的形式参数a和b
add(x, y);
return 0;
}
这里传递仅是实际参数的值,而非地址。
总的来说,函数是否传参是否传递实际参数的地址,需要看我们要实现什么样的功能;如果想要修改实际参数的值,函数传递的参数就是实际参数的地址,否则不用传递地址。
标签:函数,int,学习,add,参数,printf,形式参数 From: https://blog.csdn.net/NJL12138/article/details/140700226