if 语句之间的 for 循环在 C 中不起作用

for loop in between if statement is not working in C

提问人:MJ Saif 提问时间:11/15/2023 最后编辑:JabberwockyMJ Saif 更新时间:11/16/2023 访问量:113

问:

#include <stdio.h>

int main()
{
    int row, col, i, j;
    char ch;
    printf("Enter the Value of Row or Column: ");
    scanf("%d", &row);
    col = row;
    int mat[row][col];

    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            printf("enter the value(%d,%d): ", i, j);
            scanf("%d", &mat[i][j]);
        }
    }

    printf("Principle Diagonal is: [ ");
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            if (i == j)
            {
                printf("%d ", mat[i][j]);
            }
        }
    }
    printf("] \nGeneral Diagonal is: [ ");
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            if (i + j == row + 1)
            {
                printf("%d ", mat[i][j]);
            }
        }
    }
    printf("] \n Type 'u' or 'l' for Upper or Lower Triangular Matrix:");
    scanf("%c ", &ch);

    // upper or lower triangular matrix

    if (ch == 'u')
    {
        for (i = 1; i <= row; i++)
        {
            for (j = 1; j <= col; j++)
            {
                if (i != j && i > j)
                {
                    mat[i][j] = 0;
                }
            }
        }
    }
    else if (ch == 'l')
    {
        for (i = 1; i <= row; i++)
        {
            for (j = 1; j <= col; j++)
            {
                if (i != j && i < j)
                {
                    mat[i][j] = 0;
                }
            }
        }
    }

    // displaying the matrix
    for (i = 1; i <= row; i++)
    {
        for (j = 1; j <= col; j++)
        {
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    }

    return 0;
}

我试图从用户那里获得矩阵的输入。我从用户那里获取字符输入。

他会输入“u”或“l”......

如果输入为“u”,我将显示一个上部矩阵 如果输入为“l”,我将显示一个较低的矩阵

因此,在if else语句之间,我放置了for循环,但是这个for循环不起作用。

如果我从 if 语句中拖出 for 循环,它可以正常工作。

那么,问题出在哪里呢? 我该如何解决这个问题?

c for-loop if 语句 嵌套循环

评论

6赞 dbush 11/15/2023
数组索引从 0 开始。
1赞 yano 11/15/2023
<O/T>建议编写一些函数..发生了很多事情main
0赞 Gerhardh 11/15/2023
与您的问题无关,但您的情况过于复杂:如果为什么您也要检查?您已经知道,如果一个小于另一个,它们就不可能相同。此外,您的循环效率非常低下。如果你只在真的时候做某事,就没有必要有一个内部循环。只需使用 .只有在可能与您不同的位置时才需要额外的检查,但您为两者分配了相同的值。if (i != j && i < j)i < ji != jif (i == j)for (i = 1; i <= row; i++) { printf("%d ", mat[i][i]); }rowcol
0赞 Gerhardh 11/15/2023
同样在这个循环中,你这样做(应该是),你可以改变内部循环的条件,在得到等于或大于:之前停止。不要运行循环什么都不做。随着值的增加和不必要的嵌套循环,运行时将增加很多。if (i != j && i > j)if (i > j)jifor (j = 1; j < i; j++)
0赞 Ulrich Eckhardt 11/15/2023
请提供一个最小的可重复示例!这里的代码太多了,还需要手动交互,这可能(你需要验证!)不是实际问题的一部分。作为这里的新用户,也请浏览并阅读如何提问

答:

2赞 NoDakker 11/15/2023 #1

粗略地回顾一下你的代码,最突出的事情之一就是使用的数组索引范围。您可能想深入研究一些与数组相关的 C 编程教程,但首先要指出的是,初始数组元素是元素“0”,而不是“1”。

因此,在查看各种 for 循环时,您可能希望将起始数组元素从“1”更改为“0”并更改范围测试。以下是一些快速的重构。

for (i = 1; i <= row; i++)
{
    for (j = 1; j <= col; j++)

for (i = 0; i < row; i++)
{
    for (j = 0; j < col; j++)

在重构代码中的各种“for”循环时,以下是一些示例输出数据。

craig@Vera:~/C_Programs/Console/UpperLower/bin/Release$ ./UpperLower 
Enter the Value of Row or Column: 3
enter the value(0, 0): 1
enter the value(0, 1): 2
enter the value(0, 2): 3
enter the value(1, 0): 4
enter the value(1, 1): 5
enter the value(1, 2): 6
enter the value(2, 0): 7
enter the value(2, 1): 8
enter the value(2, 2): 9
Principle Diagonal is: [ 1 5 9 ] 
General Diagonal is: [ 9 ] 
 Type 'u' or 'l' for Upper or Lower Triangular Matrix:l
1 2 3 
4 5 6 
7 8 9 

这可能更接近您对输入和输出的期望。

因此,要带走的主要内容是:

  • 数组,无论是由字符、整数还是其他变量类型组成,都以元素“0”开头。
  • 通常,在计算大小为“x”的数组时使用“for”循环,常规语句为“for(int i = 0;我<x;x++){ . . . }

因此,请尝试一下,并深入研究一些好的教程文献。

评论

0赞 Chris 11/15/2023
还值得建议使用而不是用于数组的索引。size_tint
0赞 NoDakker 11/15/2023
我同意这个建议。
0赞 John Doe 11/15/2023
这都是很好的建议,但并没有回答主要 OP 的问题,这就是为什么由于错误的参数,for 循环在 if 条件内不运行。scanf
0赞 John Doe 11/15/2023 #2

你的代码有几个问题,首先在 C 数组中,不是从索引开始的,所以你需要将所有的循环从01for

for (i = 1; i <= row; i++)
{
    for (j = 1; j <= col; j++)
    {

for (i = 0; i < row; i++)
{
    for (j = 0; j < col; j++)
    {

您还需要删除 from 以避免超出数组的边界(with you have position so you can't to go until=<=row = 30,0 - 0,1 - 0,2 - 1,0 - 1,1 - 1,2 - 2,0 - 2,1 - 2,23)

更改此值意味着您获取一般对角线的检查需要变为

if (i + j == row - 1)

否则,将读取错误的数字row + 1

and 语句中的循环永远不会运行,因为您有if (ch == 'u')else

scanf("%c ", &ch);

在这种情况下,正确的语法是

scanf(" %c", &ch);

(注意空格 the 和 not ,请阅读题了解原因)before&cafter

总而言之,这是代码的固定版本(请注意,最好避免使用 scanf 并改用 E.G. fgetc。我只让你的代码在最少的重构下正常工作,使其更健壮取决于你)

#include <stdio.h>

int main()
{
    int row, col, i, j;
    char ch;
    printf("Enter the Value of Row or Column: ");
    scanf("%d", &row);
    col = row;
    int mat[row][col];

    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            printf("enter the value(%d,%d): ", i, j);
            scanf("%d", &mat[i][j]);
        }
    }

    printf("Principle Diagonal is: [ ");
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if (i == j)
            {
                printf("%d ", mat[i][j]);
            }
        }
    }
    printf("] \nGeneral Diagonal is: [ ");
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if (i + j == row-1)
            {
                printf("%d ", mat[i][j]);
            }
        }
    }
    printf("] \n Type 'u' or 'l' for Upper or Lower Triangular Matrix:");
    scanf(" %c", &ch);

    // upper or lower triangular matrix

    if (ch == 'u')
    {
        for (i = 0; i < row; i++)
        {
            for (j = 0; j < col; j++)
            {
                if (i != j && i > j)
                {
                    mat[i][j] = 0;
                }
            }
        }
    }
    else if (ch == 'l')
    {
        for (i = 0; i < row; i++)
        {
            for (j = 0; j < col; j++)
            {
                if (i != j && i < j)
                {
                    mat[i][j] = 0;
                }
            }
        }
    }

    // displaying the matrix
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            printf("%d ", mat[i][j]);
        }
        printf("\n");
    }

    return 0;
}
1赞 John Bode 11/15/2023 #3

您的问题(嗯,您的问题之一)是这一行:

scanf("%c ", &ch);

与 、 、 等不同,它不会跳过任何前导空格(空格、制表符、换行符等),这里发生的事情是从上一个条目中获取换行符 () 并将其分配给 。%d%s%f%cscanf'\n'ch

由于不等于 either 或 ,因此不取任何分支。您需要一个分支来处理意外的输入:'\n''u''l'else

if ( ch == 'u' )
  // print upper half
else if ( ch == 'l' )
  // print lower half
else
  // print error message

或者您需要设置“默认”大小写之一,例如'u''l'

if ( ch == 'u' )
  // print upper half
else
  // print lower half

这意味着,这将为任何不是 .'u'

格式字符串的另一个问题是尾随空白; 在输入一个字符,后跟空格,后跟一个非空格字符之前,不会返回。给定代码"%c "scanf

if ( scanf( "%c ", &ch ) == 1 ) 
  printf( "'%c'\n", ch );

你会得到以下行为:

$ ./scantest
g





v
'g'

我可以在那之后输入一堆空格或换行符;直到我输入(或其他一些非空格字符),才继续阅读。gvscanf

您可以通过在说明符放置一个空格来解决此问题:scanf%c

scanf( " %c", &ch );

这将告诉跳过任何前导空格并将下一个空格字符读入 .您还应该检查 的返回值,以查看读取是否成功。 将返回已成功转换和分配或错误时的项目数。因此,您应该将代码结构为scanfchscanfscanfEOF

if ( scanf( " %c", &ch ) == 1 ) // expecting 1 input
{
  if ( ch == 'u' )
    // print upper half
  else if ( ch == 'l' )
    // print lower half
  else
    // print error message
}
else
{
  // handle input error
}

或者,您可以使用 or 读取下一个字符,但您必须自己处理跳过前导空格的问题:getcharfgetc

int ch; // needs to be int if you're going to use getchar

do
{
  ch = getchar();
} while ( isspace( ch ) );

这将继续读取下一个字符,直到您获得非空格字符或 .如果你走这条路线,则需要声明为 ,而不是 ,因为返回并且不适合 .EOFchintchargetcharintEOFchar

您仍需要处理该 EOF:

if ( ch != EOF )
{
  if ( ch == 'u' )
    ...
  else if ( ch == 'l' )
    ...
  else
    ...
}
else
{
  // input error
}

所以,这是你的问题之一。另一个问题是 C 中的数组从 0 开始索引,因此 N 元素数组的索引从 0 到 N-1。您需要将循环更改为

for ( i = 0; i < row; i++ )
{
  for ( j = 0; j < col; j++ )
  {
    // do something with arr[i][j]
  }
}

一些文体说明:

  • 条件和是多余的;这些可以简单地重写为 和 。i != j && i > ji != j && i < ji > ji < j

  • 您不需要嵌套循环来打印对角线;你可以这样做

    for ( size_t i = 0; i < row; i++ )
      printf( "%d ", mat[i][i] );