为什么样C/C++相同内存布局的struct不能互相cast?如何调用主板上的蜂鸣器播放一定频率的音乐

发表时间:2017-12-12 08:48:02 作者: 来源: 浏览:

在上一篇文章中,小编为您详细介绍了关于《为什么样小米声称红米 2 有 1GB 内存就够?小米5、红米Pro、红米Note3的对比》相关知识。本篇中小编将再为您讲解标题为什么样C/C++相同内存布局的struct不能互相cast?如何调用主板上的蜂鸣器播放一定频率的音乐。

struct a {n int b;n};nnstruct c {n int b;n};nnint main() {n a a_;n c c_ = reinterpret_castc(a_);n return ⓪;n}

struct a和struct b的内存布局没理由不①样吧. 但我根本没办法用简单的方法cast. 我唯①找到的解决方案是union, 这是最佳实践吗?

读标准啊, 不要想当然。来,我是搬运工

An expression of integral, enumeration, pointer, or pointer-to-member type can be converted to its own type. The resulting value is the same as the value of expression. Any pointer can be converted to any integral type large enough to hold the value of the pointer (e.g. to std::uintptr_t)A value of any integral or enumeration type can be converted to a pointer type. A pointer converted to an integer of sufficient size and back to the same pointer type is guaranteed to have its original value, otherwise the resulting pointer cannot be dereferenced safely (the round-trip conversion in the opposite direction is not guaranteed; the same pointer may have multiple integer representations) The null pointer constant NULL or integer zero is not guaranteed to yield the null pointer value of the target type; static_cast or implicit conversion should be used for this purpose.Any value of type std::nullptr_t, including nullptr can be converted to any integral type as if it were (void*)⓪ · but no value, not even nullptr can be converted to std::nullptr_t: static_cast should be used for that purpose. (since C++①①)Any pointer to object of type T① can be converted to pointer to object of another type cv T②. This is exactly equivalent to static_cast(static_cast(expression)) (which implies that if T②\'s alignment requirement is not stricter than T①\'s, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if allowed by the type aliasing rules (see below)An lvalue expression of type T① can be converted to reference to another type T②. The result is an lvalue or xvalue referring to the same object as the original lvalue, but with a different type. No temporary is created, no copy is made, no constructors or conversion functions are called. The resulting reference can only be accessed safely if allowed by the type aliasing rules (see below)Any pointer to function can be converted to a pointer to a different function type. Calling the function through a pointer to a different function type is undefined, but converting such pointer back to pointer to the original function type yields the pointer to the original function.On some implementations (in particular, on any POSIX compatible system as required by dlsym), a function pointer can be converted to void* or any other object pointer, or vice versa. If the implementation supports conversion in both directions, conversion to the original type yields the original value, otherwise the resulting pointer cannot be dereferenced or called safely.The null pointer value of any pointer type can be converted to any other pointer type, resulting in the null pointer value of that type. Note that the null pointer constant nullptr or any other value of type std::nullptr_t cannot be converted to a pointer with reinterpret_cast: implicit conversion or static_cast should be used for this purpose.An rvalue pointer to member function can be converted to pointer to a different member function of a different type. Conversion to the original type yields the original value, otherwise the resulting pointer cannot be used safely.An rvalue pointer to member object of some class T① can be converted to a pointer to another member object of another class T②. If T②\'s alignment is not stricter than T①\'s, conversion to the original type yields the original value, otherwise the resulting pointer cannot be used safely.

所以像你这种情况,估计你的意图是不给c_分配内存,希望它直接使用a_的内存, 那么你有两种做法: c &c_ = reinterpret_cast(a_) 对应上面的规则⑥ 或者 c *c_ = reinterpret_cast(&a_) 对应上面的规则⑤

如果你并没有让c_直接用a_的内存的意图, 那么memcpy多直接。。。

用程序直接从MP③上扒谱是做不到的,能做到效果也不好。最好去找现成的谱子或者自己扒下来。

至于音高和频率的关系,可以看这里⑩②平均律_百度百科。

也就是说,A是④④⓪HZ的话,那么中央C就是②⑥①.⑥HZ≈②⑥②HZ。

至于效果,就取决于硬件设备,开发环境和你的优化了。

另外与其用蜂鸣器,windows下还不如用直接调用MIDI播放的有关API,效果更好,多通道多乐器,时间控制精准。

=============================

随便写了①个用蜂鸣器的例子,C#版,林俊杰的《不为谁而作的歌》。

先放图片种:

源码:

using System;using System.ComponentModel;using System.Threading;namespace CSharpBeepMusic{ class Program { //时长枚举 enum Duration { WHOLE = ⑧⓪⓪ · HALF = WHOLE / ② · QUARTER = HALF / ② · } //音调枚举 enum Tone { REST = ⓪ · C = ②⑥② · Cs = ②⑦⑦ · D = ②⑨④ · Ds = ③①① · E = ③③⓪ · F = ③④⑨ · Fs = ③⑦⓪ · G = ③⑨② · Gs = ④①⑤ · A = ④④⓪ · As = ④⑥⑥ · B = ④⑨④ · hC = ⑤②③ · hCs = ⑤⑤④ · hD = ⑤⑧⑦ · hDs = ⑥②② · hE = ⑥⑤⑨ · hF = ⑥⑨⑧ · hFs = ⑦④⓪ · hG = ⑦⑧④ · hGs = ⑧③① · hA = ⑧⑧⓪ · hAs = ⑨③② · hB = ⑨⑧⑧ · } //音符结构 struct Note { public Int③② Tone; public Int③② Time; public Note(Tone tone, Duration time) { Tone = (Int③②)tone; Time = (Int③②)time; } } //乐谱 static Note[] BeepScore = { new Note(Tone.A,Duration.HALF),new Note(Tone.Fs,Duration.HALF),new Note(Tone.A,Duration.WHOLE),new Note(Tone.A,Duration.QUARTER),new Note(Tone.B,Duration.HALF),new Note(Tone.hCs,(Int③②)Duration.QUARTER+Duration.WHOLE), new Note(Tone.hE,Duration.QUARTER),new Note(Tone.hE,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hE,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.A,Duration.QUARTER),new Note(Tone.B,(Int③②)Duration.QUARTER+Duration.WHOLE), new Note(Tone.hD,Duration.HALF),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,Duration.WHOLE),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,Duration.HALF),new Note(Tone.hE,Duration.HALF), new Note(Tone.hF,Duration.HALF),new Note(Tone.hE,Duration.HALF),new Note(Tone.hD,Duration.WHOLE),new Note(Tone.As,Duration.HALF),new Note(Tone.A,Duration.WHOLE),new Note(Tone.G,Duration.QUARTER),new Note(Tone.A,(Int③②)Duration.WHOLE+Duration.QUARTER), new Note(Tone.A,Duration.HALF),new Note(Tone.Fs,Duration.HALF),new Note(Tone.A,Duration.WHOLE),new Note(Tone.A,Duration.QUARTER),new Note(Tone.B,Duration.HALF),new Note(Tone.hCs,(Int③②)Duration.QUARTER+Duration.WHOLE), new Note(Tone.hE,Duration.QUARTER),new Note(Tone.hE,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hE,Duration.QUARTER),new Note(Tone.hFs,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hFs,Duration.HALF),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,(Int③②)Duration.QUARTER+(Int③②)Duration.WHOLE+Duration.HALF), new Note(Tone.B,Duration.HALF),new Note(Tone.hD,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,Duration.QUARTER),new Note(Tone.hE,Duration.QUARTER), new Note(Tone.hF,Duration.WHOLE),new Note(Tone.hE,Duration.HALF),new Note(Tone.hD,(Int③②)Duration.WHOLE+Duration.WHOLE), new Note(Tone.A,Duration.HALF),new Note(Tone.B,Duration.HALF),new Note(Tone.hD,(Int③②)Duration.WHOLE+Duration.QUARTER),new Note(Tone.A,Duration.QUARTER),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hD,Duration.HALF),new Note(Tone.hE,Duration.HALF), new Note(Tone.hCs,(Int③②)Duration.WHOLE+(Int③②)Duration.WHOLE+Duration.WHOLE), new Note(Tone.REST,Duration.HALF), new Note(Tone.A,Duration.HALF), new Note(Tone.B,Duration.HALF),new Note(Tone.hD,(Int③②)Duration.WHOLE+Duration.QUARTER),new Note(Tone.A,Duration.QUARTER),new Note(Tone.B,Duration.QUARTER),new Note(Tone.hD,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hD,Duration.WHOLE), new Note(Tone.hA,Duration.HALF),new Note(Tone.hFs,Duration.WHOLE),new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hE,Duration.QUARTER),new Note(Tone.hE,Duration.WHOLE), new Note(Tone.REST,Duration.HALF),new Note(Tone.A,Duration.HALF),new Note(Tone.A,Duration.WHOLE),new Note(Tone.A,Duration.WHOLE),new Note(Tone.A,(Int③②)Duration.WHOLE+Duration.WHOLE), new Note(Tone.hFs,Duration.HALF),new Note(Tone.hA,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hA,Duration.HALF),new Note(Tone.hG,Duration.HALF),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hCs,(Int③②)Duration.WHOLE+Duration.QUARTER), new Note(Tone.hFs,Duration.HALF),new Note(Tone.hA,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hA,Duration.HALF),new Note(Tone.hG,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hD,Duration.WHOLE), new Note(Tone.hFs,Duration.HALF),new Note(Tone.hA,Duration.HALF),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.HALF),new Note(Tone.hB,(Int③②)Duration.HALF+Duration.QUARTER),new Note(Tone.hD,Duration.HALF), new Note(Tone.hD,Duration.HALF),new Note(Tone.As,Duration.QUARTER),new Note(Tone.hD,(Int③②)Duration.WHOLE+Duration.QUARTER), new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hD,Duration.QUARTER),new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hD,Duration.QUARTER),new Note(Tone.hD,Duration.HALF+(Int③②)Duration.WHOLE), new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.HALF+(Int③②)Duration.QUARTER),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.HALF+(Int③②)Duration.QUARTER),new Note(Tone.hG,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hCs,Duration.WHOLE), new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.HALF+(Int③②)Duration.QUARTER),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.HALF+(Int③②)Duration.QUARTER),new Note(Tone.hG,Duration.HALF),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hD,Duration.WHOLE), new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hA,Duration.QUARTER),new Note(Tone.hB,Duration.WHOLE),new Note(Tone.hD,Duration.QUARTER),new Note(Tone.hE,Duration.HALF),new Note(Tone.hFs,Duration.HALF+(Int③②)Duration.QUARTER), new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.HALF),new Note(Tone.hG,Duration.QUARTER),new Note(Tone.hFs,Duration.QUARTER),new Note(Tone.hD,Duration.QUARTER), new Note(Tone.hE,Duration.WHOLE),new Note(Tone.hD,(Int③②)Duration.WHOLE+Duration.WHOLE),new Note(Tone.REST,Duration.WHOLE), new Note(Tone.hCs,Duration.HALF),new Note(Tone.hE,Duration.WHOLE),new Note(Tone.hD,Duration.WHOLE+(Int③②)Duration.HALF+(Int③②)Duration.WHOLE+(Int③②)Duration.WHOLE) }; static BackgroundWorker BeepThead = new BackgroundWorker(); static void Main(string[] args) { BeepThead.WorkerSupportsCancellation = true; BeepThead.DoWork += BeepThead_DoWork; Console.CursorVisible = false; Console.Write(\"┏━━━━━━━━━━━━━━━┓n┃ 《不为谁而作的歌》BEEP版 ┃n┣━━━━━━━━━━━━━━━┫n┃ 曲:林俊杰 简编/程序:雨异 ┃n┣━━━━━━━━━━━━━━━┫n┃ P=播放/停止 ┃n┗━━━━━━━━━━━━━━━┛\"); do { if (Console.ReadKey(true).Key == ConsoleKey.P) { if (BeepThead.IsBusy) { BeepThead.CancelAsync(); } else { BeepThead.RunWorkerAsync(); } } } while (true); } static void BeepThead_DoWork(object sender, DoWorkEventArgs e) { Int③② index = ⓪; do { if (BeepScore[index].Tone == ⓪) { Thread.Sleep(BeepScore[index].Time); } else { Console.Beep(BeepScore[index].Tone, BeepScore[index].Time); } ++index; if (index == BeepScore.Length) { index = ⓪; Thread.Sleep(②⓪⓪⓪); } } while (BeepThead.CancellationPending == false); e.Cancel = true; } }}

编后语:关于《为什么样C/C++相同内存布局的struct不能互相cast?如何调用主板上的蜂鸣器播放一定频率的音乐》关于知识就介绍到这里,希望本站内容能让您有所收获,如有疑问可跟帖留言,值班小编第一时间回复。 下一篇内容是有关《湛江市是华南还是华北?移动cpu和桌面cpu》,感兴趣的同学可以点击进去看看。

资源转载网络,如有侵权联系删除。

相关资讯推荐

相关应用推荐

玩家点评

条评论

热门下载

  • 手机网游
  • 手机软件

热点资讯

  • 最新话题