关于C程序输出的说明

时间:2017-12-12 11:17:44

标签: c recursion

        void HandleHighlightingPickedItem()
        {
            if (pickedItem)
            {
                if (highlightedCell)
                {
                    InventoryGrid grid = highlightedCell.grid;
                    InventoryCell[] cellsToHighlight = new InventoryCell[pickedItem.width * pickedItem.height];
                    InventoryItem firstItem = null;

                    bool valid = true;

                    int index = 0;
                    for (int x = 0; x < pickedItem.width; x++)
                    {
                        for (int y = 0; y < pickedItem.height; y++)
                        {
                            if (highlightedCell.x + x < grid.width && highlightedCell.y + y < grid.height)
                            {
                                InventoryCell cell = grid.cells[highlightedCell.x + x, highlightedCell.y + y];
                                cellsToHighlight[index] = cell;

                                if (highlightedItem)
                                {
                                    if (cell.heldItem != highlightedItem)
                                    {
                                        if (cell.heldItem)
                                        {
                                            valid = false;
                                        }
                                    }
                                }
                                else
                                {
                                    if (cell.heldItem)
                                    {
                                        if (!firstItem)
                                        {
                                            firstItem = cell.heldItem;
                                        }
                                        else
                                        {
                                            if (cell.heldItem != firstItem)
                                            {
                                                valid = false;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                valid = false;
                            }

                            index++;
                        }
                    }

                    for (int i = 0; i < cellsToHighlight.Length; i++)
                    {
                        if (cellsToHighlight[i])
                        {
                            if (valid)
                            {
                                cellsToHighlight[i].Highlight(EItemHighlightMode.VALID);
                            }
                            else
                            {
                                cellsToHighlight[i].Highlight(EItemHighlightMode.INVALID);
                            }
                        }
                    }
                }
            }
        }

我计算的输出是3 1 2 2 1 3 4

和书3 1 2 2 1 3 4 4 4

给出的输出

我知道为什么我的回答不同。

在book解决方案中,他们总是在“if”循环中执行printf语句。但是当我在我的书中研究if时,for和while循环是下一个语句,如果括号不存在。

if语句后调用true count并且不执行printf。但是为什么他们每次都在执行它。

3 个答案:

答案 0 :(得分:3)

如果您没有为ifforwhile语句添加括号,则只会执行下一行。改变之后:

if(n>1)
    count(n-1);
printf("%d", d);

要:

if(n>1){
    count(n-1);
    printf("%d", d);
}

您的输出将更接近您的预期:

gonczor@wiktor-papu:~/tmp$ gcc main.c -o main
gonczor@wiktor-papu:~/tmp$ ./main  31221344

答案 1 :(得分:1)

static d:1
count(n:3)
    print(n)         // 3
    print(d)         // 1
    ++d:2
    count(n:2)
        print(n)     // 2
        print(d)     // 2
        ++d:3
        count(n:1)
            print(n) // 1
            print(d) // 3
            ++d:4
            print(d) // 4
        print(d)     // 4
    print(d)         // 4

打印第一个4,因为if后卫停止了递归。当4的(递归)函数调用返回时,将打印第二个count(n:1)。当4的(递归)函数调用返回时,将打印第三个count(n:2)

我认为您的困惑在于您认为进行递归调用会导致调用者结束对其函数体的任何进一步处理。但事实并非如此,除非有return语句提前结束该功能。例如,如果递归调用受到如下保护:

if (n>1) {
    count(n-1);
    return;
}
print("%d", d);

然后,输出符合您的期望。只会打印一个4,因为if评估为false而执行的return。所有其他递归调用将在完成后执行4,因此不会出现其他if (n>1) count(n-1); printf("%d", d);

另请注意:

if (n>1) {
    count(n-1);
}
printf("%d", d);

d

是等价的。代码表示:if块完成后打印if。有两种方法可以完成。一种方法是if条件为假。另一种方式是当if条件为真时,执行递归调用,然后该调用返回。递归调用返回时,d块完成,然后打印d

进一步注意,虽然非常密切相关且计算上等效,但递归不能被视为普通的“循环”。递归调用意味着多个活动本地堆栈,而普通“循环”仅具有当前本地堆栈和循环执行块。因此,普通“循环”之后的打印语句将仅执行一次,这是在循环完成之后。但是,递归调用之后的代码将在递归调用返回后执行。因此,如果递归调用执行了2次,则需要完成三个活动的本地堆栈。在您的代码中,每个本地堆栈都希望在if块完成后打印from datetime import datetime try: datetime.strptime(DATE, '%Y-%m-%d %H:%M:%S') # or date_object = datetime.strptime(DATE, '%Y-%m-%d %H:%M:%S') # if you need the actual date object later except ValueError: pass # handle invalid date else: pass # handle valid date

答案 2 :(得分:0)

如果书的输出是&#39; 3 1 2 2 1 3 4 4 4&#39;

#include <stdio.h>

void count(int n) 
{ 
    static int d=1;
    printf("\nN IS: %d", n);
    printf("\nD IS: %d", d);
    d++;
    if(n>1) count(n-1);

    printf("\nFINAL D IS: %d", d);
}

int main()
{     
    count(3);
    return 0;
}

如果不改变这个:

    if(n>1)
    {       
        count(n-1); 
        printf("\nFINAL D IS: %d", d);
    }
相关问题