gpt4 book ai didi

c - 如何检查C中不同函数的调用顺序

转载 作者:行者123 更新时间:2023-11-30 14:47:01 24 4
gpt4 key购买 nike

为了将某个变量 (MyVariable) 设置为“TRUE”,我必须检查系统内是否遵循特定的函数调用顺序。例如,我在系统内有不同的功能:

uint8 myFunction1()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}

uint8 myFunction2()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}


uint8 myFunction3()
{
if (...)
{
return NOT_OK
}
else
{
return OK
}
}

MyVariable = TRUE 仅当:

  1. 确定== myFunction1

  2. 确定== myFunction2

  3. 确定== myFunction3

正是遵守了这个调用顺序。如何在不触及函数主体的情况下检查 C 中的调用顺序(例如设置一些标志等)?

我还是个初学者,正在尝试使用 C :)

谢谢!

最佳答案

这几乎肯定是一个“XY 问题”。也就是说,您认为保存调用顺序是解决实际问题的方法,但您的实际问题可能是确保首先不能以错误的顺序调用函数。

所以解决这个问题最正确的方法就是重新设计程序。有人提到状态机是一种解决方案。另一种解决方案可能类似于函数指针数组(这是状态机的常见实现)。

<小时/>

话虽如此,您可以做一些人为的事情来跟踪调用顺序,尽管我并不真正推荐它。示例:

#define CALL_ORDER_N 3

const char* call_order [CALL_ORDER_N] = {NULL};
size_t call_order_i = 0;


static void save_call (const char* func)
{
call_order[call_order_i] = func;
call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}
}

其中 call_order 将最后 3 个函数调用保存为指向字符串文字的指针。函数 save_call 通过将每个函数的 __func__ 常量传递给该数组来更新该数组。 __func__ 保证像 static const char[] 一样工作,因此这是安全的。你会做这样的事情:

void myFunction1 (void)
{
save_call(__func__);
...
}

void myFunction2 (void)
{
save_call(__func__);
...
}

void myFunction3 (void)
{
save_call(__func__);
...
}

然后检查调用以查看它们的顺序是否正确:

static bool is_call_order_ok (void)
{
const char* expected_order [CALL_ORDER_N] =
{
"myFunction1",
"myFunction2",
"myFunction3"
};

size_t co_i = call_order_i;

for(size_t i=0; i<CALL_ORDER_N; i++)
{
if(strcmp(call_order[co_i], expected_order[i])==0)
{
co_i++;
if(co_i == CALL_ORDER_N)
{
co_i = 0;
}
}
else
{
return false;
}
}

return true;
}

完整示例:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define CALL_ORDER_N 3

const char* call_order [CALL_ORDER_N] = {NULL};
size_t call_order_i = 0;


static void save_call (const char* func)
{
call_order[call_order_i] = func;
call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}
}

static bool is_call_order_ok (void)
{
const char* expected_order [CALL_ORDER_N] =
{
"myFunction1",
"myFunction2",
"myFunction3"
};

size_t co_i = call_order_i;

for(size_t i=0; i<CALL_ORDER_N; i++)
{
if(strcmp(call_order[co_i], expected_order[i])==0)
{
co_i++;
if(co_i == CALL_ORDER_N)
{
co_i = 0;
}
}
else
{
return false;
}
}

return true;
}


void myFunction1 (void)
{
save_call(__func__);
}


void myFunction2 (void)
{
save_call(__func__);
}


void myFunction3 (void)
{
save_call(__func__);
}



int main (void)
{
printf("Call 1,2,3: ");
myFunction1();
myFunction2();
myFunction3();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");

printf("Call 3,2,1: ");
myFunction3();
myFunction2();
myFunction1();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");

printf("Call 1,1,1: ");
myFunction1();
myFunction1();
myFunction1();
printf(is_call_order_ok() ? "Ok\n" : "Failed\n");

return 0;
}
<小时/>

上述的高级、更专业的版本是将一个迷你 API 与单个函数组合在一起,以便为每个变量提供私有(private)封装。函数 save_call 将是一个多用途函数,可用于注册预期的调用顺序、保存函数调用以及验证当前注册的顺序是否正确。

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define CALL_ORDER_N 3

static bool save_call (const char* func, bool verify)
{
bool result;

static const char* call_order [CALL_ORDER_N] = {NULL};
static size_t call_order_i = 0;
static const char* expected_order [CALL_ORDER_N] = {NULL};

size_t i = call_order_i;

if(verify) // special case, verify the order
{
for(size_t expected=0; expected<CALL_ORDER_N; expected++)
{
if(call_order[i] == expected_order[expected])
{
i++;
if(i == CALL_ORDER_N)
{
i = 0;
}
}
else
{
return false;
}
}
return true;
}

if(expected_order[i] == NULL) // register order of calls
{
expected_order[i] = func;
result = true;
}
else // save calls
{
call_order[i] = func;
result = false;
}

call_order_i++;
if(call_order_i == CALL_ORDER_N)
{
call_order_i = 0;
}

return result;
}


void myFunction1 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}


void myFunction2 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}


void myFunction3 (void)
{
if(save_call(__func__, false))
return ;
printf("Execute stuff in %s.\n", __func__);
}



int main (void)
{
/* register call order: */
myFunction1();
myFunction2();
myFunction3();


printf("Call 1,2,3:\n");
myFunction1();
myFunction2();
myFunction3();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");

printf("Call 3,2,1:\n");
myFunction3();
myFunction2();
myFunction1();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");

printf("Call 1,1,1:\n");
myFunction1();
myFunction1();
myFunction1();
printf(save_call(NULL, true) ? "Ok\n\n" : "Failed\n\n");

return 0;
}

save_call 当然应该正确放置在其自己的 .h/.c 文件对中。

关于c - 如何检查C中不同函数的调用顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51739429/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com