看看下面一段程序的功能:
简单地说,我可以不用知道s_t_start和s_t_end之间具体定义了多少个变量,我都可以依次调用到。如果把这些实现代码用宏封装起来,那么整个代码就会看起来非常简洁明了。这有什么用呢?嗯……
以上代码在VC 6.0、Visual Studio.Net 2003、g++、gcc、BCB 6.0、TC 2.0上面测试通过。
/* TestRCUnit.cpp : 定义控制台应用程序的入口点。
*/
#include <stdio.h>
typedef void (*__CUNIT_TEST_CASE_FUNC_TYPE)();
/*! /brief 测试用例链表结点。
存储测试用例的函数指针和测试用例的名字。
*/
typedef struct __tagCUnitTestCaseListNode
{
struct __tagCUnitTestCaseListNode *next; /*!< 下一个测试用例 */
__CUNIT_TEST_CASE_FUNC_TYPE func; /*!< 测试函数的函数指针 */
char *name; /*!< 测试用例的名字 */
}__CUNIT_TEST_CASE_LIST_NODE_S;
/* hack code */
static void __CUnit_Func_Dummy_Test()
{
}
static __CUNIT_TEST_CASE_LIST_NODE_S s_t_start = {NULL, __CUnit_Func_Dummy_Test, NULL};
static void ta();
static __CUNIT_TEST_CASE_LIST_NODE_S s_ta = {NULL, ta, "ta"};
static void tb();
static __CUNIT_TEST_CASE_LIST_NODE_S s_tb = {NULL, tb, "tb"};
static void tc();
static __CUNIT_TEST_CASE_LIST_NODE_S s_tc = {NULL, tc, "tc"};
static void td();
static __CUNIT_TEST_CASE_LIST_NODE_S s_td = {NULL, td, "td"};
static __CUNIT_TEST_CASE_LIST_NODE_S s_t_end = {NULL, __CUnit_Func_Dummy_Test, NULL};
int main(int argc, char* argv[])
{
/* hack code */
long len = (long)((char *)(void *)&s_t_end - (char *)(void *)&s_t_start) / sizeof(__CUNIT_TEST_CASE_LIST_NODE_S);
long i;
__CUNIT_TEST_CASE_LIST_NODE_S *pCase = &s_t_start;
/* hack code */
printf("registed function count: %d/n", ((char *)(void *)&s_t_end - (char *)(void *)&s_t_start) / sizeof(__CUNIT_TEST_CASE_LIST_NODE_S));
/* 不需要知道这些变量的名字就可以调用函数ta、tb、tc、td */
for (i = 1; i < len; i++)
{
pCase[i].func();
}
return 0;
}
static void ta()
{
printf("Test ta/n");
}
static void tb()
{
printf("Test tb/n");
}
static void tc()
{
printf("Test tc/n");
}
static void td()
{
printf("Test td/n");
}
*/
#include <stdio.h>
typedef void (*__CUNIT_TEST_CASE_FUNC_TYPE)();
/*! /brief 测试用例链表结点。
存储测试用例的函数指针和测试用例的名字。
*/
typedef struct __tagCUnitTestCaseListNode
{
struct __tagCUnitTestCaseListNode *next; /*!< 下一个测试用例 */
__CUNIT_TEST_CASE_FUNC_TYPE func; /*!< 测试函数的函数指针 */
char *name; /*!< 测试用例的名字 */
}__CUNIT_TEST_CASE_LIST_NODE_S;
/* hack code */
static void __CUnit_Func_Dummy_Test()
{
}
static __CUNIT_TEST_CASE_LIST_NODE_S s_t_start = {NULL, __CUnit_Func_Dummy_Test, NULL};
static void ta();
static __CUNIT_TEST_CASE_LIST_NODE_S s_ta = {NULL, ta, "ta"};
static void tb();
static __CUNIT_TEST_CASE_LIST_NODE_S s_tb = {NULL, tb, "tb"};
static void tc();
static __CUNIT_TEST_CASE_LIST_NODE_S s_tc = {NULL, tc, "tc"};
static void td();
static __CUNIT_TEST_CASE_LIST_NODE_S s_td = {NULL, td, "td"};
static __CUNIT_TEST_CASE_LIST_NODE_S s_t_end = {NULL, __CUnit_Func_Dummy_Test, NULL};
int main(int argc, char* argv[])
{
/* hack code */
long len = (long)((char *)(void *)&s_t_end - (char *)(void *)&s_t_start) / sizeof(__CUNIT_TEST_CASE_LIST_NODE_S);
long i;
__CUNIT_TEST_CASE_LIST_NODE_S *pCase = &s_t_start;
/* hack code */
printf("registed function count: %d/n", ((char *)(void *)&s_t_end - (char *)(void *)&s_t_start) / sizeof(__CUNIT_TEST_CASE_LIST_NODE_S));
/* 不需要知道这些变量的名字就可以调用函数ta、tb、tc、td */
for (i = 1; i < len; i++)
{
pCase[i].func();
}
return 0;
}
static void ta()
{
printf("Test ta/n");
}
static void tb()
{
printf("Test tb/n");
}
static void tc()
{
printf("Test tc/n");
}
static void td()
{
printf("Test td/n");
}
简单地说,我可以不用知道s_t_start和s_t_end之间具体定义了多少个变量,我都可以依次调用到。如果把这些实现代码用宏封装起来,那么整个代码就会看起来非常简洁明了。这有什么用呢?嗯……

以上代码在VC 6.0、Visual Studio.Net 2003、g++、gcc、BCB 6.0、TC 2.0上面测试通过。