文章目录
编译过程
include的区别
- include后面接
" "
号 → \rightarrow → 先在file1.c
所在的当前目录找file1.h
,如果找不到,再按系统指定的目录检索 - include后面接
< >
号 → \rightarrow → 表示系统直接按系统指定的目录检索 #include <>
常用于包含库函数的头文件;#include ""
常用于包含自定义的头文件
宏定义
宏常量
#define num 100
在预编译时将宏名替换成字符串的过程称为**“宏展开”。宏定义,只在宏定义的文件**中起作用。
注意事项:
- 宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错
- 宏名有效范围为从定义到本源文件结束,可以用
#undef
命令终止宏定义的作用域 - 宏定义中可以引用已定义的宏名
宏函数
#define SUM(x,y) (( x )+( y ))
void test(){
//仅仅只是做文本替换 下例替换为 int ret = ((10)+(20));
//不进行计算
int ret = SUM(10, 20);
printf("ret:%d\n",ret);
}
注意事项:
- 宏的名字中不能有空格,但是在替换的字符串中可以有空格
- 用括号括住每一个参数,并括住宏的整体定义
- 假如在程序中只使用一次宏对程序的运行时间没有太大提高
条件编译
作用 → \rightarrow → 防止文件被重复引用
#ifndef _SOMEFILE_H
#define _SOMEFILE_H
//需要声明的变量、函数
//宏定义
//结构体
#endif
一些特殊的预定宏
名字 | 意义 |
---|---|
__FILE__ |
宏所在文件的源文件名 → \rightarrow → 打印的是绝对路径 |
__LINE__ |
宏所在行的行号 |
__DATE__ |
代码编译的日期 |
__TIME__ |
代码编译的时间 |
静态库的封装和使用
库的概念
- 库可以简单看成一组目标文件的集合,将这些目标文件经过压缩打包之后形成的一个文件
- 像在Windows这样的平台上,最常用的c语言库是由集成开发环境所附带的运行库,这些库一般由编译厂商提供;
windows下静态库创建和使用
案例:配置一个简单的静态库
Step1:在VS中创建新项目,写静态库的.c源文件和.h头文件
.c
源文件:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void welcome()
{
printf("Hello World!!!\n");
return 0;
}
void printMessages()
{
printf("The date is %s, and the time is %s.\n", __DATE__, __TIME__);
return 0;
}
int valueSum(int a, int b)
{
return a + b;
}
.h
头文件
#pragma once
// 欢迎函数,输出“Hello World”到屏幕上
void welcome();
// 打印编译过程的时间和日期信息
void printMessages();
// 进行两数相加的运算
int valueSum(int a, int b);
Step2:生成静态库
右键解决方案的名字 → \rightarrow → 属性 → \rightarrow → 常规 → \rightarrow → 配置类型(下拉菜单) → \rightarrow → 选择静态库(.lib) → \rightarrow → 返回到代码编写界面 → \rightarrow → 点击生成按钮 → \rightarrow → 当生成\StaticLib\x64\Debug\StaticLib.lib
时,生成成功
Step3:检查静态库是否生成
鼠标点击.c源文件 → \rightarrow → 右键 → \rightarrow → 打开所在的文件夹 → \rightarrow → 进入x64
文件 → \rightarrow → 进入debug
文件 → \rightarrow → 当出现**.lib**文件后,说明静态库生成
Step4:调用静态库
查看这个文章:

在新建的解决方案中增加main.c
文件,写入以下代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"StaticLib.h"
int main()
{
welcome();
printMessages();
printf("%d\n", valueSum(5, 8));
system("pause");
return 0;
}
编译后的结果是:
Hello World!!!
The date is Aug 1 2022, and the time is 13:01:13.
13
请按任意键继续. . .
静态库和动态库的优缺点
静态库
优点 → \rightarrow → 生成的exe程序中包含了静态库中的内容,与静态库无瓜葛
缺点 → \rightarrow → 浪费资源,更新发布比较麻烦
动态库
优点 → \rightarrow → 运行阶段才去链接函数
动态库的封装和使用
查看这个文章:
具体代码与静态库的一样。
动态库封装细节
【__declspec(dllexport)
】动态链接库中定义有两种函数:导出函数(export function)和内部函数(internal function)。 导出函数可以被其它模块调用,内部函数在定义它们的DLL程序内部使用。
【动态库的lib文件和静态库的lib文件的区别】对一个DLL文件来说,其引入库文件(.lib)包含该DLL导出的函数和变量的符号名,而.dll文件包含该DLL实际的函数和数据。
递归函数
递归函数就是直接或间接调用自身的函数。
注意:必须要有结束的条件,否则会死循环
递归函数案例1——逆序打印字符数组
int reverse1(char *str){
if (str == NULL)
{
return -1;
}
if (*str == '\0') // 函数递归调用结束条件
{
return 0;
}
reverse1(str + 1);
printf("%c", *str);
return 0;
}
char buf[1024] = {
0 }; //全局变量
递归案例2——斐波那契数列
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int Fibonacci(int ss)
{
if ((ss == 1) || (ss == 2) )
{
return 1;
}
return Fibonacci(ss - 1) + Fibonacci(ss - 2);
}
void test(int s)
{
for (int i=0;i<s;i++)
{
if (i == 0)
{
continue;
}
int res = Fibonacci(i);
printf("%d\n", res);
}
}
int main()
{
test(20);
system("pause");
return 0;
}
生成的结果是:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
请按任意键继续. . .
面向接口
背景:一般的企业信息系统都有成熟的框架。
软件框架一般不发生变化,能自由的集成第三方厂商的产品。
要求在企业信息系统框架中集成第三方厂商的游戏功能产品。
软件设计要求:能够满足用户需求,完成的产品可以与用户完美对接。
- 抽象游戏中玩家结构体设计(struct Player)
- 框架接口设计(playGame)
初始化游戏
核心功能战斗
查看玩家信息
结束游戏 - 游戏厂商1入围(GameCompany1)
游戏厂商2入围(GameCompany2) - 框架接口分文件编写