C++过生日(我给我自己做的生日礼物)

C++过生日(我给我自己做的生日礼物)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
🚀欢迎互三👉:程序猿方梓燚 💎💎
🚀关注博主,后期持续更新系列文章
🚀如果有错误感谢请大家批评指出,及时修改
🚀感谢大家点赞👍收藏⭐评论✍

引言

今天是我的生日,我写了一段代码作为自己的生日礼物。

一、项目要求

主要功能是播放一段音乐旋律并展示一张图片,模拟 “祝我生日快乐” 的场景。

二、代码详解

一、包含的头文件及库

#include<iostream>// 引入输入输出流头文件,用于控制台的输入输出操作。#include<Windows.h>// 提供与 Windows 操作系统交互的功能,在这里用于播放 MIDI 音乐。#include<cstdio>// 提供标准输入输出函数。#include<cstdlib>// 提供通用的函数,如内存分配等。#include<graphics.h>// 用于图形绘制,可创建图形窗口和进行图像显示等操作。#include<conio.h>// 提供控制台输入输出相关功能,如获取用户输入等。#include<thread>// 支持多线程编程,允许同时执行多个任务。

这部分代码引入了多个头文件,为程序提供了不同的功能支持。iostream用于输入输出操作,Windows.h用于与 Windows 系统交互以播放 MIDI 音乐,cstdiocstdlib提供了 C 风格的输入输出和通用函数,graphics.h用于图形绘制,conio.h用于控制台输入输出,thread用于多线程编程。

二、枚举定义

音阶枚举Scale

enumScale{ Rest =0, C8 =108, B7 =107, A7s =106, A7 =105, G7s =104, G7 =103, F7s =102, F7 =101, E7 =100, D7s =99, D7 =98, C7s =97, C7 =96, B6 =95, A6s =94, A6 =93, G6s =92, G6 =91, F6s =90, F6 =89, E6 =88, D6s =87, D6 =86, C6s =85, C6 =84, B5 =83, A5s =82, A5 =81, G5s =80, G5 =79, F5s =78, F5 =77, E5 =76, D5s =75, D5 =74, C5s =73, C5 =72, B4 =71, A4s =70, A4 =69, G4s =68, G4 =67, F4s =66, F4 =65, E4 =64, D4s =63, D4 =62, C4s =61, C4 =60, B3 =59, A3s =58, A3 =57, G3s =56, G3 =55, F3s =54, F3 =53, E3 =52, D3s =51, D3 =50, C3s =49, C3 =48, B2 =47, A2s =46, A2 =45, G2s =44, G2 =43, F2s =42, F2 =41, E2 =40, D2s =39, D2 =38, C2s =37, C2 =36, B1 =35, A1s =34, A1 =33, G1s =32, G1 =31, F1s =30, F1 =29, E1 =28, D1s =27, D1 =26, C1s =25, C1 =24, B0 =23, A0s =22, A0 =21};

这个枚举定义了不同的音阶,从最低音A0到最高音C8,还包括一个休止符Rest。它为后续播放音乐时表示不同的音符提供了一种方便的方式。

声音枚举Voice

enumVoice{ X1 = C2, X2 = D2, X3 = E2, X4 = F2, X5 = G2, X6 = A2, X7 = B2, L1 = C3, L2 = D3, L3 = E3, L4 = F3, L5 = G3, L6 = A3, L7 = B3, M1 = C4, M2 = D4, M3 = E4, M4 = F4, M5 = G4, M6 = A4, M7 = B4, H1 = C5, H2 = D5, H3 = E5, H4 = F5, H5 = G5, H6 = A5, H7 = B5, LOW_SPEED =500, MIDDLE_SPEED =400, HIGH_SPEED =300, _ =0XFF};

这个枚举定义了不同的音符以及一些特殊的值。其中,从X1H7分别对应不同的音符,LOW_SPEEDMIDDLE_SPEEDHIGH_SPEED表示不同的播放速度,_是一个占位符。这个枚举为播放音乐提供了更多的控制选项。
枚举定义部分的作用是为程序中的不同音符和特殊值提供一种易于理解和使用的命名方式,使得代码更加清晰可读。同时,也方便在后续的代码中进行音乐播放和控制。

三、函数实现

播放音乐函数SRKL

voidSRKL(){ HMIDIOUT handle;// 打开一个 MIDI 输出设备,并将设备句柄存储在 handle 变量中。midiOutOpen(&handle,0,0,0, CALLBACK_NULL);int volume =0x7f;// 定义音量为 0x7f。int voice =0x0;// 初始化音符编号为 0。int sleep =400;// 定义初始延迟时间为 400 毫秒。int tmp =6;// 定义一个临时变量 tmp 并初始化为 6。int srkl[]={ L5, L5, L6, _, L5, _, M1, _, L7, _, _, _, L5, L5, L6, _, L5, _, M2, _, M1, _, _, L5, L5, M5, _, M3, _, M1, _, L7, _, L6, _, M4, M4, M3, _, M1, _, M2, _, M1, _, _, _, L5, L5, L6, _, L5, _, M1, _, L7, _, _, _, L5, L5, L6, _, L5, _, M2, _, M1, _, _, L5, L5, M5, _, M3, _, M1, _, L7, _, L6, _, M4, M4, M3, _, M1, _, M2, _, M1, _, _, _,};// 定义一个数组 srkl,其中包含了一系列音符和特殊标识,用于播放音乐旋律。for(int i : srkl){if(i == LOW_SPEED || i == HIGH_SPEED || i == MIDDLE_SPEED){ sleep = i;// 如果当前元素是速度标识(LOW_SPEED、HIGH_SPEED、MIDDLE_SPEED),则更新延迟时间 sleep。continue;}if(i ==0){ sleep =200;// 如果当前元素是 0,则将延迟时间设置为 200 毫秒。continue;}if(i ==700){Sleep(200);// 如果当前元素是 700,则延迟 200 毫秒。continue;}if(i == _){Sleep(400);// 如果当前元素是占位符 _,则延迟 400 毫秒。continue;}if(i ==1000){ tmp +=5;// 如果当前元素是 1000,则增加临时变量 tmp 的值。continue;} voice =(volume <<16)+((i + tmp)<<8)+0x90;// 计算音符编号 voice。midiOutShortMsg(handle, voice);// 通过 MIDI 输出设备发送音符编号播放音符。Sleep(sleep);// 根据延迟时间 sleep 进行延迟。}midiOutClose(handle);// 关闭 MIDI 输出设备。}

这个函数用于播放一段特定的音乐旋律。它通过打开 MIDI 输出设备,设置音量、延迟时间等参数,然后遍历一个音符数组,根据不同的音符值进行不同的操作,包括播放音符、设置延迟时间等。最后关闭 MIDI 输出设备。

展示图片函数photo

voidphoto(){initgraph(614,446);// 初始化图形窗口,设置窗口大小为 614x446。// 加载图片IMAGE img;loadimage(&img,"res\\1.png");// 加载名为“res\\1.png”的图片到 IMAGE 对象 img 中。// 在窗口中绘制图片putimage(0,0,&img);// 在图形窗口的左上角(0,0)位置绘制图片。_getch();// 等待用户输入。closegraph();// 关闭图形窗口。}

这个函数用于在图形窗口中展示一张图片。它首先初始化图形窗口,然后加载指定的图片,将图片绘制在窗口中,等待用户输入后关闭图形窗口。

四、主函数main

intmain(){system("title 祝我生日快乐");// 设置控制台窗口标题为“祝我生日快乐”。 thread musicThread(SRKL); thread photoThread(photo);// 创建两个线程,一个线程执行 SRKL 函数播放音乐,另一个线程执行 photo 函数展示图片。 musicThread.join(); photoThread.join();// 等待两个线程执行完毕。return0;}

主函数首先设置控制台窗口标题,然后创建两个线程分别用于播放音乐和展示图片。接着,等待这两个线程执行完毕,最后返回 0,表示程序正常结束。

三、完整代码

#include<iostream>// 引入输入输出流头文件,用于控制台的输入输出操作。#include<Windows.h>// 提供与 Windows 操作系统交互的功能,在这里用于播放 MIDI 音乐。#include<cstdio>// 提供标准输入输出函数。#include<cstdlib>// 提供通用的函数,如内存分配等。#include<graphics.h>// 用于图形绘制,可创建图形窗口和进行图像显示等操作。#include<conio.h>// 提供控制台输入输出相关功能,如获取用户输入等。#include<thread>// 支持多线程编程,允许同时执行多个任务。#pragmacomment(lib,"winmm.lib")// 链接 winmm.lib 库,用于播放 MIDI 音乐。// 定义音阶枚举enumScale{ Rest =0,// 表示休止符,值为 0。 C8 =108,// 表示高音 C,音符值为 108。 B7 =107,// 以下类似,分别表示不同的音符。 A7s =106, A7 =105, G7s =104, G7 =103, F7s =102, F7 =101, E7 =100, D7s =99, D7 =98, C7s =97, C7 =96, B6 =95, A6s =94, A6 =93, G6s =92, G6 =91, F6s =90, F6 =89, E6 =88, D6s =87, D6 =86, C6s =85, C6 =84, B5 =83, A5s =82, A5 =81, G5s =80, G5 =79, F5s =78, F5 =77, E5 =76, D5s =75, D5 =74, C5s =73, C5 =72, B4 =71, A4s =70, A4 =69, G4s =68, G4 =67, F4s =66, F4 =65, E4 =64, D4s =63, D4 =62, C4s =61, C4 =60, B3 =59, A3s =58, A3 =57, G3s =56, G3 =55, F3s =54, F3 =53, E3 =52, D3s =51, D3 =50, C3s =49, C3 =48, B2 =47, A2s =46, A2 =45, G2s =44, G2 =43, F2s =42, F2 =41, E2 =40, D2s =39, D2 =38, C2s =37, C2 =36, B1 =35, A1s =34, A1 =33, G1s =32, G1 =31, F1s =30, F1 =29, E1 =28, D1s =27, D1 =26, C1s =25, C1 =24, B0 =23, A0s =22, A0 =21};// 定义声音枚举enumVoice{ X1 = C2,// 将 X1 定义为 C2 对应的音符值。 X X2 = D2,// 以下类似,分别对应不同的音符。 X3 = E2, X4 = F2, X5 = G2, X6 = A2, X7 = B2, L1 = C3, L2 = D3, L3 = E3, L4 = F3, L5 = G3, L6 = A3, L7 = B3, M1 = C4, M2 = D4, M3 = E4, M4 = F4, M5 = G4, M6 = A4, M7 = B4, H1 = C5, H2 = D5, H3 = E5, H4 = F5, H5 = G5, H6 = A5, H7 = B5, LOW_SPEED =500,// 定义低速度播放对应的延迟时间为 500 毫秒。 MIDDLE_SPEED =400,// 定义中速度播放对应的延迟时间为 400 毫秒。 HIGH_SPEED =300,// 定义高速度播放对应的延迟时间为 300 毫秒。 _ =0XFF// 定义一个占位符,值为 0XFF。};// 播放音乐的函数voidSRKL(){ HMIDIOUT handle;// 定义一个 MIDI 输出设备句柄。midiOutOpen(&handle,0,0,0, CALLBACK_NULL);// 打开 MIDI 输出设备,并将句柄存储在 handle 中。int volume =0x7f;// 定义音量为 0x7f。int voice =0x0;// 初始化音符编号为 0。int sleep =400;// 定义初始延迟时间为 400 毫秒。int tmp =6;// 定义一个临时变量 tmp 并初始化为 6。int srkl[]={ L5, L5, L6, _, L5, _, M1, _, L7, _, _, _, L5, L5, L6, _, L5, _, M2, _, M1, _, _, L5, L5, M5, _, M3, _, M1, _, L7, _, L6, _, M4, M4, M3, _, M1, _, M2, _, M1, _, _, _, L5, L5, L6, _, L5, _, M1, _, L7, _, _, _, L5, L5, L6, _, L5, _, M2, _, M1, _, _, L5, L5, M5, _, M3, _, M1, _, L7, _, L6, _, M4, M4, M3, _, M1, _, M2, _, M1, _, _, _,};// 定义一个数组 srkl,其中包含了一系列音符和特殊标识,用于播放音乐旋律。for(int i : srkl){if(i == LOW_SPEED || i == HIGH_SPEED || i == MIDDLE_SPEED){ sleep = i;// 如果当前元素是速度标识(LOW_SPEED、HIGH_SPEED、MIDDLE_SPEED),则更新延迟时间 sleep。continue;}if(i ==0){ sleep =200;// 如果当前元素是 0,则将延迟时间设置为 200 毫秒。continue;}if(i ==700){Sleep(200);// 如果当前元素是 700,则延迟 200 毫秒。continue;}if(i == _){Sleep(400);// 如果当前元素是占位符 _,则延迟 400 毫秒。continue;}if(i ==1000){ tmp +=5;// 如果当前元素是 1000,则增加临时变量 tmp 的值。continue;} voice =(volume <<16)+((i + tmp)<<8)+0x90;// 计算音符编号 voice。midiOutShortMsg(handle, voice);// 通过 MIDI 输出设备发送音符编号播放音符。Sleep(sleep);// 根据延迟时间 sleep 进行延迟。}midiOutClose(handle);// 关闭 MIDI 输出设备。}voidphoto(){initgraph(614,446);// 初始化图形窗口,设置窗口大小为 614x446。// 加载图片 IMAGE img;loadimage(&img,"res\\1.png");// 加载名为“res\\1.png”的图片到 IMAGE 对象 img 中。// 在窗口中绘制图片putimage(0,0,&img);// 在图形窗口的左上角(0,0)位置绘制图片。_getch();// 等待用户输入。closegraph();// 关闭图形窗口。}intmain(){system("title 祝我生日快乐");// 设置控制台窗口标题为“祝我生日快乐”。 thread musicThread(SRKL);// 创建一个线程 musicThread,用于执行播放音乐的函数 SRKL。 thread photoThread(photo);// 创建一个线程 photoThread,用于执行展示图片的函数 photo。 musicThread.join();// 等待 musicThread 线程执行完毕。 photoThread.join();// 等待 photoThread 线程执行完毕。return0;}

四、总结

该程序通过结合音乐播放和图片展示,为用户提供了一种多媒体的体验。利用多线程技术确保音乐和图片的展示可以同时进行,提高了程序的效率和用户体验。同时,代码中的枚举定义使得音符和特殊值的表示更加清晰可读,方便了音乐播放的控制。

五、素材

高清无水印图片素材如下↓↓↓

在这里插入图片描述

Read more

Neo4j 知识讲解与在线工具使用教程

图数据库领域的核心工具 ——Neo4j,同时详细拆解其在线预览控制台(https://console-preview.neo4j.io/)的使用方法,以及查询工具(https://console-preview.neo4j.io/tools/query)的模块功能。 一、Neo4j 核心知识铺垫 在使用工具前,我们需要先理解 Neo4j 的本质和核心概念,这是后续操作的基础。 1. 什么是 Neo4j? Neo4j 是世界上最流行的原生图数据库(Native Graph Database),专门用于存储、查询和分析 “实体之间的关联关系”。它与我们熟悉的 MySQL 等关系型数据库的核心差异的是: * 关系型数据库(MySQL):用 “表 + 行 + 外键” 间接表示关联,查询多表关联时需频繁 JOIN,效率低; * 图数据库(Neo4j)

By Ne0inhk
【无人机】无人机路径规划算法

【无人机】无人机路径规划算法

目录 一、引言:无人机与路径规划算法 二、路径规划算法基础 (一)定义与重要性 (二)规划目标与约束条件 三、常见路径规划算法详解 (一)A * 算法 (二)Dijkstra 算法 (三)RRT(快速扩展随机树)算法 (四)蚁群算法 四、算法应用实例与效果展示 (一)不同场景下的算法应用 (二)算法性能对比数据 五、算法的优化与发展趋势 (一)现有算法的优化策略 (二)结合新技术的发展方向 六、挑战与展望 (一)面临的技术挑战 (二)未来应用前景 七、结论 一、引言:无人机与路径规划算法 在科技飞速发展的今天,无人机作为一种极具创新性的技术产物,已深度融入我们生活的方方面面,

By Ne0inhk

简单理解:单片机怎么和FPGA通信

了解单片机与 FPGA 之间的通信方式,这是嵌入式系统中非常常见的硬件交互场景,核心是要根据传输速率、硬件资源、开发复杂度选择合适的通信协议。 一、主流通信方式及实现方案 单片机和 FPGA 通信主要分为并行通信和串行通信两大类,下面按从易到难、从低速到高速的顺序介绍: 1. 通用 IO 口(GPIO)自定义协议(最简单) 适合低速、短距离、数据量小的场景(如按键、状态交互),完全自定义通信规则,开发灵活。 * 硬件连接: * 单片机:1 个输出引脚(发送) + 1 个输入引脚(接收) * FPGA:1 个输入引脚(接收) + 1 个输出引脚(发送) * 需共地,建议加 10K 上拉电阻提高稳定性。 * 单片机端(C 语言,

By Ne0inhk