sound() 是一个在较老的 C 语言标准库(主要是 <conio.h>)中声明的函数,用于让计算机的扬声器发出指定频率的声音,它在现代编程中已经很少被直接使用,但了解它对于学习计算机历史、底层原理或处理一些简单的控制台应用仍然很有价值。

函数简介
sound() 函数的作用是让计算机的扬声器持续发出一个特定频率的声音,直到调用 nosound() 函数来停止。
声明:
#include <dos.h> // 在一些编译器(如 Turbo C/C++)中,它在这个头文件里 // 或者 #include <conio.h> // 在另一些编译器中,它可能在这里
注意: 在现代标准 C 库(如 GCC/Clang 的
libc)中,没有sound()函数,它是一个非标准的、特定于旧操作系统的函数,主要用于 DOS 和早期的 Windows 环境。
函数原型
void sound(unsigned int frequency);
参数:

frequency: 一个无符号整型(unsigned int),代表声音的频率,单位是赫兹。- 频率范围: 通常在 37 Hz 到 32767 Hz 之间,低于 37Hz 的声音人耳听不到,高于 32767Hz 的值会被截断。
- 常用频率示例:
440Hz: 标准音 A (La)262Hz: 中音 C (Do)523Hz: 高音 C (Do)
返回值:
void,没有返回值。
工作原理(简化版)
sound() 函数通过直接操作计算机的硬件(或模拟硬件)来发声,在 DOS 时代,它通过向 8253/8254 可编程间隔定时器 的通道 2 发送一个计数值来控制扬声器的频率,这个计数值由 1193180 / frequency 计算得出,它再通过 8255 可编程外围接口 芯片来控制扬声器的开关,从而发出声音。
sound(frequency) 就是告诉电脑:“请以 frequency 次/秒的频率来开关扬声器”。
最重要的配套函数:nosound()
如果你只调用 sound() 而不调用 nosound(),那么声音将会永远持续下去,直到你的程序结束。sound() 必须与 nosound() 配对使用。

nosound() 函数原型:
#include <dos.h> // 或 <conio.h> void nosound(void);
nosound() 函数的作用是关闭扬声器,停止当前正在播放的声音。
代码示例
下面是一个简单的示例,演示如何使用 sound() 和 nosound() 来播放一个 440Hz 的音调,持续 1 秒钟。
重要提示: 在现代操作系统(如 Windows 10/11, macOS, Linux)上,标准编译器(如 GCC, Clang, MSVC)的默认环境中无法编译和运行这段代码,因为它依赖的底层 DOS API 已经不存在,你需要使用支持这些旧函数的编译器,Turbo C/C++ (在 DOSBox 中运行) 或一些旧版的 Visual C++。
#include <stdio.h>
#include <dos.h> // 包含 sound() 和 nosound() 的声明
#include <conio.h> // 有时也需要这个头文件
int main() {
// 定义要播放的频率 (440 Hz 是标准音 A)
unsigned int frequency = 440;
printf("正在播放 %d Hz 的声音,持续 1 秒...\n", frequency);
// 调用 sound() 开始发声
sound(frequency);
// 暂停程序 1 秒,让声音持续一段时间
// delay() 函数也来自 <dos.h> 或 <conio.h>
delay(1000); // 参数单位是毫秒
// 调用 nosound() 停止发声
nosound();
printf("声音已停止,\n");
return 0;
}
现代替代方案
既然 sound() 已经过时,那么在现代 C 语言中如何播放声音呢?答案是使用平台相关的 API 或跨平台的音频库。
A. 在 Windows 平台上
可以使用 Windows API 中的 PlaySound() 函数,它可以播放 .wav 文件或简单的系统声音。
#include <windows.h>
#include <mmsystem.h> // 需要这个头文件
#pragma comment(lib, "winmm.lib") // 链接 winmm.lib 库
int main() {
// 播放一个系统提示音
PlaySound(TEXT("SystemExclamation"), NULL, SND_ALIAS | SND_ASYNC);
// 播放一个 .wav 文件
// PlaySound(TEXT("my_sound.wav"), NULL, SND_FILENAME | SND_ASYNC);
Sleep(2000); // 暂停 2 秒
return 0;
}
B. 在 Linux/macOS 平台上
可以使用 system() 函数调用命令行工具,如 paplay (PulseAudio) 或 afplay (macOS)。
#include <stdio.h>
#include <stdlib.h> // 用于 system()
int main() {
// 使用 afplay 播放 macOS 系统声音
// system("afplay /System/Library/Sounds/Ping.aiff");
// 使用 paplay 播放一个 .wav 文件 (需要 PulseAudio)
// system("paplay /path/to/your/sound.wav");
printf("请检查你的系统是否安装了相应的音频工具,\n");
return 0;
}
C. 使用跨平台库
对于更复杂的音频需求,应该使用专门的库,
- SDL2 (Simple DirectMedia Layer): 非常流行,功能强大,支持音频、图形、输入等。
- PortAudio: 一个跨平台的音频 I/O 库,非常适合处理实时音频流。
- SFML (Simple and Fast Multimedia Library): 另一个优秀的多媒体库,易于使用。
| 特性 | sound() |
现代替代方案 |
|---|---|---|
| 来源 | 旧式 <dos.h> / <conio.h> |
平台 API (Win32) 或跨平台库 |
| 功能 | 发出单一频率的蜂鸣声 | 播放复杂音效、音乐、流式音频 |
| 兼容性 | 极差,仅限 DOS 和旧 Windows | 良好,可在现代系统上运行 |
| 易用性 | 非常简单 | 相对复杂,需要学习 API/库 |
| 适用场景 | 学习、怀旧、极简控制台应用 | 游戏、多媒体应用、专业音频处理 |
sound() 是一个有趣的历史遗留函数,可以帮助你理解计算机是如何与硬件交互的,但在实际开发中,你应该选择更现代、更强大的工具来处理音频。
