当前位置: 首页 > article >正文

【C语言】第五期——函数

目录

0 前言 

1 定义函数

2 调用函数

3 函数的实参和形参

4 函数声明

5 作用域

5.1 局部变量和全局变量

5.2 static关键字

5.2.1 修饰局部变量

5.2.2 修饰全局变量

5.2.3 修饰函数

6 函数的返回值

6.1 return语句

6.2 函数返回值的类型

7 函数的其他形式

7.1 函数作为表达式

7.2 函数作为实参


0 前言 

函数是组织好的、可重复使用的、用于执行指定任务的代码块。函数是 C 语言程序实现模块化思想的关键。

在C语言中函数分为以下两种:

(1)库函数:由系统或第三方库提供,直接调用即可,无需了函数内部实现,例如printf、getchar 等函数

(2)用户自定义函数:由程序员手动封装,需要了解函数内部实现 以上两种函数都是程序中比较常用的,一般情况下,如果系统库已经提供了实现某个功能的函数,直接 调用系统库函数即可,否则用户需要自己编写代码实现

1 定义函数

 return_type function_name( parameter list )
 {
     body of the function
 }

返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型,有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void

函数名称(function_name):这是函数的实际名称。函数名和参数列表一起构成了函数签名

参数(parameter):参数就像是占位符,当函数被调用时,您向参数传递一个值,这个值被称为 实际参数,参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包 含参数

函数主体:函数主体包含一组定义函数执行任务的语句 

无参无返回值函数的定义

void print()
{
	printf("我是一个无返回值无参数的函数");
}

有参数无返回值函数的定义

void sum(int a, int b)
{
	printf("a+b=%d", a + b);
}

有参数有返回值函数的定义

int mul(int a, int b)
{
	return a * b;
}

定义函数注意事项:
(1)同一个.c 文件中,函数名之间不能重名
(2)用户自定义函数一般需要放置在调用它的函数之前,如果放置在调用它的函数之后就需要添加函数声明
(3)函数之间不能嵌套定义,也就是说函数内部不能再定义函数


2 调用函数

定义了函数之后,我们可以通过函数名()的方式来调用,如果函数有参数调用的时候还需要传入参数:函数名(参数1,参数2),如果函数有返回值我们还可以接收函数的返回值

注意: 定义函数的时候需要定义到 main函数上面,如果定义到main函数下面需要进行声明

详细看4 函数声明

#include <stdio.h>
void print()
{
	printf("我是一个无返回值无参数的函数\n");
}

void sum(int a, int b)
{
	printf("a+b=%d\n", a + b);
}


int mul(int a, int b)
{
	return a * b;
}

int main()
{
	print();
	sum(10, 20);
	int c = mul(2, 4);
	printf("c=", c);
	return 0;
}


3 函数的实参和形参

形参: 就是函数定义时函数名后面小括号中的变量,本质上就是局部变量,在该函数被调用时,由外部为该形参变量进行赋值,形参变量与局部变量的生命周期是一样的,只能在本函数内使用,函数执行结束形参变量就被释放,需要注意的是,形参只能是变量

实参:调用函数的时候实际传入的数据就是函数的实参

#include <stdio.h>
void sum(int a, int b) // 形参
{
	printf("a+b=%d\n", a + b);
}
int mul(int a, int b) // 形参
{
	return a * b;
}
int main()
{
	sum(10, 20); // 实参
	int a = 2;
	int b = 3;
	int c = mul(a, b);  //实参
	printf("c=", c);
	return 0;
}

4 函数声明

注意: 定义函数的时候需要定义到 main函数上面,如果定义到main函数下面需要进行声明

当把函数定义到main函数下面的时候,默认main函数里面是无法调用这个函数的

#include <stdio.h>
int main()
{
	int a = 2;
	int b = 3;
	int c = mul(a, b); // 实参
	printf("c=%d", c);
	return 0;
}
int mul(int a, int b) // 形参
{
	return a * b;
}

此代码会提示: main.c:8:13: warning: implicit declaration of function 'mul' [ Wimplicit-function-declaration]

如果想把自定义函数定义到main函数下面,我们就需要声明函数

#include <stdio.h>
// 声明函数
int mul(int a, int b);
int main()
{
	int a = 2;
	int b = 3;
	int c = mul(a, b); // 调用函数
	printf("c=%d", c);
	return 0;
}
// 定义函数
int mul(int a, int b)
{
	return a * b;
}

5 作用域

5.1 局部变量和全局变量

局部变量:定义在函数内部的变量被称为局部变量。局部变量只能在当前函数中访问,不能跨函数访问,函数执行结束时,局部变量将被系统回收

全局变量: 全局变量是指在整个程序中都可见的变量。它们可以被任何函数调用并使用。全局变量通常在程序开始时声明,并在程序执行期间保持不变,即使它们的作用域已经消失。虽然全局变量可以提高 程序的可重用性和可扩展性,但它们也可能会带来一些潜在的问题,如命名冲突和安全问题

#include <stdio.h>
int x = 2; // 全局变量
int sum()
{
	int a = 10; // 局部变量
	int b = 20;
	printf("a=%d", a);
	printf("b=%d", b);
	printf("b=%d", x); // 正确
}
int main()
{
	sum();
	// printf("a=%d", a); // 错误   局部变量只能在作用域内访问
	printf("a=%d", x); // 正确
	return 0;
}

5.2 static关键字

5.2.1 修饰局部变量

当 static 修饰局部变量时,该变量被称为静态局部变量。其主要作用如下:

1.延长变量的生命周期:普通局部变量存储在栈区,在函数调用结束后就会被销毁;而静态局部变量存储在静态存储区,在程序的整个运行期间都存在,不会因为函数调用结束而被销毁。
2.保持变量的值:静态局部变量只会在第一次函数调用时进行初始化,之后再次调用该函数时,静态局部变量会保留上一次调用结束时的值。

#include <stdio.h>

void test() {
    // 静态局部变量,只会在第一次调用函数时初始化
    static int count = 0;
    count++;
    printf("count = %d\n", count);
}

int main() {
    test();
    test();
    test();
    return 0;
}

代码解释
在 test 函数中,count 是一个静态局部变量。第一次调用 test 函数时,count 被初始化为 0,然后自增为 1 并输出;第二次调用 test 函数时,count 不会再次被初始化为 0,而是保留上一次的值 1,然后自增为 2 并输出;同理,第三次调用时输出 3。


5.2.2 修饰全局变量

当 static 修饰全局变量时,该变量被称为静态全局变量。其主要作用是限制变量的作用域,使该变量只能在定义它的源文件中使用,而不能被其他源文件通过 extern 关键字引用

// file1.c
#include <stdio.h>
// 静态全局变量,只能在 file1.c 中使用
static int staticGlobalVar = 10;

void printStaticGlobalVar() {
    printf("staticGlobalVar = %d\n", staticGlobalVar);
}
// file2.c
// 尝试在另一个源文件中使用静态全局变量,这是错误的
// extern int staticGlobalVar; 

int main() {
    // 这里不能直接使用 staticGlobalVar
    // printf("staticGlobalVar = %d\n", staticGlobalVar);
    return 0;
}

代码解释
在 file1.c 中定义了一个静态全局变量 staticGlobalVar,它只能在 file1.c 文件中使用。在 file2.c 中,即使使用 extern 关键字声明,也无法引用该变量。


5.2.3 修饰函数

当 static 修饰函数时,该函数被称为静态函数。其主要作用也是限制函数的作用域,使该函数只能在定义它的源文件中使用,而不能被其他源文件通过 extern 关键字调用

// file1.c
#include <stdio.h>
// 静态函数,只能在 file1.c 中使用
static void staticFunction() {
    printf("This is a static function.\n");
}

void callStaticFunction() {
    staticFunction();
}
// file2.c
// 尝试在另一个源文件中声明并调用静态函数,这是错误的
// extern void staticFunction(); 

int main() {
    // 这里不能直接调用 staticFunction
    // staticFunction();
    return 0;
}

在 file1.c 中定义了一个静态函数 staticFunction,它只能在 file1.c 文件中被调用。在 file2.c 中,即使使用 extern 关键字声明,也无法调用该函数。


6 函数的返回值

按照有无返回值,函数可以分为无返回值函数和有返回值函数。对于无返回值函数前面已经介绍过,这类函数的返回值类型为 void

对于有返回值函数,需要显式指定的返回值类型这类函数的返回值通过 return 语句得到。 retum 是C语言中的关键字,后面可以跟常量、变量、表达式等。例如:

return 100;    //返回常量 100
return a;      //返回变量 a的值
return a + b;  //返回表达式a+b 的运行结果

说明:retumn 语句后面可以加括号也可以不加,例如:

return (100);   //返回常量 100
return (a);     //返回变量 a的值
return (a+b);   //返回表达式a+b 的运行结果

6.1 return语句

return语句的作用主要有以下两个:

(1)返回值:当函数执行到return 语句时,会将return 后面的结果值返回给主调函数,也就是说,在主函数中可 以得到被调函数中的数据

(2)终止程序:当return 语句被执行时,它下面的语句将不再执行。因此,retumn 语句可以看作是函数结束的标志,一般放置在函数末尾,以免影响其他语句的正常执行,return 还可以在无返回值的函数中作为终止函数使用


6.2 函数返回值的类型

函数返回值类型指的是函数返回数据的类型。例如:

 char getChar();
 int getInt();
 float getFloat();
 double getDouble();
 void print();

以上5个函数的返回值类型分别为: 字符型、整型、单精度浮点型、双精度浮点型、无返回值型,当主调函数中需要得到被调函数的返回值时,也要定义与其函数返回值类型对应的变量进行接收


7 函数的其他形式

7.1 函数作为表达式

#include <stdio.h>
int sum(int a, int b)
{
	return a + b;
}
int main(void)
{
	int c = 100 + sum(10, 20);
	printf("c=%d\n", c);
	return 0;
}

7.2 函数作为实参

#include <stdio.h>
// 声明函数
int mul(int a, int b);
int main()
{
	int a = 2;
	int b = 3;
	printf("c=%d", mul(a, b));
	return 0;
}
// 定义函数
int mul(int a, int b)
{
	return a * b;
}

http://www.kler.cn/a/557184.html

相关文章:

  • windows下docker使用笔记
  • 重构谷粒商城07:Git一小时快速起飞指南
  • 12.Docker 的资源限制
  • Github 开源 AI 知识库推荐
  • Ansible 学习笔记
  • Python----数据结构(哈希表:哈希表组成,哈希冲突)
  • Java函数式接口的巧妙应用
  • 2025.2.19——1500
  • uniapp 整合openlayers 编辑图形文件并上传到服务器
  • 从零搭建微服务项目(全)
  • QARepVGG--含demo实现
  • 蓝桥杯——lcd显示
  • 【Agent的革命之路——LangGraph】工作流中的 Command 模式
  • XiaoMi Mi5(gemini) 刷入Ubuntu Touch 16.04——安卓手机刷入Linux
  • CLAM模型使用教程
  • 想学python进来看看把
  • 在本地使用 Llama 3.2-Vision:分步指南
  • python学智能算法(二)|模拟退火算法:进阶分析
  • Jetson Orin Nano烧录系统
  • 【多语言生态篇一】【DeepSeek×Java:Spring Boot微服务集成全栈指南 】