You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这段C语言代码能正确打印字符串?逻辑疑问求解

关于这段C语言代码的错误分析

首先明确:这段代码存在严重的数组越界问题,你测试时得到“正确”结果只是巧合,属于未定义行为,绝对不能这么写。下面逐个解释你的疑问:

1. 为什么scanf("%s", &flower[i][50])能“正常工作”?

  • char flower[7][50]是一个7行50列的二维字符数组,内存中是连续存储的:第0行从flower[0][0]到flower[0][49],紧接着是第1行flower[1][0]到flower[1][49],以此类推。
  • 正确的写法应该是scanf("%s", flower[i])或者scanf("%s", &flower[i][0]),这两个表达式等价,都是第i行的起始地址,用来存储第i+1个输入的花名(因为循环i从0开始)。
  • 而&flower[i][50]是第i行第50个元素的地址——注意每行只有50个元素,索引是0到49,所以这个地址其实就是第i+1行的起始地址。
  • 循环中i从0到6:
    • i=0时,写入flower[1]的位置;
    • i=1时,写入flower[2]的位置;
    • ...
    • i=5时,写入flower[6]的位置;
    • i=6时,&flower[6][50]已经超出了flower数组的内存范围(数组只有7行,索引0-6),属于越界写入,这是未定义行为——可能覆盖其他变量、导致程序崩溃,只是你的测试环境没触发而已。

2. 为什么printf用n而非n-1能得到正确结果?

这完全是前面越界写入导致的错位巧合:

  • 正常逻辑下,用户输入的n是“第n个花”,对应数组索引应该是n-1(因为数组从0开始)。
  • 但因为前面的scanf把第1个输入的花名写到了flower[1],第2个写到flower[2]……第6个写到flower[6],所以当你输入n=6时,访问flower[6]刚好是第6个输入的内容,看起来正确。
  • 如果输入n=1,访问flower[1]也会得到第1个输入的花名,但这都是错误代码带来的假象,一旦数组越界的内存被其他变量占用,程序立刻会出问题。

修正后的正确代码

char flower[7][50];
int i, n;
for (i = 0; i < 7; i++)
{
    printf("Enter the name of the flower number %d : ", i + 1);
    scanf("%s", flower[i]); // 或者&flower[i][0],两者等价
}
printf("\nEnter the number of the flower you want : ");
scanf("%d", &n);
// 这里要注意判断n的范围,避免越界访问
if (n >= 1 && n <=7)
    printf("Flower number %d is %s\n", n, flower[n-1]);
else
    printf("Invalid flower number!\n");

内容的提问来源于stack exchange,提问作者PhoenXHO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:17:02