如何计算没有全局变量的函数调用次数?

How to count number of calls of function without a global variable?

我有一个C语言的作业:这段代码是给我们的,它的思想是统计一个函数被调用了多少次:

    #include <stdio.h>
int call_counter; //global
void fun()
{  call_counter++;}
void main()
{
 fun();  fun();   fun();
 printf("function \"fun\" was called %d times",call_counter);
}

然后他们问了我们以下问题:如果变量“call_counter”不是全局变量,您应该如何以及在何处声明它?

我尝试在main中声明为静态变量,但是即使调用该函数值也不会增加:

#include <stdio.h>

void fun()
{  call_counter++;}
void main()
{
static int call_counter = 0;
fun();  fun();   fun();
printf("function \"fun\" was called %d times",call_counter);
}

但是输出是0,不知如何调整代码解决这个问题 谢谢

另一种方法是从函数中 return 一个等于 1 的整数值。例如

#include <stdio.h>

int fun( void )
{
    //...
    return 1;
}

int main( void )
{
    size_t call_counter = 0;

    call_counter += fun();  call_counter += fun();   call_counter += fun();

    printf( "function \"fun\" was called %zu times.\n", call_counter );
}

或者您可以自己计算函数被调用了多少次

#include <stdio.h>

void fun( void )
{
    //...
}

int main( void )
{
    size_t call_counter = 0;

    ( ++call_counter, fun() );  ( ++call_counter, fun() ); ( ++call_counter, fun() );

    printf( "function \"fun\" was called %zu times.\n", call_counter );
}

这是一个演示程序

#include <stdio.h>

void fun( void )
{
    puts( "Hello World!" );
}

int main(void) 
{
    size_t call_counter = 0;

    ( ++call_counter, fun() );  
    ( ++call_counter, fun() ); 
    ( ++call_counter, fun() );

    printf( "function \"fun\" was called %zu times.\n", call_counter );
    
    return 0;
}

Hello World!
Hello World!
Hello World!
function "fun" was called 3 times.

或者您可以将函数调用包装在一个宏中,例如

#define FUN_CALL( n  )  ( ++n, fun() )

并像

一样使用它
FUN_CALL( call_counter );

您有四个选择:

  1. 使用全局变量。
  2. 将对计数器的引用传递给函数并在函数内部增加它。
  3. 在函数内部使用本地 static 计数器,每次 return 它。
  4. 在调用者中使用宏加局部变量。

对于选项 2,您可以这样做:

void foo(unsigned *count) {
    (*count)++;
    // do something
}

int main(void) {
    unsigned count = 0;
    foo(&count); foo(&count); foo(&count);
    // count is now 3
}

对于选项 3:

unsigned foo(void) {
    static unsigned count;
    count++;
    // do something
    return count;
}

int main(void) {
    unsigned count;
    foo(); foo(); 
    count = foo();
    // count is now 3
}

对于选项 4:

void foo(void) {
    // do something
}

int main(void) {
    unsigned count = 0;

#define FOO_COUNT() do { foo(); count++; } while (0)

    FOO_COUNT(); FOO_COUNT(); FOO_COUNT();
    // count is now 3
}

或者以不同的更通用的方式:

#define FN_COUNT(fn, counter) do { (fn)(); (counter)++; } while (0)

void foo(void) {
    // do something
}

int main(void) {
    unsigned count = 0;
    FN_COUNT(foo, count); FN_COUNT(foo, count); FN_COUNT(foo, count);
    // count is now 3
}

C没有任何全局变量; C 标准不对与标识符相关的任何内容使用“全局”。最接近的是与文件范围的外部链接,不同翻译单元中的标识符可能指的是同一个东西。

如果您使用 static 声明计数器,它将具有内部链接,因此它不会是全局的或外部的。如果你在任何函数之外和之前声明它,它从它的声明到翻译单元的末尾都是可见的:

#include <stdio.h>

static int call_counter;

void fun()
{
    call_counter++;
}

int main(void)
{
    fun();
    fun();
    fun();
    printf("The function \"fun\" was called %d times.\n", call_counter);
}

补充

不要用 void main() 声明 main。使用 int main(void)int main(int argc, char *argv[])(或由您的 C 实现定义的其他方式)。