zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    [转]JAVA程序执行顺序,你了解了吗:JAVA中执行顺序,JAVA中赋值顺序
    [转]浅谈Java中的equals和==
    [原创]java WEB学习笔记102:Spring学习---Spring Bean配置:bean配置方式(工厂方法(静态工厂方法 & 实例工厂方法)、FactoryBean) 全类名
    [原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器
    C# 数组之List<T>
    C# 数组之ArrayList
    C# 数组之int[]
    reverse-XNUCA-babyfuscator
    reverse-daily(1)-audio_visual_receiver_code
    Python多线程和多进程谁更快?
  • 原文地址:https://www.cnblogs.com/darkchii/p/9077285.html
Copyright © 2011-2022 走看看