C 语言实战:数组实现斐波那契数列(格式化输出 + 边界校验)
斐波那契数列是编程入门的经典案例,其 “前两项之和等于后一项” 的规律,适合练习数组存储、循环逻辑与格式化输出。本文以 “输出斐波那契数列前 n 项,每行显示 5 个且对齐” 为例,拆解数组实现思路、边界校验逻辑与格式化输出技巧,同时优化代码规范性,帮助新手掌握数列生成与格式控制的核心方法。
一、斐波那契数列核心规则
斐波那契数列定义:
- 第 1 项、第 2 项固定为 1;
- 从第 3 项开始,每一项 = 前两项之和(如:1,1,2,3,5,8,13...);
- 核心需求:用户输入项数 n,输出前 n 项,每行显示 5 个,数字右对齐保证格式整洁。
二、优化后完整代码(规范 + 无 BUG)
/******************************
*文件名称:Fibonacci.c
*作者:czy
*邮箱:caozhiyang_0613@163.com
*创建日期:2025/12/25
*修改日期:2025/12/25
*文件功能:利用数组实现斐波那契数列的前n项,格式化对齐且每行输出5个数
*核心规则:斐波那契数列:1 1 2 3 5 8 13 21……
*****************************/
#include<stdio.h>
int main()
{
int n;
printf("输入斐波那契数列项数:");
scanf("%d",&n);
// 边界校验:项数必须为正整数,非法输入直接退出
if(n<=0)
{
printf("错误:必须输入正整数!\n");
return 1; // 返回非0值表示程序异常退出
}
// 定义数组存储斐波那契数列(变长数组,C99及以上支持)
int a[n];
int i;
// 初始化前两项
a[0] = 1;
if(n >= 2)
{
a[1] = 1;
}
// 生成第3项到第n项
for(i=2; i<n; i++)
{
a[i] = a[i-1] + a[i-2];
}
// 格式化输出:每行5个,右对齐占10个字符宽度
printf("前%d项斐波那契数列:\n", n);
for(i=0; i<n; i++)
{
printf("%10d", a[i]); // %10d:右对齐,不足10位补空格
// 每输出5个数字换行
if((i+1) % 5 == 0)
{
printf("\n");
}
}
// 最后一行不足5个时,补充换行(避免输出卡在行尾)
if(n % 5 != 0)
{
printf("\n");
}
return 0; // 程序正常退出
}
三、代码核心逻辑拆解
1. 边界校验:避免非法输入
c
运行
if(n<=0)
{
printf("错误:必须输入正整数!\n");
return 1;
}
- 若用户输入 0、负数(如 - 5、0),直接提示错误并退出程序,避免后续数组越界或逻辑错误;
return 1:区别于正常退出的return 0,明确标记程序因非法输入终止。
2. 数组初始化与数列生成
c
运行
// 初始化前两项
a[0] = 1;
if(n >= 2)
{
a[1] = 1;
}
// 生成后续项
for(i=2; i<n; i++)
{
a[i] = a[i-1] + a[i-2];
}
- 斐波那契数列前两项固定为 1,需单独初始化;
- 若用户仅输入 n=1,无需初始化 a [1],避免数组越界;
- 循环从 i=2 开始(第 3 项),通过
a[i] = a[i-1] + a[i-2]递推生成所有项。
3. 格式化输出:对齐 + 分行
c
运行
printf("%10d", a[i]); // 右对齐,占10个字符宽度
if((i+1) % 5 == 0) // 每输出5个数字换行(i从0开始,i+1为项数)
{
printf("\n");
}
// 最后一行不足5个时补换行
if(n % 5 != 0)
{
printf("\n");
}
%10d:数字右对齐,不足 10 位时左侧补空格,保证不同位数的数字(如 1、13、233)对齐,视觉整洁;(i+1)%5==0:i 从 0 开始,第 1 项是 i=0(i+1=1),第 5 项是 i=4(i+1=5),满足条件时换行;- 最后补充换行:若 n=7(输出 2 行,第 2 行仅 2 个数字),避免输出停在行尾,提升格式美观度。
四、原代码问题优化说明
对比原始代码中的注释版本,优化点如下:
- 冗余换行修复:原注释版将
if(n%5!=0)写在输出循环内,导致每输出一个数字都判断一次,产生大量多余换行,优化后移到循环外,仅判断一次; - 边界校验增强:原代码非法输入仅提示但不退出,仍会执行后续代码(如定义长度≤0 的数组),优化后直接
return 1终止; - 用户体验优化:输入提示、错误提示更清晰,输出格式统一(
%10d替代%6d,适配更大的斐波那契数); - 代码整洁度:删除冗余注释代码,逻辑分层更清晰(输入→校验→生成→输出)。
五、运行结果示例
示例 1:输入 n=8
plaintext
输入斐波那契数列项数:8
前8项斐波那契数列:
1 1 2 3 5
8 13 21
示例 2:输入 n=5
plaintext
输入斐波那契数列项数:5
前5项斐波那契数列:
1 1 2 3 5
示例 3:输入 n=-3(非法输入)
plaintext
输入斐波那契数列项数:-3
错误:必须输入正整数!
六、扩展优化思路
1. 适配 C89 标准(无变长数组)
C89 不支持int a[n],可改用固定大小数组或动态内存分配:
c
运行
// 动态内存分配(最大支持100项)
int max_n = 100;
int *a = (int*)malloc(max_n * sizeof(int));
if(a == NULL) // 内存分配失败校验
{
printf("内存分配失败!\n");
return 1;
}
// 使用完释放内存
free(a);
2. 避免数组存储(节省内存)
无需存储所有项,仅用两个变量递推:
c
运行
int prev1=1, prev2=1, curr;
printf("%10d%10d", prev1, prev2); // 输出前两项
for(i=2; i<n; i++)
{
curr = prev1 + prev2;
printf("%10d", curr);
if((i+1)%5==0) printf("\n");
// 更新前两项
prev1 = prev2;
prev2 = curr;
}
七、新手避坑指南
- 数组越界:n=1 时,若直接赋值
a[1]=1,会访问数组不存在的下标,必须加if(n>=2)判断; - 格式化换行错误:换行判断用
i+1而非i(i 从 0 开始,i+1 才是实际项数); - 变长数组兼容性:部分老旧编译器不支持
int a[n],需改用动态内存分配; - 输出格式混乱:小宽度(如
%6d)在斐波那契数变大后(如第 20 项 6765)会挤在一起,建议用%10d或%12d。