C — 小知识

  老是记错int与void*之间的转换,所以记录一个,顺便用一下一些宏、预处理。。。

  int与void*的转换、打印变量名:

#include <stdio.h>
// 打印变量名
#define VNAME(name) (#name)

typedef void*(*func)(void*);

void call(func myfunc, void*var)
{
	(*myfunc)(var);
}

void*myfunc(void*var)
{
	printf("变量%s=%d
", VNAME(var), *(int*)var);
}

int main(int argc, char** argv)
{
	int i = 0;

	call(myfunc, (void*)&i);
	return 0;
}

  还可以这样调用回调函数:

#include <stdio.h>

static void*(*func)(void*); // or no static, but can not is 'extern'

void*myfunc(void*var)
{
	printf("Output:%d
", *(int*)var);
}

int main(int argc, char** argv)
{
	int n = 5;
	func = myfunc((void*)&n);
	return 0;
}

  跨编译器的一些宏与预处理方式(在RapidJson看到的):

...
#ifndef RAPIDJSON_UNLIKELY
#if defined(__GNUC__) || defined(__clang__)
#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define RAPIDJSON_UNLIKELY(x) (x)
#endif
#endif
...

  C/C++的预处理:

#ifdefined(__cplusplus) || defined(c_plusplus)
extern "C"{
#endif
// ...
#ifdefined(__cplusplus) || defined(c_plusplus)
}
#endif

  跨平台的预处理(参考):

#if defined(WIN32) && !defined(UNIX)
/* Do windows stuff */
#elif defined(UNIX) && !defined(WIN32)
/* Do linux stuff */
#else
/* Error, both can't be defined or undefined same time */
#endif

  可变长参数(参考该文章):

#include <stdio.h>
#include <stdarg.h> /* __VA_ARGS__ */

#define DISPLAY(params, ...) printf(params, __VA_ARGS__) // c99

int main(int argc, char** argv)
{
	int start = 0;
	int end = 100;

	DISPLAY("%d - %d
", start, end);
	return 0;
}

  __VA__ARGS__只能用宏展开的方式使用,想要自己实现一个可变长参数的方法可以这样(参考《Linux网络编程》第十四章):

#include <stdio.h>
#include <stdarg.h> /* *va* */

#define DISPLAY(params, ...) printf(params, __VA_ARGS__)

int print(const char*sp, ...)
{
	char*buf;
	va_list args;
	
	va_start(args, sp);
	int args_nums = vsprintf(buf, sp, args);
	va_end(args);

	puts(buf);
	
	return args_nums;
}

int main(int argc, char** argv)
{
	int start = 5, end = 10;

	printf("%s:%s
", __FILE__, argv[0]);


	DISPLAY("In %s:%d:
%d,%d
", __func__, __LINE__, start, end);
	print("In %s:%d:
%d,%d
", __func__, __LINE__, start, end);
	return 0;
}

  Output:

test.c:./test
In main:39:
5,10
In main:41:
5,10

  其他参考:

    1.打印变量名:https://blog.csdn.net/sfwork/article/details/7866463

    2.一些宏的巧用:https://www.zhihu.com/question/40325914?sort=created

    3.http://bbs.chinaunix.net/thread-1293908-1-1.html

    4.https://blog.csdn.net/u012252959/article/details/53761360

    5.预处理:https://docs.microsoft.com/zh-cn/cpp/preprocessor/hash-if-hash-elif-hash-else-and-hash-endif-directives-c-cpp

原文地址:https://www.cnblogs.com/darkchii/p/9077285.html