1 C 语言中的函数
- 函数的由来
- 程序 = 数据 + 算法
- C 程序 = 数据 + 函数
2 函数的意义
-
模块化程序设计
-
C 语言中的模块化
3 面向过程的程序设计
- 面向过程是一种以过程为中心的编程思想
- 首先将复杂的问题分解为一个个容易解决的问题
- 分解过后的问题可以按照步骤一步步完成
- 函数是面向过程在 C 语言中的体现
- 解决问题的每个步骤可以用函数来实现
4 声明和定义
-
声明和定义并不相同
-
声明的意义在于告诉编译器程序单元的存在
-
定义则明确指示程序单元的意义
-
C 语言中通过
extern
进行程序单元的声明 -
一些程序单元在声明时可以省略
extern
-
示例:声明和定义的不同
-
Demo1
// test.c #include <stdio.h> #include <malloc.h> //声明外部全局变量,在其他C文件中被定义,编译器在此处不会给g_var分配空间 extern int g_var; //声明外部全局结构体,在其他C文件中被定义 extern struct Test; int main() { //声明函数,在其他C文件中被定义 extern void f(int i, int j); extern int g(int x); struct Test* p = NULL; // (struct Test*)malloc(sizeof(struct Test)); printf("p = %p ", p); g_var = 10; printf("g_var = %d ", g_var); f(1, 2); printf("g(3) = %d ", g(3)); free(p); return 0; } //global.c #include <stdio.h> int g_var = 5; struct Test { int x; int y; }; void f(int i, int j) { printf("i + j = %d ", i + j); } int g(int x) { return (int)(2 * x + g_var); }
-
编译:struct 不需要使用
extern
进行声明test.c:6: warning: useless storage class specifier in empty declaration
-
运行
p = (nil) g_var = 5 g_var = 10 i + j = 3 g(3) = 16
-
Demo2:修改
p
指针指向的内存分配方式// test.c #include <stdio.h> #include <malloc.h> extern int g_var; extern struct Test; int main() { extern void f(int i, int j); extern int g(int x); struct Test* p = (struct Test*)malloc(sizeof(struct Test)); printf("p = %p ", p); g_var = 10; printf("g_var = %d ", g_var); f(1, 2); printf("g(3) = %d ", g(3)); free(p); return 0; } //global.c #include <stdio.h> int g_var = 5; struct Test { int x; int y; }; void f(int i, int j) { printf("i + j = %d ", i + j); } int g(int x) { return (int)(2 * x + g_var); }
-
编译
- 分析:编译器编译文件的顺序是不确定的,那么编译器在编译 test.c 文件时,编译到 14 行时无法知道结构体
Test
的大小信息
test.c: In function ‘main’: test.c:13: error: invalid application of ‘sizeof’ to incomplete type ‘struct Test’
- 分析:编译器编译文件的顺序是不确定的,那么编译器在编译 test.c 文件时,编译到 14 行时无法知道结构体
-
Demo3:
g_var
变量的类型在声明和定义时不同// test.c #include <stdio.h> #include <malloc.h> extern int g_var; extern struct Test; int main() { extern void f(int i, int j); extern int g(int x); struct Test* p = NULL; printf("p = %p ", p); g_var = 10; printf("g_var = %d ", g_var); f(1, 2); printf("g(3) = %d ", g(3)); free(p); return 0; } //global.c #include <stdio.h> float g_var = 5; struct Test { int x; int y; }; void f(int i, int j) { printf("i + j = %d ", i + j); } int g(int x) { return (int)(2 * x + g_var); }
-
编译运行:变量
g_var
打印出的值与预期不同- 分析:编译器在处理 test.c 文件的第 19 行时,按照
int
的存储方式到g_var
对应的内存处取值,即将一个二进制的float
值解释为int
型
p = (nil) g_var = 1084227584 g_var = 10 i + j = 3 g(3) = 6
- 分析:编译器在处理 test.c 文件的第 19 行时,按照
-