C语言语法入门-函数
9unk Lv5

什么是函数?

函数就是一个功能模块,就是之前学的子程序模块。
由C语言提供的函数称为库函数。

通常各个编译器在提供C语言规定的函数外,还会提供各自不同的函数。具体内容参考各编译器的说明书。

函数的定义

1
2

函数的调用

使用函数的过程,称为 “调用函数”。 进行函数调用后,程序的流程会跳转到被调用的函数处,传递过去的实参会赋值给函数的形参。

代码清单6-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:list0601.c*/
/*
求两个整数中较大的值
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int max2(x, y)
{
return (x > y) ? x : y;
}

int main(void)
{
int a, b;
printf("请输入两个整数:"); scanf("%d%d", &a, &b);
printf("两个数中较大的值是%d\n", max2(a, b));
}

代码清单6-2

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
28
29
30
31
/*程序名:list0602.c*/
/*
求三个整数中较大的值
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

int max3(x, y, z)
{
if ((x > y)&&(x>z))
{
return x;
}
else if ((y > x) && (y > z))
{
return y;
}
else if ((z > x) && (z > y))
{
return z;
}
}

int main(void)
{
int a, b, c;
printf("请输入三个整数:"); scanf("%d%d%d", &a, &b, &c);
printf("三个数中较大的值是%d\n", max2(a, b, c));
}

将函数的返回值作为参数传递给函数

代码清单6-3

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
/*程序名:list0603.c*/
/*
求两个整数的平均差。
*/
#include <stdio.h>
#include <stdlib.h>

/*计算平方*/
int sqr(x)
{
return x * x;
}

/*计算平方差*/
int diff(x, y)
{
return (x > y) ? x - y : y - x;
}

int main(void)
{
int a, b;
printf("请输入两个整数:"); scanf("%d%d", &a, &b);
printf("两个整数的平方差是%d\n", diff(sqr(a), sqr(b)));
}

调用其他函数

在自己创建的函数中也可以调用其他的函数。

代码清单6-4

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
/*程序名:list0604.c*/
/*
计算四个整数最大的值
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*两个整数最大的值*/
int max2(x, y)
{
return (x > y) ? x : y;
}

/*四个整数最大的值*/
int max4(x, y)
{
return (x > y) ? x : y;
}

int main(void)
{
int a, b, c, d;
printf("请输入四个整数:"); scanf("%d%d%d%d", &a, &b, &c, &d);
printf("四个整数最大的值是%d\n", max4(max2(a,b),max2(c,d)));
}

值传递

代码清单6-5

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
28
29
/*程序名:list0605.c*/
/*
计算幂
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*求 x 的 n 次幂*/
double power(double x, int n)
{
double temp = x;
for (int i = 1; i < n; i++)
{
temp *= x;
}
return temp;
}


int main(void)
{
double a ;
int b;
printf("请输入一个数:"); scanf("%lf", &a);
printf("要打印多少次幂:"); scanf("%d", &b);
printf("%lf的%d次幂是%lf\n", a, b, power(a, b));
}

函数间参数的传递是通过值传递进行的。

代码清单6-6

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
28
29
/*程序名:list0606.c*/
/*
计算幂
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*求 x 的 n 次幂*/
double power(double x, int n)
{
double temp = x;
while (--n > 0)
{
temp *= x;
}
return temp;
}


int main(void)
{
double a ;
int b;
printf("请输入一个数:"); scanf("%lf", &a);
printf("要打印多少次幂:"); scanf("%d", &b);
printf("%lf的%d次幂是%lf\n", a, b, power(a, b));
}

函数设计

没有返回值的函数

void 是 “空” 的意思,创建的函数不需要返回值时,可以使用void声明函数。在 C 语言中,不论有没有返回值都称为函数。而在其他编程语言中,没有返回值的会定义为其他非函数的概念。

代码清单6-7

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
28
29
/*程序名:list0607.c*/
/*
显示出一个直角在左下方的等腰三角形(函数版)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

void put_starts(int n)
{
while (n-- > 0)
putchar('*');
}

int main(void)
{
int i, len;
printf("生成一个直角在左下方的等腰三角形。\n");
printf("短边:");
scanf("%d", &len);

for (i = 1; i <= len; i++)
{
put_starts(i);
putchar('\n');
}
return 0;
}

通用性

创建的函数可通过修改参数来达到改变程序的目的,这样函数会变得更加灵活,通用性更好。

代码清单6-8

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
28
29
30
/*程序名:list0608.c*/
/*
显示出一个直角在右下方的等腰三角形(函数版)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

void put_chars(int ch,int n)
{
while (n-- > 0)
putchar(ch);
}

int main(void)
{
int i, len;
printf("生成一个直角在右下方的等腰三角形。\n");
printf("短边:");
scanf("%d", &len);

for (i = 1; i <= len; i++)
{
put_chars(' ',len-i);
put_chars('*', i);
putchar('\n');
}
return 0;
}

不含形参的函数

代码清单6-9

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*程序名:list0609.c*/
/*
逆向显示输入的整数
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*---返回输入的正整数---*/
int scan_print(void)
{
int tmp;

do
{
printf("请输入一个整数:");
scanf("%d", &tmp);
if (tmp <= 0)
puts("\a请不要输入非正整数。");
} while (tmp <= 0);
return tmp;
}

/*---返回正整数倒转后的值---*/
int rev_int(int num)
{
int tmp = 0;

if (num > 0)
{
do
{
tmp = tmp * 10 + num % 10;
num /= 10;
} while (num > 0);
}
return tmp;
}

int main(void)
{
int nx = scan_print();
printf("该整数倒转后的值是%d。\n", rev_int(nx));
return 0;
}

作用域

3

文件作用域

在函数外声明的变量标识符,其名称从声明的位置开始,到该程序的结尾都是通用的。这样的作用域称为文件作用域。

代码清单6-10

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*程序名:list0610.c*/
/*
计算最高分
*/
#define _CRT_SECURE_NO_DEPRECATE
#define NUMBER 5
#include <stdio.h>
#include <stdlib.h>

int tensu[NUMBER];
int top(void);


int main(void)
{
extern int tensu[];
int i;

printf("请输入%d学生的分数。\n", NUMBER);
for (i = 0; i < NUMBER; i++)
{
printf("%d:", i + 1);
scanf("%d", &tensu[i]);
}
printf("最高分=%d\n", top());
return 0;
}

/*---返回数组 tensu 的最大值(函数top的函数定义)---*/
int top(void)
{
extern int tensu[];
int i;
int max = tensu[0];

for (i = 1; i < NUMBER; i++)
{
if (tensu[i] > max)
max = tensu[i];
}
return max;
}

extern 表示引用全局变量 tensu[],这个是编译器来实现的。编译器会将 extern 声明的变量都用全局变量指针来替换。这个和我们之前再汇编中学习的 extern 是一个意思。

声明和定义

4

这里的声明和定义在x86汇编中也是一样的,被调用函数在调用函数之前,否则需要在调用函数之前声明被调用函数。

数组的传递

代码清单6-11

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*程序名:list0611.c*/
/*
计算英语分数和数学分数中的最高分
*/
#define _CRT_SECURE_NO_DEPRECATE
#define NUMBER 5
#include <stdio.h>
#include <stdlib.h>

int max_of(int v[],int n)
{
int i;
int max = v[0];

for (i = 1; i < n; i++)
{
if (v[i] > max)
max = v[i];
}
return max;
}

int main(void)
{
int i;
int eng[NUMBER];
int mat[NUMBER];
int max_e, max_m;

printf("请输入%d学生的分数。\n", NUMBER);
for (i = 0; i < NUMBER; i++)
{
printf("[%d]英语:", i + 1);
scanf("%d", &eng[i]);

printf(" 数学:");
scanf("%d", &mat[i]);
}

max_e = max_of(eng, NUMBER);
max_m = max_of(mat, NUMBER);

printf("英语的最高分=%d\n", max_e);
printf("数学的最高分=%d\n", max_m);
return 0;
}

通过函数 max_of 来计算数组中的最高值,这样提高了程序的通用性。

函数的传递和 const 类型的修饰符

代码清单6-12

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*程序名:list0612.c*/
/*
将数组的所有元素设置为0
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void set_zero(int v[], int n)
{
int i;
for (i = 0; i < n; i++)
v[i] = 0;
}

/*---显示在n个元素的数组v的所有元素并换行---*/
void printf_array(const int v[], int n)
{
int i;
printf("{ ");
for (i = 0; i < n; i++)
printf("%d", v[i]);
printf("}");
}

int main(void)
{
int ary1[] = { 1,2,3,4,5 };
int ary2[] = { 3,2,1 };

printf("ary1 = "); printf_array(ary1, 5); putchar('\n');
printf("ary2 = "); printf_array(ary2, 3); putchar('\n');

set_zero(ary1, 5);
set_zero(ary2, 3);

printf("\n把0赋给了两个数组的所有元素。\n");
printf("ary1 = "); printf_array(ary2, 3); putchar('\n');
printf("ary2 = "); printf_array(ary2, 3); putchar('\n');
return 0;
}

printf_array 函数的第一个参数是一个常量值,因此该函数中就不能改写数组v的元素值。

线性查找(顺序查找)

代码清单6-13

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*程序名:list0613.c*/
/*
线性查找(顺序查找)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#define NUMBER 5 /*元素个数*/
#define FAILED -1 /*查找失败*/

int search(const int v[], int key, int n)
{
int i = 0;

while (1)
{
if (i == n)
return FAILED;
if (v[i] == key)
return i;
i++;
}
}

int main(void)
{
int i, ky, idx;
int vx[NUMBER];

for (i = 0; i < NUMBER; i++)
{
printf("vx[%d]:", i);
scanf("%d", &vx[i]);
}
printf("要查找的值:");
scanf("%d", &ky);

idx = search(vx, ky, NUMBER);

if (idx == FAILED)
puts("\a查找失败。");
else
printf("%d 是数组的第 %d 号元素。\n", ky, idx + 1);

return 0;
}

哨兵查找

在数组最后插入要查找的值,这个值称为哨兵,当循环遍历到哨兵,说明未查找到该值,反之查找到该值。

代码清单6-14

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*程序名:list0614.c*/
/*
哨兵查找(哨兵查找法)
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#define NUMBER 5 /*元素个数*/
#define FAILED -1 /*查找失败*/

int search(int v[], int key, int n)
{
int i = 0;
v[n] = key;

while (1)
{
if (v[i] == n)
break;
i++;
}
return (i < n) ? i : FAILED;
}

int main(void)
{
int i, ky, idx;
int vx[NUMBER+1];

for (i = 0; i < NUMBER; i++)
{
printf("vx[%d]:", i);
scanf("%d", &vx[i]);
}
printf("要查找的值:");
scanf("%d", &ky);


if ((idx = search(vx, ky, NUMBER)) == FAILED)
puts("\a查找失败。");
else
printf("%d 是数组的第 %d 号元素。\n", ky, idx + 1);

return 0;
}

代码清单6-15

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*程序名:list0615.c*/
/*
从元素个数为n的数组v中查找和key一致的元素(哨兵查找法)
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#define NUMBER 5 /*元素个数*/
#define FAILED -1 /*查找失败*/

int search(int v[], int key, int n)
{
int i = 0;
v[n] = key;

for (i = 0; v[i] != key; i++)
;
return (i < n) ? i : FAILED;
}

int main(void)
{
int i, ky, idx;
int vx[NUMBER+1];

for (i = 0; i < NUMBER; i++)
{
printf("vx[%d]:", i);
scanf("%d", &vx[i]);
}
printf("要查找的值:");
scanf("%d", &ky);


if ((idx = search(vx, ky, NUMBER)) == FAILED)
puts("\a查找失败。");
else
printf("%d 是数组的第 %d 号元素。\n", ky, idx + 1);

return 0;
}

在该 for 语句中,i会不断地自动增加,知道在数组中找到key值相同的元素为止。循环体中并不需要执行什么特别的语句。

多维数组的传递

函数间多维数组的传递中,一般将最高维的元素个数作为不同于数组的其他参数进行传递。

代码清单6-16

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*程序名:list0616.c*/
/*
求4名学生在两次考试中3个课程的总分并显示(函数版)
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*——将4行3列矩阵a和b的和存储在c中——*/
void mat_add(const int a[4][3],const int b[4][3],int c[4][3])
{
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++)
c[i][j] = a[i][j] + b[i][j];
}

/*——显示4行3列的矩阵m——*/
void mat_print(const int m[4][3])
{
int i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 3; j++)
printf("%4d", m[i][j]);
putchar('\n');
}
}
int main(void)
{
int tensu1[4][3] = { {91,63,78},{67,72,46},{89,34,53},{32,54,34} };
int tensu2[4][3] = { {97,67,82},{73,43,46},{97,56,21},{85,46,35} };
int sum[4][3];

mat_add(tensu1, tensu2, sum);
puts("第一次考试分数"); mat_print(tensu1);
puts("第二次考试分数"); mat_print(tensu2);
puts("总分"); mat_print(sum);

return 0;
}

代码清单6C-1

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*程序名:listC0601.c*/
/*
为n行3列的二维数组的所有构成元素赋上同样的值
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>


/*——将 v 赋值给元素类型int[3]、元素个数为n的数组m的所有构成元素——*/
void fill(int m[][3], int n, int v)
{
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 3; j++)
m[i][j] = v;
}

/*——显示4行3列的矩阵m——*/
void mat_print(const int m[][3],int n)
{
int i, j;
for (i = 0; i < n; i++)
{
for (j = 0; j < 3; j++)
printf("%4d", m[i][j]);
putchar('\n');
}
}
int main(void)
{
int no;
int x[2][3] = { 0 };
int y[4][3] = { 0 };

printf("赋给所有构成元素的值:");
scanf("%d", &no);
fill(x, 2, no);
fill(y, 4, no);

fill(x, 2, no);
fill(y, 4, no);
printf("--- x ---\n"); mat_print(x, 2);
printf("--- y ---\n"); mat_print(y, 4);

return 0;
}

作用域和存储期

作用域和标识符的可见性

代码清单6-17

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
28
29
30
31
32
33
34
35
/*程序名:list0617.c*/
/*
确认标识符的作用域
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int x = 75; /*文件作用域*/

void print_x(void)
{
printf("x = %d\n", x);
}

int main(void)
{
int i;
int x = 999; /*块作用域*/

print_x();

printf("x = %d\n", x);

for (i = 0; i < 5; i++) /*块作用域*/
{
int x = i * 100;
printf("x = %d\n", x);
}

printf("x = %d\n", x);

return 0;
}
  1. 不在函数内的变量(全局变量)拥有文件作用域,因此 print_x() == 75。
  2. 函数内部的变量(局部变量)拥有块作用域,而当两个同名变量分别拥有文件作用域和块作用域,那么只有拥有块作用域的变量优先使用。因此第二次输出结果 x=999(此时x在main语句块中) 。
  3. 第三次输出(此时x在for语句块中)同序列2,x=0~x=400
  4. 第四次输出(此时x在main语句块中),x=999

存储期

在函数声明的变量,并不是从程序开始到程序结束始终有效。变量的生存期也就是寿命有两种,它们可以通过存储器这个概念来体现。

  • 自动存储期
    在函数中不使用存储类型说明符static而定义出的对象(变量),被赋予了自动存储期,它具有以下特性:
    程序执行到对象声明的时候创建出相应的对象。而执行到包含该声明的程序块结尾,也就是大括号 “}” 的时候,该对象就会消失。

也就是说,该对象拥有短暂的寿命,另外,如果不显示地机型初始化,则该对象会被初始化为不确定地值。

这里想要讲的就是局部变量在堆栈中的变化规律,画过堆栈图后就很容易理解。

  • 静态存储期
    在函数使用 static 定义出来的对象,或者在函数外声明定义出来的对象被赋予了静态存储其,它具有以下特性:
    在程序开始执行的时候,具体地说是在 main 函数执行之前的准备阶段被创建出来,在程序结束的时候消失。

也就是说对象拥有 “永久” 寿命。另外,如果不显式地进行初始化,则该对象自动初始化为0。

这里想要讲地是全局变量是知道程序运行结束后才会失效,且存储全局变量区默认都是0,即使不对全局变量初始化,其默认值也是0

代码清单6-18

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
28
29
30
/*程序名:list0618.c*/
/*
自动存储期和静态存储期。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int fx = 0; /*静态存储期+文件作用域*/

void func(void)
{
static int sx = 0; /*静态存储期+块作用域*/
int ax = 0; /*自动存储期+块作用域*/

printf("%3d%3d%3d\n", ax++,sx++,fx++);
}

int main(void)
{
int i;
puts("ax sx fx");
puts("---------");
for (i = 0; i < 10; i++)
func();
puts("---------");

return 0;
}

5

从上图中可以看到 static 修饰符就是把局部变量转换成全局变量,当然在这个功能由编译器实现。

代码清单6-19

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
/*程序名:list0619.c*/
/*
确认拥有静态存储期地对象的默认的初始化
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int fx; /*用0初始化*/

int main(void)
{
int i;
static int si;
static double sd;
static int sa[5];

printf("fx=%d\n", fx);
printf("si=%d\n", si);
printf("sd=%d\n", sd);

for (i = 0; i < 5; i++)
printf("sa[%d] = %d\n", i, sa[i]);

return 0;
}

总结

summaxy1

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
/*程序名:summaxy1.c*/
/*
以实数的形式返回 a 和 b 的平均值
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

double ave2(int a, int b)
{
return (double)(a + b) / 2;
}

int main(void)
{
int n1, n2;

puts("请输入两个整数。");
printf("整数1:"); scanf("%d", &n1);
printf("整数2:"); scanf("%d", &n2);

printf("平均值是%.1f。\n", ave2(n1, n2));

return 0;
}

summaxy2.c

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
28
/*程序名:summaxy2.c*/
/*
记录函数上一次的返回值。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*记下参数no上一次的返回值*/
int val(int no)
{
static int v;
int temp = v;

v = no;
return temp;
}

int main(void)
{
int x=val(2);
int y=val(7);
int z=val(9);

printf("%d %d %d", x, y, z);
return 0;
}

summaxy3.c

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
28
/*程序名:summaxy3.c*/
/*
以实数形式返回数组a的所有元素的平均值
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*以实数形式返回数组a的所有元素的平均值*/
double ave_ary(const int a[],int n)
{
int i;
double sum = 0;

for (i = 0; i < n; i++)
sum += a[i];
return sum / n;
}

int main(void)
{
int num[5] = { 2,4,7,9 };
double a=ave_ary(num, 4);

printf("%.1f", a);
return 0;
}

summaxy4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*程序名:summaxy4.c*/
/*
输出响铃
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*输出响铃*/
void put_alert(void)
{
putchar('\a');
}

int main(void)
{
put_alert();
return 0;
}

summaxy5

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
/*程序名:summaxy5.c*/
/*
设计一个赋值数组的函数
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*将数组b开头的n个元素赋值给数组a*/
void cpy_ary(int a[],const int b[], int n)
{
int i;
for (i = 0; i < n; i++)
a[i] = b[i];
}

int main(void)
{
int source[] = { 1,3,5,7,9 };
int dest[6] = { 0 };
cpy_ary(dest, source, 5);

for (int i = 0; i < 5; i++)
printf("%d ",dest[i]);
return 0;
}

summaxy6

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
28
/*程序名:summaxy6.c*/
/*
返回二维数组a的所有构成元素的总和
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*返回二维数组a的所有构成元素的总和*/
int sum_ary2D(const int a[][3], int n)
{
int i, j;
int sum = 0;
for (i = 0; i < n; i++)
for (j = 0; j < 3; j++)
sum += a[i][j];
return sum;
}

int main(void)
{
int source[2][3] = { {1,3,5},{2,4,6} };
int a = sum_ary2D(source, 2);

printf("%d",a);
return 0;
}

练习

练习6-1

6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:lx6-1.c*/
/*
创建一个函数,返回两个int型整数中较小的一数的值。
int min2(int a,int b)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*求 x 的 n 次幂*/
int min2(x, y)
{
return (x < y) ? x : y;
}


int main(void)
{
int a, b;
printf("请输入两个整数:"); scanf("%d%d", &a,&b);
printf("两个数中较小的值是%d\n", min2(a, b));
}

练习6-2

7

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
28
29
30
31
32
33
34
35
/*程序名:lx6-2.c*/
/*
创建一个函数,返回三个int型整数中最小值。
int min3(int a,int b,int c)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*求 x 的 n 次幂*/
int min3(x, y, z)
{
if ((x < y) && (x < z))
{
return x;
}
else if ((y < 4) && (y < z))
{
return y;
}
else if ((z < x) && (z < y))
{
return z;
}
return -1;
}


int main(void)
{
int a, b, c;
printf("请输入三个整数:"); scanf("%d%d%d", &a,&b,&c);
printf("三个数中较小的值是%d\n", min3(a, b, c));
}

练习6-3

8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:lx6-3.c*/
/*
创建一个函数,返回int型整数的立方。
int cube (int x)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*求 x 的立方*/
int cube(int x)
{
return x * x * x;
}


int main(void)
{
int a;
printf("请输入一个整数:"); scanf("%d", &a);
printf("%d的立方是%d\n", a, cube(a));
}

练习6-4

9

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
/*程序名:lx6-4.c*/
/*
使用代码6-3中的sqr函数创建另一个函数,返回int型整数的四次幂。
int pow4(int x)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*计算平方*/
int sqr(x)
{
return x * x;
}

int pow4(int x)
{
return x * x;
}

int main(void)
{
int a;
printf("请输入一个整数:"); scanf("%d", &a);
printf("%d的四次幂是%d\n", a, pow4(sqr(a)));
}

练习6-5

10

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
/*程序名:lx6-5.c*/
/*
创建一个函数,返回1到n之间所有整数的和
int sump (int n)
*/
#define _CRT_SECURE_NO_DEPRECATE

#include <stdio.h>
#include <stdlib.h>

/*返回1到n之间所有整数的和*/
int sump(int n)
{
int temp=0;
for (int i = 1; i <= n; i++)
{
temp += i;
}
return temp;
}

int main(void)
{
int a;
printf("请输入一个整数:"); scanf("%d", &a);
printf("1到%d之间所有整数的和是%d\n", a, sump(a));
}

练习6-6

11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*程序名:lx6-6.c*/
/*
创建一个函数连续发出n次响铃
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void alert(int n)
{
for (int i = 0; i < n; i++)
{
printf("\a");
}
}

int main(void)
{
alert(5);
return 0;
}

练习6-7

12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*程序名:lx6-7.c*/
/*
在屏幕上显示出“你好。”并换行。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void hello(void)
{
printf("你好。\n");
}

int main(void)
{
hello();
return 0;
}

练习6-8

13

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
/*程序名:lx6-8.c*/
/*
创建一个函数,返回元素个数为n的int型数组v中的最小值。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int min_of(const int v[],int n)
{
int min = v[0];
for (int i = 1; i < n; i++)
{
if (min > v[i])
min = v[i];
}

return min;
}

int main(void)
{
int a[4] = { 4,3,5,1 };
printf("数组中最小的值是:%d", min_of(a, 4));
return 0;
}

练习6-9

14

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
28
29
30
31
32
33
34
35
/*程序名:lx6-9.c*/
/*
创建一个函数,对元素个数为n的int型数组v进行倒序排列。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void rev_intary(int v[],int n)
{
int change = 0;
for (int i = 0; i < n/2; i++)
{
change = v[i];
v[i] = v[n - 1 - i];
v[n -1 - i] = change;
}
}


int main(void)
{
int a[6] = { 4,3,2,0,5,1 };

rev_intary(a, 6);

printf("该数组的倒序是:");

for (int i = 0; i < 6; i++)
{
printf("%d ", a[i]);
}
return 0;
}

练习6-10

15

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
28
29
30
31
32
/*程序名:lx6-10.c*/
/*
创建一个函数,对元素个数为n的int型数组v2进行倒序排列,并将其结果保存到v1。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void intary_rcpy(int v1[],const int v2[],int n)
{
for (int i = 0, j = n - 1; i < n && j >= 0; i++, j--)
{
v1[i] = v2[j];
}
}

int main(void)
{
int b[6] = { 0 };
int a[6] = { 4,3,2,0,5,1 };

intary_rcpy(b, a, 6);

printf("该数组的倒序是:");

for (int i = 0; i < 6; i++)
{
printf("%d ", b[i]);
}
return 0;
}

练习6-11

16

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
28
29
30
31
32
33
34
35
36
37
38
39
40
/*程序名:lx6-11.c*/
/*
创建一个函数 search_idx,将和n个元素的数组v中的key相等的所有元素的下标存储在数组idx中,返回和key相等的元素个数。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

int search_idx(const int v[], int idx[], int key, int n)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
if (v[i] == key)
{
idx[sum] = i;
sum++;
}
}
return sum;
}

int main(void)
{
int key = 0;
int idx[11] = { 0 };
int a[11] = { 0,3,2,0,5,1,0,7,4,5,0 };
int sum = search_idx(a, idx, key, 11);

printf("一共找到了%d个与key相等的元素,", sum);

printf("它们的下标分别是:");

for (int i = 0; i < sum; i++)
{
printf("%d ", idx[i]);
}
return 0;
}

练习6-12

17

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*程序名:lx6-12.c*/
/*
创建一个函数,将4行3列矩阵a和3行4列矩阵b的成绩,存储在3行3列矩阵c中。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void mat_mul(const int a[4][3], const int b[3][4], int c[3][3])
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
c[i][j] = a[i][j] * b[i][j];
}
}
}

int main(void)
{
int c[3][3] = {0};
int a[4][3] =
{
{1,1,1},
{2,2,2},
{3,3,3},
{4,4,4}
};

int b[3][4] =
{
{1,2,3,4},
{2,3,4,5},
{3,4,5,6}
};

mat_mul(a, b, c);

printf("a、b两个数组的乘积分别是:");

for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", c[i][j]);
}
printf("\n");
}
return 0;
}

练习6-13

18

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*程序名:lx6-13.c*/
/*
改写代码6-16的程序,将两次考试的分数存储在三维数组中。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

/*——将4行3列矩阵a和b的和存储在c中——*/
void mat_add(const int a[4][3], const int b[4][3], int c[2][2][3])
{
int i, j, n = 0, k = 0;
for (i = 0; i < 4; i++,k++)
for (j = 0; j < 3; j++)
{
if (k == 2)
{
k = 0;
n++;
}
c[n][k][j] = a[i][j] + b[i][j];
}
}

/*

a[0][0] + b[0][0] = c[0][0][0]
a[0][1] + b[0][1] = c[0][0][1]
a[0][2] + b[0][2] = c[0][0][2]

a[1][0] + b[1][0] = c[0][1][0]
a[1][1] + b[1][1] = c[0][1][1]
a[1][2] + b[1][2] = c[0][1][2]

a[2][0] + b[2][0] = c[1][0][0]
a[2][1] + b[2][1] = c[1][0][1]
a[2][2] + b[2][0] = c[1][0][2]

a[3][0] + b[2][0] = c[1][1][0]
a[3][1] + b[2][1] = c[1][1][1]
a[3][2] + b[2][0] = c[1][1][2]
*/

/*——显示4行3列的矩阵m——*/
void mat_print(const int m[4][3])
{
int i, j;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 3; j++)
printf("%4d", m[i][j]);
putchar('\n');
}
}
int main(void)
{
int tensu1[4][3] = { {91,63,78},{67,72,46},{89,34,53},{32,54,34} };
int tensu2[4][3] = { {97,67,82},{73,43,46},{97,56,21},{85,46,35} };
int sum[2][2][3];


mat_add(tensu1, tensu2, sum);
puts("第一次考试分数"); mat_print(tensu1);
puts("第二次考试分数"); mat_print(tensu2);
puts("总分"); mat_print(sum);

return 0;
}

这里提示警告信息: warning C4048: “const int (*)[3]”和“int [2][2][3]”数组的下标不同。这里数组的形参和实参维数不一样,但并没有报错,这也表明了多维数组在计算中以线性(一维数组)方式存储,而多维的概念是人为划分,它主要是为了快速处理区分不同的数据。

练习6-14

19

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*程序名:lx6-14.c*/
/*
编写一段程序,为 double 型数组的所有元素分配静态存储期,并确认它们都被初始化为0.0
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>


int main(void)
{
static double array[5];

for (int i = 0; i < 5; i++)
{
printf("%.1f\n", array[i]);
}

return 0;
}

练习6-15

20

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*程序名:lx6-15.c*/
/*
创建 pu-count 函数,并显示被调用的次数。
*/

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>

void put_count()
{
static int count;
count++;
printf("put_count:第%d次\n", count);
}
int main(void)
{
put_count();
put_count();
put_count();

return 0;
}
  • 本文标题:C语言语法入门-函数
  • 本文作者:9unk
  • 创建时间:2023-06-13 13:58:00
  • 本文链接:https://9unkk.github.io/2023/06/13/c-yu-yan-yu-fa-ru-men-han-shu/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!