14_C++_编译过程_递归函数_面向接口

编译过程

include的区别

  1. include后面接" " → \rightarrow file1.c所在的当前目录找file1.h,如果找不到系统指定的目录检索
  2. include后面接< > → \rightarrow 表示系统直接系统指定的目录检索
  3. #include <>常用于包含库函数的头文件;#include ""常用于包含自定义的头文件

宏定义

宏常量

#define num 100在预编译时将宏名替换成字符串的过程称为**“宏展开”。宏定义,只在宏定义的文件**中起作用。
注意事项:

  1. 宏定义不作语法检查,只有在编译被宏展开后的源程序才会报错
  2. 宏名有效范围为从定义到本源文件结束,可以用#undef命令终止宏定义的作用域
  3. 宏定义中可以引用已定义的宏名

宏函数

#define SUM(x,y) (( x )+( y ))
void test(){
    
    
	
	//仅仅只是做文本替换 下例替换为 int ret = ((10)+(20));
	//不进行计算
	int ret = SUM(10, 20);
	printf("ret:%d\n",ret);
}

注意事项:

  1. 宏的名字中不能有空格,但是在替换的字符串中可以有空格
  2. 括号括住每一个参数,并括住宏的整体定义
  3. 假如在程序中只使用一次对程序的运行时间没有太大提高

条件编译

作用 → \rightarrow 防止文件被重复引用
条件编译的三个基本类型

#ifndef _SOMEFILE_H
#define _SOMEFILE_H

//需要声明的变量、函数
//宏定义
//结构体

#endif

一些特殊的预定宏

名字 意义
__FILE__ 宏所在文件的源文件名 → \rightarrow 打印的是绝对路径
__LINE__ 宏所在行的行号
__DATE__ 代码编译的日期
__TIME__ 代码编译的时间

静态库的封装和使用

库的概念

  1. 库可以简单看成一组目标文件的集合,将这些目标文件经过压缩打包之后形成的一个文件
  2. 像在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:调用静态库

查看这个文章:

使用VS生成本地静态库文件以及静态库文件的使用

在新建的解决方案中增加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 运行阶段才去链接函数

动态库的封装和使用

查看这个文章:

VS生成和使用动态库(.dll)

具体代码与静态库的一样。

动态库封装细节

__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
请按任意键继续. . .

面向接口

背景:一般的企业信息系统都有成熟的框架。
软件框架一般不发生变化,能自由的集成第三方厂商的产品。
要求在企业信息系统框架中集成第三方厂商的游戏功能产品。
软件设计要求:能够满足用户需求,完成的产品可以与用户完美对接。

  1. 抽象游戏中玩家结构体设计(struct Player)
  2. 框架接口设计(playGame)
    初始化游戏
    核心功能战斗
    查看玩家信息
    结束游戏
  3. 游戏厂商1入围(GameCompany1)
    游戏厂商2入围(GameCompany2)
  4. 框架接口分文件编写

猜你喜欢

转载自blog.csdn.net/m0_48948682/article/details/126097947
今日推荐