函数

C语言函数章节语法总结C语言中函数章节的语法包括函数声明和函数定义两个部分。

函数声明

函数声明是指在使用函数之前,对函数进行声明,以告诉编译器该函数的返回值类型、函数名以及参数列表等信息。函数声明的一般语法格式如下:

1
返回值类型 函数名(参数列表); //又叫 函数原型

例如:

1
int max(int x, int y);  // 声明函数 max

函数定义

函数定义是指实现函数功能的具体代码,定义包括函数头和函数体两部分。函数头包括返回值类型、函数名和参数列表,函数体包括函数的具体实现。函数定义的一般语法格式如下:

1
2
3
4
返回值类型 函数名(参数列表)
{
// 函数体
}

其中,参数列表是指用逗号分隔的一个或多个参数,参数由参数类型和参数名组成,参数类型指定参数的数据类型,参数名指定参数的名称。

例如:

1
2
3
4
5
6
7
int max(int x, int y)  // 定义函数 max
{
if (x > y)
return x;
else
return y;
}

在函数定义中,参数列表可以为空,表示该函数不接受任何参数。返回值类型可以为任何合法的 C 语言类型,包括基本类型、结构体、联合体等。函数体中可以包含任何 C 语言语句,包括变量定义、循环语句、条件语句、函数调用等。

此外,在 C 语言中还有一种特殊的函数,即无返回值函数。其定义格式为:

1
2
3
4
void 函数名(参数列表)
{
// 函数体
}

其中,返回值类型为 void 表示该函数不返回任何值。

注意:函数不能嵌套定义

函数的参数

实参:

真实传给函数的参数,叫实参。 实参可以是:常量、变量、表达式、函数等。

无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。

形参:

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

注意:实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误

函数的调用:

传值调用

在值传递方式中,函数参数的值被复制到函数的局部变量中,函数使用的是副本而不是原始值。这意味着在函数中对参数的修改不会影响原始值。在函数调用时,参数必须是一个表达式,例如常量、变量或表达式等。

例如:

1
2
3
4
5
6
7
8
9
10
11
void func(int x, int y)
{
// 使用 x 和 y
}

int main()
{
int a = 10, b = 20;
func(a, b); // 值传递参数 a 和 b
return 0;
}

在上面的例子中,函数 func 接受两个整型参数 x 和 y,参数类型为 int。在主函数 main 中,将变量 a 和 b 作为参数传递给函数 func。

传址调用

在指针传递方式中,函数参数被声明为指针类型,指向函数调用中传递的实际参数的内存位置。这意味着在函数中对参数的修改将影响原始值。在函数调用时,必须传递指向实际参数的指针。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
void swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}

int main()
{
int a = 10, b = 20;
swap(&a, &b); // 通过指针传递参数 a 和 b
return 0;
}

在上面的例子中,函数 swap 接受两个整型指针参数 x 和 y,参数类型为 int *。在主函数 main 中,使用 & 运算符获取变量 a 和 b 的地址,并将它们作为指针传递给函数 swap。

函数的嵌套调用

函数不能嵌套定义,但可以嵌套调用,也就是在一个函数的定义或调用过程中允许出现对另外一个函数的调用。

内部函数与外部函数

内部函数

一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的前面加static。内部函数定义的一般语法格式如下:

1
static 返回值类型 函数名(参数列表); //又叫静态函数

static总结

  1. 隐藏:仅限于在本源文件中使用,在其他源文件中不能引用,也就是说限制其作用域只在定义该变量的源文件内有效,而在同一源程序的其他源文件中不能使用。
  1. 隐藏:仅限于在本源文件中使用,在其他源文件中不能引用,也就是说限制其作用域只在定义该变量的源文件内有效,而在同一源程序的其他源文件中不能使用。
  2. 保持变量内容的持久:函数中局部变量的值在函数调用结束之后不会消失,而仍然保留其原值
  3. 默认初始化为 0:静态变量与全局变量也一样,它们都存储在静态数据区中,因此其变量的值默认也为 0。
  1. 对于函数来讲,static 的作用仅限于隐藏
  2. 对于变量,static 的作用有 隐藏、保持变量内容的持久和默认初始化为 0。全局变量也具有默认初始化为 0。

外部函数

在定义函数时,在函数首部的最左端加关键字extern,则此函数是外部函数,可以被其他文件内的函数调用。外部函数定义的一般语法格式如下:

1
extern 返回值类型 函数名(参数列表); //又叫静态函数

C语言函数返回值

函数的返回值使用 return 语句返回。具体格式如下

1
return 表达式;

例如:

1
2
3
4
return a;
return a+b;
return (a+b);
return (10+20);

函数的返回值类型在函数定义时就需要指定。如果函数没有返回值,则返回类型应该是 void。

return 语句是提前结束函数的唯一办法。return 后面可以跟一份数据,表示将这份数据返回到函数外面;return 后面也可以不跟任何数据,表示什么也不返回,仅仅用来结束函数。

函数调用参数的计算顺序(偏门)

函数调用参数的时候,从右往左依次执行所有会改变变量数值的式子,遇到后置自增的式子则直接把此时的变量代入,得到该自增式的值。全部执行完成后再从左往右依次把改变后的变量值代入各个除后置自增式以外的所有式子,此时这些式子的值是最终要代入函数的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main()
{
//int a = 1;
//printf("%d %d %d\n", a++, a+1, a = 3); // 3 5 4

int i = 2;
printf("%d,%d,%d,%d,\n", i++, ++i, i, i++); //4 5 5 2
//先 从右到左
//① i++,后置直接给出结果,这一项的结果为2,i此时为3
//② i,没有什么运算
//③ ++i,这一项输出什么先不要管,因为还需要从左到右执行,来输出结果。i此时为4
//④ i++,后置直接给出结果,这一项结果为4,i此时为5
//再 从左到右
//第一项上面说了,结果为4,然后第二项的结果是i最后的值,也就是上面第五步的5,第三项也是。最后一项之前说了2
//说白了,就是遇到后置就直接给出结果,其他的等从右到左运行结束后再进行运算

printf("%d,%d,%d,%d,\n", i++, ++i, i + 2, i++); //4 5 7 2

printf("%d", i); // 从右往左执行,遇到后置(真结束)直接给出结果。最后的结果其实就是i最后的值的基础上进行运算

int a = 1;
printf("%d %d %d\n", a = 11, a = 22, a = 33); // 11 11 11
// 就是从右到左执行,后置直接给结果;然后再从右到左给结果(如a+1,就在a的基础上+1)
printf("%d %d %d %d\n", a = 11, a = 22, a = 33, a+1); // 11 11 11 12

return 0;
}