最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

静态如何在函数内部工作?

网站源码admin137浏览0评论
本文介绍了静态如何在函数内部工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

我遇到了一些我以前从未见过的东西.我有以下递归函数,仅当 i 是静态的

I came across something I haven't seen before. I have the following recursive function that only works when i is static

void printNthFromLast(Node* head, int n) {

    static int i = 0;

    if(head == nullptr)
        return;

    printNthFromLast(head->next, n);

    if(++i == n)
        cout << head->data;
}

我假设在这种情况下静态意味着在对同一函数的多个递归调用之间共享 printNthFromLast?

I assume static in this context means shared among multiple recursive calls to the same function printNthFromLast?

真正令人困惑的部分是它不会在每次递归函数调用自身时将其重新初始化为 0.好像这整行代码static int i = 0;被跳过了?

The real confusing part is that it doesn't reinitialize it to 0 every time the recursive function calls itself. It's like this whole line of code static int i = 0; is skipped?

有人可以向我解释一下吗?

Can someone explain this to me?

推荐答案

所以,如上所述,static int i = 0; 是函数的局部变量.它在 flow-control 第一次通过它的定义时被初始化,然后被跳过.做了两个特例:

So, as said, static int i = 0; is local to the function. It is initialized the first time flow-control passes through its definition, and skipped ever after. Two special cases are made:

如果动态初始化(通过函数)引发异常,则下次流控制通过定义时将重新尝试初始化.在来自多个线程的调用的情况下,第一个线程进行初始化,所有其他线程都被阻塞,直到完成(或因异常而失败)

现在,关于您的代码:不要.局部静态是变相的全局变量,你的代码相当于:

Now, regarding your code: don't. A local static is a global variable in disguise, your code is equivalent to:

int i = 0;

void printNthFromLast(Node* head, int n) {    
    if(head == nullptr)
        return;

    printNthFromLast(head->next, n);

    if(++i == n)
        cout << head->data;
}

注意:不仅调试更困难,而且不是线程安全的.

相反,您应该为此用途提供一个局部变量:

Instead, you should provide a local variable for this usage:

static void printNthFromLastImpl(Node const* const head, int& i, int const n) {
    if(head == nullptr)
        return;

    printNthFromLastImpl(head->next, i, n);

    if(++i == n)
        cout << head->data;
}

// Each call to this function instantiates a new `i` object.
void printNthFromLast(Node const* const head, int const n) {
    int i = 0;
    printNthFromLastImpl(head, i, n);
}

正如 Ad N 所述,因为列表未修改它应该通过 const 指针传递.

As remarked by Ad N, since the list is not modified it should be passed by const pointer.

在 Ad N 最新编辑(TCO 版本)之后,我意识到迭代实现应该有效(注意,可能会有一些错误).

Following Ad N latest edit (TCO version), I realized an iterative implementation should work (note, there might be some off by one errors).

void printNthFromLast(Node const* const head, int const n) {
    if (n == 0) { return; }

    // Set "probe" to point to the nth item.
    Node const* probe = head;
    for (int i = 0; i != n; ++i) {
        if (probe == nullptr) { return; }
        probe = probe->next;
    }

    Node const* current = head;

    // Move current and probe at the same rhythm;
    // when probe reaches the end, current is the nth from the end.
    while (probe) {
        current = current->next;
        probe = probe->next;
    }

    std::cout << current->data;
}

这篇关于静态如何在函数内部工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

发布评论

评论列表(0)

  1. 暂无评论