什么是函数?
函数就是一个功能模块,就是之前学的子程序模块。
由C语言提供的函数称为库函数。
通常各个编译器在提供C语言规定的函数外,还会提供各自不同的函数。具体内容参考各编译器的说明书。
函数的定义
函数的调用
使用函数的过程,称为 “调用函数”。 进行函数调用后,程序的流程会跳转到被调用的函数处,传递过去的实参会赋值给函数的形参。
代码清单6-1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #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 #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 #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 #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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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 #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 #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 #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 ; }
作用域
文件作用域
在函数外声明的变量标识符,其名称从声明的位置开始,到该程序的结尾都是通用的。这样的作用域称为文件作用域。
代码清单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 #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 ; } 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 是一个意思。
声明和定义
这里的声明和定义在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 #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 #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 ; } 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 #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 #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 #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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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]; } 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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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; } 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 #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 ; }
不在函数内的变量(全局变量)拥有文件作用域,因此 print_x() == 75。
函数内部的变量(局部变量)拥有块作用域,而当两个同名变量分别拥有文件作用域和块作用域,那么只有拥有块作用域的变量优先使用。因此第二次输出结果 x=999(此时x在main语句块中) 。
第三次输出(此时x在for语句块中)同序列2,x=0~x=400
第四次输出(此时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 #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 ; }
从上图中可以看到 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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> int fx; 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 #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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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 #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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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
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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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
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 #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
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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> void hello (void ) { printf ("你好。\n" ); } int main (void ) { hello(); 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 #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
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 #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
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 #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
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 #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
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 #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
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 #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h> 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]; } } 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #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 ; }