C语言模版的使用 ##

文章目录

示例1

#define ADD(N)                                                   \
static void add_##N##_t(int##N##_t a,int##N##_t b,int##N##_t *c) \
{ *c=a+b;}

ADD(8)
ADD(16)
ADD(32)
int main(void)
{
    int16_t a,b,c=0;
    a=100;b=200;
    add_16_t(a,b,&c);
    printf("c=%d\n",c);
}

运行结果:c=300;可以尝试调用add_8_t(a,b,&c);

示例2

#define _Max(T) Max$_##T##_$
#define Max(T) _Max(T)

#define _Max_IMPL(T) 				\
	T Max(T)(T a, T b) 				\
	{ return a > b ? a : b; }

#define Max_IMPL(T) _Max_IMPL(T)

Max_IMPL(int);
Max_IMPL(char);
Max_IMPL(double);

int main(void) 
{
    printf("%d, %c, %lf\n", Max(int)(123, 456), Max(char)('a', 'z'), Max(double)(1.1, 2.2));
    return 0;
}

运行结果:456, z, 2.200000
有个$可以迷惑大家,其实不加也没影响

内容概要:本文介绍了ENVI Deep Learning V1.0的操作教程,重点讲解了如何利用ENVI软件进行深度学习模型的训练与应用,以实现遥感图像中特定目标(如集装箱)的自动提取。教程涵盖了从数据准备、标签图像创建、模型初始化与训练,到执行分类及结果优化的完整流程,并介绍了精度评价与通过ENVI Modeler实现一键化建模的方法。系统基于TensorFlow框架,采用ENVINet5(U-Net变体)架构,支持通过点、线、面ROI或分类图生成标签数据,适用于多/高光谱影像的单一类别特征提取。; 适合人群:具备遥感图像处理基础,熟悉ENVI软件操作,从事地理信息、测绘、环境监测等相关领域的技术人员或研究人员,尤其是希望将深度学习技术应用于遥感目标识别的初学者与实践者。; 使用场景及目标:①在遥感影像中自动识别和提取特定地物目标(如车辆、建筑、道路、集装箱等);②掌握ENVI环境下深度学习模型的训练流程与关键参数设置(如Patch Size、Epochs、Class Weight等);③通过模型调优与结果反馈提升分类精度,实现高效自动化信息提取。; 阅读建议:建议结合实际遥感项目边学边练,重点关注标签数据制作、模型参数配置与结果后处理环节,充分利用ENVI Modeler进行自动化建模与参数优化,同时注意软硬件环境(特别是NVIDIA GPU)的配置要求以保障训练效率。
<think>好的,我现在需要详细思考用户关于C语言##符号用法的问题。首先,用户明确询问##的用法,我需要结合提供的引用内容来整理答案。 根据引用[1],提到##是C语言中的一个重要内容,很多程序员可能不知道其隐藏用法。引用[4]中提到了##在可变参数宏中的使用,特别是在处理__VA_ARGS__时,结合,##可以删除多余的逗号。引用[2]和[3]主要讨论#运算符和字符串拼接,但可能相关,因为##也涉及预处理器的操作。 首先,##在C语言中是预处理器的运算符,用于宏定义中的标记连接(Token Pasting)。它可以将两个标记合并成一个。例如,在宏定义中,如果参数需要组合成变量名或类型,可以使用##来连接。 然后,考虑用户提供的示例,比如引用[4]中的例子,当使用可变参数宏时,,##__VA_ARGS__的作用是当__VA_ARGS__为空时,删除前面的逗号。这可以避免编译错误,尤其是在宏展开后参数为空的情况。 接下来需要分点说明##的用法: 1. 基本用法:连接两个标记。例如,定义宏#define CONCAT(a, b) a##b,则CONCAT(var, 123)会生成var123。 2. 在可变参数宏中的应用:使用, ## __VA_ARGS__来处理可变参数为空的情况,避免出现多余的逗号。例如引用[4]中的例子,当__VA_ARGS__为空时,前面的逗号会被删除。 3. 实际应用场景:如生成唯一的变量名,创建通用的宏模板,或者在日志输出宏中处理可变参数。 需要注意语法细节,比如##必须位于宏替换列表中,且操作的是预处理标记,不能用于字符串或字符常量的连接。同时,要区分#和##的不同,前者用于字符串化,后者用于标记连接。 需要验证提供的引用内容是否准确。例如引用[4]中提到的,##__VA_ARGS__是否符合C99标准,是的,这是GCC的扩展,后来被C99采纳。 最后,生成相关问题,可能涉及##的其他应用、与#的区别、实际案例或常见错误等。 确保回答结构清晰,步骤正确,并引用正确的来源。例如,关于,##__VA_ARGS__的部分引用[4],而基本用法引用[1]。</think>### C语言##符号的用法详解 在C语言预处理器中,**##** 被称为**标记连接运算符**(Token Pasting Operator),主要用于宏定义中将两个独立的标记(Token)合并为一个新标记。以下是其核心用法和实际应用场景: --- #### 一、基础用法:标记连接 **##** 可将宏参数与相邻字符直接拼接成新标识符。例如: ```c #define CONCAT(a, b) a##b int var123 = 10; printf("%d", CONCAT(var, 123)); // 输出 10 ``` 此处 `CONCAT(var, 123)` 展开为 `var123`,与定义的变量名匹配[^1]。 --- #### 二、可变参数宏中的高级应用 在支持可变参数的宏中,**##** 可解决参数为空导致的语法错误。例如: ```c #define LOG(fmt, ...) printf(fmt, ##__VA_ARGS__) LOG("Hello"); // 展开为 printf("Hello") LOG("Sum: %d", 5);// 展开为 printf("Sum: %d", 5) ``` 当 `__VA_ARGS__` 为空时,**##** 会删除前面的逗号,避免 `printf("Hello", )` 的语法错误[^4]。 --- #### 三、实际应用场景 1. **生成唯一标识符** 常用于创建结构体或函数名的动态拼接: ```c #define DECLARE_STRUCT(name) struct struct_##name DECLARE_STRUCT(point); // 展开为 struct struct_point ``` 2. **实现通用宏模板** 结合泛型编程,简化代码: ```c #define MAX(type) type max_##type(type a, type b) { return a > b ? a : b; } MAX(int) // 生成 int max_int(int a, int b) { ... } ``` --- #### 四、注意事项 - **操作对象必须是标记**:不能拼接字符串或字符常量,如 `"Hello"##"World"` 非法。 - **与#运算符的区别**:`#` 将参数转换为字符串(如 `#var` 变为 `"var"`),而 `##` 直接拼接标记[^3]。 - **兼容性**:`,##__VA_ARGS__` 是C99标准引入的特性,部分旧编译器可能不支持。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值