C 练习实例61 – 杨辉三角形:从零开始理解二维数组的实用应用
在学习 C 语言的过程中,杨辉三角形是一个经典且极具教学意义的练习题。它不仅帮助初学者掌握循环嵌套、数组操作等核心语法,更让中级开发者深入理解二维数组的逻辑结构与实际用途。今天我们就来一起完成这个 C 练习实例61 – 杨辉三角形,带你一步步从零构建出完整的程序。
杨辉三角形,也叫帕斯卡三角形,是一个由数字构成的三角形图案。它的每一行都遵循一个简单的规则:除了首尾两个数为 1 之外,其余每个数都是它上方两个数的和。这个规律看似简单,却蕴含了组合数学的深刻原理。
想象一下,你正在搭建一座积木塔。最顶层只有一块积木,第二层放两块,第三层三块……每一块积木的重量,都来自它上面两块积木的合力。杨辉三角形中的每一个数字,正是这种“合力”的体现。
理解杨辉三角形的数学规律
要编写程序,首先得搞清楚它的数学规律。我们来看前几行的杨辉三角形:
第 1 行: 1
第 2 行: 1 1
第 3 行: 1 2 1
第 4 行: 1 3 3 1
第 5 行: 1 4 6 4 1
第 6 行: 1 5 10 10 5 1
观察可以发现:
- 每一行的开头和结尾都是 1。
- 中间任意位置的元素
triangle[i][j],等于上一行的triangle[i-1][j-1] + triangle[i-1][j]。 - 第 n 行有 n 个元素。
这个规律正是我们编写程序的核心逻辑。我们可以把它想象成一个“接力传递”的过程:每一行的数字,都是从上一行“接棒”后相加而来的。
创建数组与初始化
在 C 语言中,二维数组是实现杨辉三角形最直观的方式。我们使用一个固定大小的数组来存储每一行的值,比如定义一个 10x10 的数组,足够容纳前 10 行的杨辉三角形。
#include <stdio.h>
int main() {
int n = 6; // 设置要打印的行数,这里为 6 行
int triangle[10][10]; // 定义一个 10x10 的二维数组,用于存储杨辉三角形
// 初始化所有元素为 0,防止未赋值导致的随机值
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
triangle[i][j] = 0;
}
}
return 0;
}
这里的关键是:初始化数组为 0。这一步非常重要。因为 C 语言不会自动初始化局部变量,如果不对数组清零,内存中可能残留旧数据,导致计算错误。
我们用双层循环遍历整个数组,将每个元素设置为 0。这就像在搭建积木前,先清理干净工作台,确保每一块积木都从零开始。
构建杨辉三角形的逻辑实现
现在我们来填充三角形的数值。核心思路是:
- 第 0 行(第一行):只放一个 1。
- 第 i 行(第 i+1 行):第一个和最后一个元素设为 1,中间的元素由上一行的两个值相加得到。
// 开始构建杨辉三角形
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) { // 第 i 行有 i+1 个元素,j 从 0 到 i
if (j == 0 || j == i) {
// 首尾元素都是 1
triangle[i][j] = 1;
} else {
// 中间元素 = 上一行的左上 + 上一行的右上
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
}
}
这段代码是整个程序的“心脏”。我们来逐行解释:
for (int i = 0; i < n; i++):外层循环控制行数,i 从 0 开始,表示第 i+1 行。for (int j = 0; j <= i; j++):内层循环控制列数,每行的列数等于行号加 1。if (j == 0 || j == i):判断是否为该行的第一个或最后一个元素,是则赋值为 1。else分支:中间元素,从上一行的两个位置相加得到。
这个逻辑就像一场“接力赛”:每跑一步,选手都要把前两步的接力棒接过来,然后传递给下一个选手。
打印杨辉三角形:格式化输出技巧
构建完数据后,我们需要将结果打印出来。为了让输出看起来像一个三角形,我们需要对空格进行控制,每行前面补上适当的空格。
// 打印杨辉三角形
for (int i = 0; i < n; i++) {
// 打印前导空格,使三角形居中
for (int k = 0; k < n - i - 1; k++) {
printf(" "); // 两个空格,保持对齐
}
// 打印该行的数字
for (int j = 0; j <= i; j++) {
printf("%2d ", triangle[i][j]); // %2d 表示每个数字占 2 个字符宽度
}
printf("\n"); // 换行
}
这里有几个关键点:
n - i - 1:前导空格的数量,随着行数增加而减少,实现居中对齐。printf(" ");:每个空格用两个空格,避免数字挤在一起。%2d:格式化输出,确保每个数字占据两个字符宽度,即使是一位数也会补一个空格。- 最后一个
printf("\n");:换行,保证每行独立。
这样输出的效果是:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
看起来是不是非常规整?这就是格式化输出的魅力所在。
完整代码示例与运行结果
下面是完整的 C 练习实例61 – 杨辉三角形程序:
#include <stdio.h>
int main() {
int n = 6; // 可修改行数,比如改为 10 或 15
int triangle[10][10];
// 初始化数组为 0
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
triangle[i][j] = 0;
}
}
// 构建杨辉三角形
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
triangle[i][j] = 1;
} else {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
}
}
// 打印杨辉三角形
for (int i = 0; i < n; i++) {
// 打印前导空格
for (int k = 0; k < n - i - 1; k++) {
printf(" ");
}
// 打印数字
for (int j = 0; j <= i; j++) {
printf("%2d ", triangle[i][j]);
}
printf("\n");
}
return 0;
}
运行结果如下(6 行):
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
你可以尝试修改 n 的值,比如设为 10,看看更大的三角形长什么样。你会发现,随着行数增加,数字增长得非常快,这正是组合数的体现。
深入理解:为什么使用二维数组?
在 C 语言中,数组是内存中连续的存储单元。二维数组本质上是一个“数组的数组”。当我们定义 int triangle[10][10],系统会在内存中开辟一个 10×10 的格子,每个格子存放一个整数。
使用二维数组的好处是:
- 可以通过
triangle[i][j]直接访问第 i 行第 j 列的元素。 - 支持随机访问,适合需要反复查询的场景。
- 逻辑清晰,代码易读。
当然,也可以用一维数组模拟二维结构,但会增加复杂度。对于杨辉三角形这种按行构建、逐行访问的场景,二维数组是最自然的选择。
小结与拓展建议
C 练习实例61 – 杨辉三角形,虽然看似简单,却涵盖了 C 语言中多个重要知识点:数组定义、嵌套循环、条件判断、格式化输出、内存管理等。它不仅是编程练习,更是一次对逻辑思维的训练。
如果你已经掌握这个例子,可以尝试以下拓展:
- 改写程序,让用户输入行数。
- 用递归方式实现杨辉三角形的某一项。
- 打印奇数行用红色,偶数行用绿色(配合 ANSI 转义码)。
- 将结果写入文件,而不是只打印在控制台。
编程的本质,不是记住多少语法,而是理解问题背后的逻辑。杨辉三角形就是这样一座桥梁——从简单的数字规律,通向更复杂的算法与数学之美。
希望这篇教程能帮你扎实掌握 C 语言的核心能力。每一次动手写代码,都是在为未来的程序世界打地基。继续加油!