13
#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;
}

在这种情况下,输出将是

我被叫了1次!
我被叫了1次!
我被叫了1次!
我被叫了1次!

相反,我希望输出打印为

我被叫了1次!
我被叫了2次!
我被叫了3次!
我被叫了4次!
4

9 回答 9

41

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

#include<iostream.h>

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

int main()
{
    callMe();
    callMe();
    callMe();
    callMe();
    return 0;
}

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

于 2012-11-26T10:15:49.987 回答
24
void callMe()
{
    static int count = 0; // note 'static' keyword
    cout<<"I am called "<<++count<<" times!\n";
}
于 2012-11-26T10:15:50.207 回答
11

做一个静态变量

因此在函数本身中定义它,并且由于 static 的属性,它将在每次调用中保留它的值。

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

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

但是count您声明的是本地的并且在堆栈上存储,因此对于每个函数调用它总是需要count = 0

于 2012-11-26T10:17:18.133 回答
11

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

1) 将变量声明为静态:

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

这是有效的,因为内存现在创建了一个 count 副本,而不是每次调用函数时都创建一个,然后在函数完成时将其删除。这里还值得注意的是 count 仍然是函数的本地,即如果您尝试执行以下操作:

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

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

2)初始化一个全局变量:

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

在上面的示例中,变量具有全局范围,因此整个程序使用变量的单个副本,因此在某处所做的更改将反映在程序中的任何位置。如果您需要监控 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;
}

由于这里的 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;
}

这可能是最干净的方法,变量是 main 的本地变量(这将节省垃圾收集的复杂性),并且由于这是通过引用传递,所以所做的所有更改都指向内存中的同一位置。如果你没有充分的理由不遵循这个,我会说使用这个。

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

于 2012-11-26T12:14:33.427 回答
6

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

int count = 0;
auto callMe = [=] mutable {
    cout<<"I am called "<<++count<<" times!\n";
};
于 2012-11-26T10:37:42.547 回答
5

如果您想计算单个函数的调用次数,您确实可以使用staticcounter 变量。


或者,如果您想出于调试目的执行此操作,则为此使用分析工具并不是最糟糕的主意。例如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";
}

这是我机器上的输出:

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.
于 2012-11-26T14:42:25.980 回答
3

您必须在计数之前使用“静态”关键字。

修正后的代码片段将是这样的: *

void callMe()
{
    static int count;
    cout<<"I am called "<<++count<<" times!\n";
}
于 2012-11-26T10:19:24.267 回答
2

您可以通过引用传递变量计数,并在每次调用函数时增加它,如下所示:

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

int main()
  {
    int count=0;
  callMe(count);
  callMe(count);
  callMe(count);
  callMe(count);
  return 0;
  }

有关按引用传递的更多信息,您可以参考此处

于 2012-11-26T10:44:50.337 回答
1

基本上这里的每个人都建议。这是我不时使用的宏。我发现它使阅读更容易。

in a separate header: (say debug_helper.h)
---------------------
#define COUNT_USAGE() {static int count=0;++count;std::cout<<"Called "<<count<<" times\n";}

In the CPP file:
----------------
#include "debug_helper.h"    

void callMe()
{
    COUNT_USAGE();
}
于 2012-12-10T04:01:56.687 回答