首页 > 其他分享 >函数的学习(一)

函数的学习(一)

时间:2024-07-29 20:57:02浏览次数:16  
标签:函数 int 学习 add 参数 printf 形式参数

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

相关文章

  • 随机数函数 和 猜数字游戏(c语言初学者拔高)
    目录1.随机数的生成方法1.1rand()函数1.1.1函数原型1.1.2函数功能1.2srand()函数1.2.1函数原型1.2.2函数功能1.3time()函数1.2.1函数原型1.1.2函数功能1.4设置随机数的范围2.猜数字游戏2.1普通版:结构逻辑解析2.1.1程序代码2.1.2 细节答疑2.2拓......
  • Python 教程(六):函数式编程
    目录专栏列表前言函数定义参数返回值示例函数类型普通函数空函数匿名函数(Lambda函数)嵌套函数函数装饰器高阶函数函数参数位置参数默认参数可变位置参数可变关键字参数函数属性和方法`__name__``__doc__``func.__dict__``func.__defaults__``func.__annotations__`函......
  • 学习教务管理系统的记录
    学习教务管理系统的记录最近学习了基础的c++以及mysql的知识,迫不及待寻找紧密相关的项目来巩固所学知识,经过筛选找了一个教务管理系统的项目,总共一千多行代码。感兴趣可以去GitHub查看原代码很多同学觉得教务系统烂大街了,也觉得简单,但是事实上真正写一个就知道并非想的......
  • JAVA小白学习日记Day12
    CSS定位1.定位属性 在CSS中,position属性用于指定元素在文档流中的定位方式。常用的取值包括:static:默认值,元素遵循正常的文档流布局,不受top、right、bottom、left属性的影响。relative:元素相对于其正常位置进行定位,通过top、right、bottom、left属性可以调整元素相......
  • Trick 学习笔记(1)实数范围内随机
    实数范围内随机学习笔记有一些题目很好玩,它的随机不是在有限整数范围内,而是在实数范围内随机,然后让你算什么什么的期望,而这个期望往往又是并不复杂的分数。在线段上任取\(n\)点就是经典例子。看起来很简单,但是一旦跟无穷相关,感觉不积分不太可做。可惜,我并不会积分,去世!现在......
  • ssm+vue大学生互助学习平台【开题+程序+论文】-计算机毕业设计
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景在当今信息化高速发展的时代,高等教育正经历着前所未有的变革。随着知识更新速度的加快和学习方式的多样化,大学生对于高效、灵活的学习资源及互助机制......
  • 学习C语言第十六天(调试、)
    调试第一题    C第二题    A第三题    C第四题    C第五题    Drelease不可以调试第六题        越界访问访问到了i的地址编程题模拟strcpyvoidmy_strcpy(char*arr1,char*arr2){ while(*arr2) { *a......
  • 深度学习与图像识别day5(机器学习基础)
    线性问题主要处理回归问题,回归问题即预测一个连续问题的数值。计算决定系数(R-squared,也称为R²或系数决定)是衡量回归模型预测准确性的一个常用指标。R-squared值越接近1,表示模型的预测性能越好;如果R-squared值为0,则表示模型只是简单地预测了目标变量的平均值;如果R-squared值为负,......
  • MyBatis-Plus学习笔记
    使用SpringBoot创建工程并添加依赖pom.xml版本:SpringBoot2.3JDK1.8<?xmlversion="1.0"encoding="UTF-8"?><!--定义项目元数据,基于MavenPOM4.0.0模型--><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.......
  • 如何用3个月零基础入门网络安全?_网络安全零基础怎么学习
    前言写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全,实现自己的“黑客梦”。文章的宗旨是:1.指出一些自学的误区2.提供客观可行的学习表3.推荐我认为适合小白学习的资源.大佬绕道哈!→点击获取网络安全资料·攻略←一、自学网络安全学习的误区和陷阱1.不要......