打印出由星号组成的字母 E - 我的程序可以运行,但我不明白为什么

Print out the letter E made of asterisks - My program works, but I don't understand why

我是一名初级程序员,正在学习 Java class。我们被分配编写一个程序,输出由星号组成的字母 E,5 向下和 3 横向如下:

*** 
* 
*** 
* 
*** 

唯一的要求是使用嵌套循环和 if 语句来得到我们的结果。下面是我的代码。它按预期工作,但我无法理解原因。

public class LetterE {
    public static void main(String args[]) {

        final int NUM_ACROSS = 3; 
        final int NUM_DOWN = 5;        
        int row; 
        int column; 

        for (row = 1; row <= NUM_DOWN; row++) {
            if (row == 1 || row == 3 || row == NUM_DOWN)
                for (column = 1; column <= NUM_ACROSS; column++) {
                    if (column == 1 || column == NUM_ACROSS)
                        System.out.print("*");
                }
            System.out.print("*");
            System.out.print(" ");
            System.out.println();
        }
        System.exit(0);
    }
}

基本上,我的问题与 System.out.print 语句有关。我不明白我的循环和打印语句之间的关系。例如,第一个 print 语句在花括号内,将其取出会导致输出不正确。最重要的是,我不明白第一个大括号之外的其他打印语句是做什么用的,以及为什么它们不能在大括号内。

任何指导将不胜感激。尽我最大的努力去理解它是如何工作的,但我已经坚持了一段时间了。

非常非常感谢!

试试下面的代码。我将内部循环打印替换为“#”只是为了让您了解它是如何工作的。内部循环是打印 3 行(顶部、中间和底部)所需的额外 *。外部 System.out 默认情况下我们需要在每一行中使用 * 并且 System.out.println 是移动到下一行。我移动了 {} 中的内部 for 循环以使其更具可读性。

public class LetterE {
    public static void main(String args[]) {

        final int NUM_ACROSS = 3; 
        final int NUM_DOWN = 5;        
        int row; 
        int column; 

        for (row = 1; row <= NUM_DOWN; row++) {
            if (row == 1 || row == 3 || row == NUM_DOWN){
                for (column = 1; column <= NUM_ACROSS; column++) {
                    if (column == 1 || column == NUM_ACROSS)
                        System.out.print("L");
                }
            }
            System.out.print("*");
            System.out.print(" ");
            System.out.println();
        }
        System.exit(0);
    }
}
public class LetterE {
    public static void main(String[] args) {     
        int row; 
        int column; 
        for (row = 1; row <= 5; row++) { //final int NUM_DOWN = 5
            if (row == 1 || row == 3 || row == 5) {
                for (column = 1; column <= 3; column++) {//final int NUM_ACROSS = 3
                    if (column == 1 || column == 3)
                        System.out.print("*");
                }               
            }
            System.out.print("*");
            System.out.print("\n");      
        }
        System.exit(0);
    }
}

看看我的代码。 我为 if 循环添加了另一个括号,以便于您使用。

以下代码打印 1 * 5 行。

for (row = 1; row <= 5; row++) {
    System.out.print("*");
    System.out.print("\n"); 
}

output: 
row1: 1  = *
row2: 1  = *
row3: 1  = *
row4: 1  = *   
row5: 1  = *

在这个 for 循环中还有另一个带有 if 条件的 for 循环

if (row == 1 || row == 3 || row == 5) {
    for (column = 1; column <= 3; column++) {//final int NUM_ACROSS = 3
        if (column == 1 || column == 3)
        System.out.print("*");
    }               
 }

此循环为行 1,3,5 打印另一个 2 * 因此,

* 总数
row1: 1 + 2 = ***
row2: 1     = *
row3: 1 + 2 = ***
row4: 1     = *
row5: 1 + 2 = ***

希望对您的理解有所帮助。

final int NUM_ACROSS = 3;
final int NUM_DOWN = 5;
int row;
int column;

我假设你知道上面的代码是做什么的,所以我不会详细说明。

for (row = 1; row <= NUM_DOWN; row++) {

这段代码的意思是要连续执行大括号内的代码只要row <= NUM_DOWN。但在此之前,我们将 1 赋值给 row(该语句只执行一次)。每次迭代(= 花括号内代码的完整执行)row++ 将被执行。

所以我们从 row == 1 开始,然后是 row == 2row == 3 ... 直到 row == 6,此时 row > NUM_DOWN,因为 NUM_DOWN == 5.

如果我们将我们为 row 获得的所有值放在一个列表中,该列表将等于 {1,2,3,4,5,6},其中包含 6 个值。但是,由于for循环在row == 6时退出,所以只有6 - 1 == 5次迭代。

继续:

if (row == 1 || row == 3 || row == NUM_DOWN){

基本上是指:如果row == 1 OR row == 3 OR row == 5,则执行大括号内的代码。否则,跳过它。

for (column = 1; column <= NUM_ACROSS; column++) {

与另一个 for 循环基本相同,只是变量不同。

if (column == 1 || column == NUM_ACROSS)

也与上面的 if 语句相同,但参数不同。

System.out.print("*");

这会将 * 字符一次打印到控制台 而没有 换行符(= 输入,基本上)。

在此之后执行的打印语句将追加另一个字符到已经写入的字符,因此在第一次迭代后您的输出将首先如下所示:

*

那么第三次之后是这样的(第二次,column等于2,所以column == 1 || column == NUM_ACROSS为false,所以里面的代码没有执行):

**

然后退出循环,执行另一个print语句。

***

A space 也被追加,但它不可见,因为......好吧,它是一个 space :P

println 函数本质上与 print 相同,但它还附加了 转义序列 \n。这个转义序列称为换行符,就像在键盘上按回车键:它开始一个新行。

下一次迭代,第一个 if 语句中的代码被完全跳过,所以我们直接跳到第二个 print 函数。现在我们的输出看起来像这样:

***
*

如果我们重复这个过程,我们将得到:

***
*
***

.

***
*
***
*

***
*
***
*
***

进入"optimizing"程序,因为这里其实有很多冗余代码:

int row; 
int column;

只需将它放在 for 语句中,如下所示:

for (int row = 1; row <= NUM_DOWN; row++) {

它更短,更易读;)

if (row == 1 || row == 3 || row == NUM_DOWN){

这个有点奇怪,因为一方面,声明 NUM_DOWN 可以更容易地更改高度,但另一方面,您必须编辑常量 13 手动然后任一方式。 让我们采用更具适应性的方式:

if (row == 1 || row == NUM_DOWN / 2 + 1 || row == NUM_DOWN) {

整数总是向下舍入,所以 5 / 2 == 2。当 NUM_DOWN 为偶数时,字母可能看起来有点奇怪,但无论如何。

for (int column = 1; column <= NUM_ACROSS; column++)
    if (column == 1 || column == NUM_ACROSS)

好吧,这只是一段奇怪的代码:我们最好从 column = 2 开始(2 因为我们将在下面打印另一个星号)并废弃 if 语句(循环将针对值 23 执行,因此总共 2 个元素 --> 2 个星号)。

System.out.print(" ");

既然看不懂,那我们干脆把它删掉吧

System.out.println("*");

同样,它更短,但几乎做同样的事情。

System.exit(0);

嗯...这不是真正需要的,因为您的程序 returns 无论如何默认为 0。

最终程序如下所示:

public class LetterE {

    public static void main(String args[]) {

        final int NUM_ACROSS = 3; 
        final int NUM_DOWN = 5;        

        for (int row = 1; row <= NUM_DOWN; row++) {
            if (row == 1 || row == NUM_DOWN / 2 + 1 || row == NUM_DOWN)
                for (int column = 2; column <= NUM_ACROSS; column++)
                    System.out.print("*");
            System.out.println("*");
        }
    }
}