如何获得在C++中执行函数的确切次数?

12 c++

#include<iostream>
using namespace std;

void callMe()
{
    int count=0;
    cout<<"I am called "<<++count<<" times!\n";
}

int main()
{
    callMe();
    callMe();
    callMe();
    callMe();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,输出将是

I am called 1 times!
I am called 1 times!
I am called 1 times!
I am called 1 times!

相反,我希望输出打印为

I am called 1 times!
I am called 2 times!
I am called 3 times!
I am called 4 times!

Pra*_*nny 39

我希望以下代码段能解决您的问题!

#include<iostream.h>

void callMe()
{
    static int count=0;
    cout << "I am called " << ++count << " times!\n";
}

int main()
{
    callMe();
    callMe();
    callMe();
    callMe();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里静态变量将保留其值,并且每次都会打印递增的计数!

  • @Praveen Vinny仍然是初始化它的好主意.在大多数情况下,显式优于隐式(特别是如果以后某个时候不止一个人会阅读该代码)并且应该鼓励养成良好的习惯. (16认同)
  • 它不是全局的,只在`callMe()`中可见. (13认同)
  • 虽然我认为最好的做法是显式初始化静态var,但根据这个SO问题,C++规范说静态变量将被设置为零,如果你不自己做的话http://stackoverflow.com/questions/ 1294772 /不-GCC-自动初始化静态变量到零 (8认同)
  • 那是因为_initialization_只设置了_initial_值.如果您想要一个不同的_initial_值为零怎么办? (7认同)
  • 因为它是一个静态变量,所以不需要初始化计数. (3认同)
  • *"没有必要初始化计数,因为它是一个静态变量."*错误......没有必要,因为你对默认值为0感到满意.如果你想,比如,用静态变量倒数那么你*会*需要初始化它. (3认同)
  • 不应该"数"被初始化? (2认同)

Die*_*Epp 24

void callMe()
{
    static int count = 0; // note 'static' keyword
    cout<<"I am called "<<++count<<" times!\n";
}
Run Code Online (Sandbox Code Playgroud)


Omk*_*ant 11

制作一个静态变量

所以在函数本身中定义它,并且由于静态属性,它将在每次调用中保留它的值.

void callMe()
{
    static int count=0;
    cout<<"I am called "<<++count<<" times!\n";
}
Run Code Online (Sandbox Code Playgroud)

静态存储是在数据分段中完成的,它不在函数堆栈上,因此在每个调用函数中都将采用它的修改值.因此它将打印您想要的结果.

但是count你声明的是本地的并且在堆栈上有存储空间,所以对于它总是需要的每个函数调用count = 0


Ind*_*oob 11

实际上有3种方式,其中2种已经在这里提到了.我会总结一下原因:

1)将变量声明为Static:

void callMe()
{
    static int count=0;
    cout<<"I am called "<<++count<<" times!\n";
}
Run Code Online (Sandbox Code Playgroud)

这是因为内存现在创建一个count的副本,而不是每次调用函数时创建一个,然后在函数完成时删除它.另外值得注意的是,count仍然是函数的Local,即如果你尝试做这样的事情:

int main()
{
    int count;
    callMe();
    callMe();
    callMe();
    callMe();
    cout<<"you called "<<count<<"functions!\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

count仍将显示垃圾值,因为您的函数计数和主计数是2个不同位置的2个不同变量.

2)初始化全局变量:

int count=0; 
void callMe()
{
    cout<<"I am called "<<++count<<" times!\n";
}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,变量具有全局范围,因此整个程序使用变量的单个副本,因此在某处进行的更改将反映在程序中的任何位置.如果需要监控2个以上的功能,可以使用此方法.例如:

int count=0;
void callMe()
{
    cout<<"I am called "<<++count<<" times!\n";
}

void callMe2()
{
    cout<<"I am called 2 "<<++count<<" times!\n";
}

int main()
{
    callMe();
    callMe();
    callMe2();
    callMe2();
    cout<<"you called "<<count<<" functions!\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

由于这里的count对函数和main都基本相同,因此它们都引用相同的值而不是制作自己的本地副本.如果您有相同名称的变量,可能会搞砸.要了解全局变量和静态变量之间的差异及其范围,请单击此处

3)传递变量的引用:

void callMe(int &count)
{
   cout<<"I am called "<<count++<<" times!\n";
}

void callMe2(int &count)
{
   cout<<"I am called 2 "<<++count<<" times!\n";
}

int main()
{
    int count=0;
    callMe(count);
    callMe(count);
    callMe2(count);
    callMe2(count);
    cout<<"you called "<<count<<" functions!\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这可能是最干净的方法,变量是main的本地变量(这可以节省垃圾收集的复杂性),因为这是一个refrence传递,所有更改都指向内存中的相同位置.如果你没有坚定的理由不遵循这个,我会说使用它.

希望我没有进一步混淆你,快乐狩猎.


Pup*_*ppy 5

您必须将其作为参数传递或将其存储为函数状态.

int count = 0;
auto callMe = [=] mutable {
    cout<<"I am called "<<++count<<" times!\n";
};
Run Code Online (Sandbox Code Playgroud)


moo*_*eep 5

如果要计算单个函数的调用次数,您确实可以使用static计数器变量.


或者,如果您想为调试目的而这样做,那么为此使用分析工具并不是最糟糕的想法.例如Valgrind的Callgrind [强调我的]:

Callgrind是一个分析工具,它记录程序作为调用图运行的函数之间的调用历史记录.默认情况下,收集的数据包括执行的指令数,它们与源行的关系,函数之间的调用者/被调用者关系以及此类调用的数量.


当你使用gcc时,你也可以修改__PRETTY_FUNCTION__宏和全局地图:

#include <iostream>
#include <string>
#include <map>

std::map<std::string, int> call_counts;

void call_me_one() {
    call_counts[__PRETTY_FUNCTION__] += 1;
}

void call_me_two() {
    call_counts[__PRETTY_FUNCTION__] += 1;
}

void call_me_three() {
    call_counts[__PRETTY_FUNCTION__] += 1;
}

int main()
{
    for (int i = 0; i < 10; i++) 
        call_me_one();

    for (int i = 0; i < 20; i++) 
        call_me_two();

    for (int i = 0; i < 30; i++) 
        call_me_three();

    for (auto it = call_counts.begin(); it != call_counts.end(); ++it)
        std::cout << (*it).first << " was being called " 
            << (*it).second << " times.\n";
}
Run Code Online (Sandbox Code Playgroud)

这是我机器上的输出:

void call_me_one() was being called 10 times.
void call_me_three() was being called 30 times.
void call_me_two() was being called 20 times.
Run Code Online (Sandbox Code Playgroud)