C 语言编程教程

C 语言 - 首页

C 语言基础

C 语言 - 概述 C 语言 - 特性 C 语言 - 发展历史 C 语言 - 环境设置 C 语言 - 程序结构 C 语言 - Hello World C - 编译过程 C - 注释 C - 标记 C - 关键字 C - 标识符 C - 用户输入 C - 基本语法 C - 数据类型 C - 变量 C - 整数提升 C - 类型转换 C - 类型转换 C - 布尔值

C 语言中的常量和文字

C - 常量 C - 字面量 C - 转义序列 C - 格式说明符

C 语言中的运算符

C - 运算符 C - 算术运算符 C - 关系运算符 C - 逻辑运算符 C - 位运算符 C - 赋值运算符 C - 一元运算符 C - 递增和递减运算符 C - 三元运算符 C - sizeof 运算符 C - 运算符优先级 C - 其他运算符

C 语言中的决策

C - 决策 C - if 语句 C - if...else 语句 C - 嵌套 if 语句 C - switch 语句 C - 嵌套 switch 语句

C 语言中的循环

C - 循环 C - While 循环 C - For 循环 C - Do...while 循环 C - 嵌套循环 C - 无限循环 C - Break 语句 C - Continue 语句 C - goto 语句

C 语言中的函数

C - 函数 C - Main 函数 C - 按值调用函数 C - 按引用调用函数 C - 嵌套函数 C - 可变参数函数 C - 用户定义函数 C - 回调函数 C - return 语句 C - 递归

C 语言中的作用域规则

C - 作用域规则 C - 静态变量 C - 全局变量

C 语言中的数组

C - 数组 C - 数组的属性 C - 多维数组 C - 将数组传递给函数 C - 从函数返回数组 C - 可变长度数组

C 语言中的指针

C - 指针 C - 指针和数组 C - 指针的应用 C - 指针运算 C - 指针数组 C - 指向指针的指针 C - 将指针传递给函数 C - 从函数返回指针 C - 函数指针 C - 指向数组的指针 C - 指向结构体的指针 C - 指针链 C - 指针 vs 数组 C - 字符指针和函数 C - NULL 指针 C - void 指针 C - 悬垂指针 C - 解引用指针 C - Near、Far 和 Huge 指针 C - 指针数组的初始化 C - 指针与多维数组

C 语言中的字符串

C - 字符串 C - 字符串数组 C - 特殊字符

C 语言的结构体和联合

C - 结构体 C - 结构体和函数 C - 结构体数组 C - 自引用结构 C - 查找表 C - 点 (.) 运算符 C - 枚举(或 enum) C - 结构填充和打包 C - 嵌套结构 C - 匿名结构和联合 C - 联合 C - Bit 位字段 C - Typedef

C 语言中的文件处理

C - 输入和输出 C - 文件 I/O(文件处理)

C 语言中的预处理器

C - 预处理器 C - #pragma 编译指示 C - 预处理器操作符 C - 宏 C - 头文件

C 语言中的内存管理

C - 内存管理 C - 内存地址 C - 存储类

C 其他主题

C - 错误处理 C - 可变参数 C - 命令执行 C - 数学函数 C - static 静态关键字 C - 随机数生成 C - 命令行参数

C 语言编程资源

C语言问题与解答答案 C语言快速指南 C语言速查表 C语言实用资源 C语言讨论


C 语言中的函数

C 语言中的函数是一段可复用的代码块,用于执行单一相关的操作。每个 C 语言程序至少包含一个函数,即 main(),所有最简单的程序都可以定义其他函数。

当某个问题的算法涉及冗长复杂的逻辑时,它会被分解成更小、独立且可复用的代码块。这些小代码块在不同的编程语言中有不同的名称,例如 模块子例程函数方法

您可以将代码拆分成多个独立的函数。如何在不同的函数之间划分代码由您决定,但从逻辑上讲,这种划分应该确保每个函数执行特定的任务。

函数声明会告知编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

C 标准库提供了许多可供程序调用的内置函数。例如,strcat() 用于连接两个字符串,memcpy() 用于将一个内存位置复制到另一个位置,以及许多其他函数。

C 语言中的模块化编程

函数旨在执行作为整个过程一部分的特定任务。这种软件开发方法称为模块化编程

模块化编程采用自上而下的软件开发方法。编程解决方案有一个主例程,通过该主例程可以调用较小的独立模块(函数)。

每个函数都是一个独立、完整且可重用的软件组件。函数被调用时,会执行指定的任务,并将控制权返回给调用例程,并可选地返回其处理结果。

这种方法的主要优点是代码易于理解、开发和维护。

C 语言中的库函数

C 语言提供了许多库函数,包含在不同的头文件中。例如,stdio.h 头文件包含 printf() 和 scanf() 函数。同样,math.h 头文件包含许多函数,例如 sin()、pow()、sqrt() 等等。

这些函数执行预定义的任务,可以根据需要在任何程序中调用。但是,如果您找不到合适的库函数来满足您的目的,您可以定义一个。

在 C 语言中定义函数

在 C 语言中,任何函数都需要提供原型的前向声明。库函数的原型位于相应的头文件中。

对于用户定义的函数,其原型位于当前程序中。函数的定义和原型声明应该匹配。

函数中的所有语句执行完成后,程序流程返回到调用环境。函数可能会随流程控制一起返回一些数据。

C 语言中的函数声明

函数声明会告知编译器函数名称以及如何调用该函数。函数的实际主体可以单独定义。

函数声明包含以下部分 -

返回类型 函数名(参数列表);

对于上面定义的函数 max(),函数声明如下 -

int max(int num1, int num2);

函数声明中参数名称并不重要,只需要其类型,因此以下声明也是有效的 -

int max(int, int);

当您在一个源文件中定义一个函数并在另一个文件中调用该函数时,需要进行函数声明。在这种情况下,您应该在调用该函数的文件顶部声明该函数。

C 语言中函数的组成部分

C 编程语言中函数定义的一般形式如下 -

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

C 语言中的函数定义由函数头函数体组成。以下是函数的所有组成部分 -

  • 返回类型 - 函数可以返回一个值。return_type 是函数返回值的数据类型。某些函数执行所需的操作而不返回值。在这种情况下,return_type 是关键字 void。
  • 函数名称 - 这是函数的实际名称。函数名称和参数列表共同构成了函数签名。
  • 参数列表 - 参数(也称为参数)就像一个占位符。调用函数时,您将一个值作为参数传递。该值称为实际参数或实参。参数列表指的是函数参数的类型、顺序和数量。参数是可选的;也就是说,函数可以不包含任何参数。
  • 函数体 − 函数体包含一组定义函数功能的语句。

C 语言中的函数应该具有返回类型。函数返回的变量类型必须是函数的返回类型。在上图中,add() 函数返回 int 类型。

示例:C 语言中的用户定义函数

在此程序中,我们使用了一个名为 max() 的用户定义函数。该函数接受两个参数 num1num2,并返回两者之间的最大值 −

#include <stdio.h>

/* 返回两个数字之间最大值的函数 */
int max(int num1, int num2){

   /*局部变量声明*/
   int result;
   
   if(num1 > num2)
      result = num1;
   else
      result = num2;
 
   return result; 
}

int main(){
   printf("Comparing two numbers using max() function: 
");
   printf("Which of the two, 75 or 57, is greater than the other? 
");
   printf("The answer is: %d", max(75, 57));
    
   return 0;
}

输出

运行此代码时,它将产生以下输出 -

Comparing two numbers using max() function: 
Which of the two, 75 or 57, is greater than the other? 
The answer is: 75

在 C 语言中调用函数

创建 C 函数时,需要定义该函数的功能。要使用函数,必须调用该函数来执行定义的任务。

要正确调用函数,需要遵循函数原型的声明。如果函数定义为接收一组参数,则必须传递相同数量和类型的参数。

当函数定义时带有参数,函数名称前面的参数称为形式参数。当函数被调用时,传递给它的参数称为实际参数

当程序调用函数时,程序控制权将转移到被调用函数。被调用函数执行定义的任务,当执行其 return 语句或到达函数结束括号时,程序控制权将返回给主程序。

示例:调用函数

要调用函数,您只需传递所需的参数以及函数名称。如果函数返回值,则可以存储返回值。请看以下示例 -

#include <stdio.h>
 
/* 函数声明 */
int max(int num1, int num2);
 
int main (){

   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret;
 
   /* 调用函数获取最大值 */
   ret = max(a, b);
 
   printf( "Max value is : %d
", ret );
 
   return 0;
}
 
/* 函数返回两个数字之间的最大值 */
int max(int num1, int num2){

   /*局部变量声明*/
   int result;
 
   if (num1 > num2)
      result = num1;
   else
      result = num2;
 
   return result; 
}

输出

我们将 max() 与 main() 函数一起保留,并编译了源代码。运行最终的可执行文件时,将产生以下结果 -

Max value is :200

C 语言中的 main() 函数

C 程序是一个或多个函数的集合,但其中一个函数必须命名为 main(),它是程序执行的入口点。

在 main() 函数内部,调用其他函数。main() 函数可以调用库函数,例如 printf(),其原型从头文件 (stdio.h) 中获取,也可以调用代码中存在的任何其他用户定义函数。

在 C 语言中,程序的定义顺序并不重要。在程序中,无论 main() 函数是否是第一个函数,它都是程序的入口点。

注意:在 C 语言中,任何函数都可以调用其他函数,调用次数不限。函数也可以调用自身。这种自调用函数称为递归函数

函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量被称为函数的形式参数

形式参数的行为类似于函数内的其他局部变量,在函数进入时创建,在函数退出时销毁。

调用函数时,有两种方式将参数传递给函数 -

序号 调用类型和说明
1 按值调用

此方法将参数的实际值复制到函数的形式参数中。在这种情况下,对函数内部形参的更改不会影响实际参数。

2 通过引用调用

此方法将实参的地址复制到形式参数中。在函数内部,该地址用于访问调用中使用的实际实参。这意味着对形参的更改会影响实际参数。

默认情况下,C 使用通过值调用来传递实参。通常,这意味着函数内的代码无法更改用于调用函数的实参。