鱼C论坛

 找回密码
 立即注册
查看: 1569|回复: 12

[已解决]C语言 41课的视频疑惑

[复制链接]
发表于 2018-7-24 16:08:08 | 显示全部楼层 |阅读模式
10鱼币
请问下面##是不是多余的,##前面有‘,’,没有代码连,如果是和逗号前面的printf,好像语法就不对。
最佳答案
2018-7-24 16:08:09
本帖最后由 TyCk 于 2018-7-24 18:48 编辑

我查了下,在这里,##是用来去除前面那个逗号的。
标准C里面,没有可变参数的时候,输入PRINT(HELL)是非法的,因为没有逗号。有些编译器会自动忽略,但又会多出个逗号。
而使用##以后,如果可变参数被忽略或为空,’##’操作将使预处理器去除掉它前面的那个逗号。
如果你在宏调用时,确实提供了可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。

我前面说的那行代码也没法执行成功,主要就是##在这里不是连接参数的,printf函数本身也没法识别。
你可以试一下,把##删除以后,PRINT(HELL)就报错了。反正CodeBlocks我测试是这样,不同编译器可能有所差别,楼主可以实际测试下。
不好意思哈,前面误导你了,当初看视频的时候就以为是连接参数呢,好啦,这次又弄懂一个小知识点

最佳答案

查看完整内容

我查了下,在这里,##是用来去除前面那个逗号的。 标准C里面,没有可变参数的时候,输入PRINT(HELL)是非法的,因为没有逗号。有些编译器会自动忽略,但又会多出个逗号。 而使用##以后,如果可变参数被忽略或为空,’##’操作将使预处理器去除掉它前面的那个逗号。 如果你在宏调用时,确实提供了可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。 我前面说的那行代码也没法执行成功,主要就是##在这里不是 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-24 16:08:09 | 显示全部楼层    本楼为最佳答案   
本帖最后由 TyCk 于 2018-7-24 18:48 编辑

我查了下,在这里,##是用来去除前面那个逗号的。
标准C里面,没有可变参数的时候,输入PRINT(HELL)是非法的,因为没有逗号。有些编译器会自动忽略,但又会多出个逗号。
而使用##以后,如果可变参数被忽略或为空,’##’操作将使预处理器去除掉它前面的那个逗号。
如果你在宏调用时,确实提供了可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。

我前面说的那行代码也没法执行成功,主要就是##在这里不是连接参数的,printf函数本身也没法识别。
你可以试一下,把##删除以后,PRINT(HELL)就报错了。反正CodeBlocks我测试是这样,不同编译器可能有所差别,楼主可以实际测试下。
不好意思哈,前面误导你了,当初看视频的时候就以为是连接参数呢,好啦,这次又弄懂一个小知识点
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 16:08:38 | 显示全部楼层
这是截图
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-24 16:13:22 | 显示全部楼层
##你知道是啥意思吧?
这里呢,ARGS是不确定个数的参数,就是说你可以输入1个,可以不输入,还可以输入10个。
当输入的多于1个时,##就起作用了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 16:55:53 | 显示全部楼层
本帖最后由 wow7jiao 于 2018-7-24 17:01 编辑

这是课件##的定义 ,例子是2个参数一个前一个后把##夹在中间。
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 16:59:23 | 显示全部楼层
TyCk 发表于 2018-7-24 16:13
##你知道是啥意思吧?
这里呢,ARGS是不确定个数的参数,就是说你可以输入1个,可以不输入,还可以输入10 ...

我把#define PRINT(format, ...) printf(# format, __VA_ARGS__)写成这样,去掉##也是也是正常的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 17:03:32 | 显示全部楼层
这是截图
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-24 17:05:52 | 显示全部楼层
本帖最后由 TyCk 于 2018-7-24 17:30 编辑
wow7jiao 发表于 2018-7-24 16:59
我把#define PRINT(format, ...) printf(# format, __VA_ARGS__)写成这样,去掉##也是也是正常的


我已经说了啊,PRINT(HELL)这条语句只给出了第一个参数,后面的参数没有给出啊,所以##根本就没用到,自然去掉也正常。
你试一下下面这行代码:
  1. PRINT(HELL,HI,WORLD,OK)
复制代码

有没有##就不一样了。
——————————————————————————————————————————————————
好吧,这行代码会报错的,因为printf函数调用错误,HI、WORLD、OK都没有定义。
  1. PRINT(HELL,"HI","WORLD","OK");
复制代码

这样就能执行了,但是还是没达到想要的结果,原因就在于##是连接前面的逗号的,与后面无关。
具体在下面楼解释了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 17:06:14 | 显示全部楼层
#include <stdio.h>

#define PRINT(format, ...) printf(# format, ## __VA_ARGS__)

int main(void)
{
        PRINT(num = %d\n, 520,1314);,<---我在多加一个参数也没有链接起来。
        PRINT(Hello FishC!\n);

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-24 17:13:07 | 显示全部楼层
wow7jiao 发表于 2018-7-24 17:06
#include

#define PRINT(format, ...) printf(# format, ## __VA_ARGS__)

稍等哈,我测试下,好像有点问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 17:20:45 | 显示全部楼层
TyCk 发表于 2018-7-24 17:05
我已经说了啊,PRINT(HELL)这条语句只给出了第一个参数,后面的参数没有给出啊,所以##根本就没用到,自 ...

改了直接报错
#include <stdio.h>

#define PRINT(format, ...) printf(# format, ## __VA_ARGS__)

int main(void)
{
        PRINT(HI, HI, WORLD, OK);
        PRINT(Hello FishC!\n);

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-7-24 17:44:13 | 显示全部楼层
课件是说用##连在一起
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-7-24 17:48:43 | 显示全部楼层
wow7jiao 发表于 2018-7-24 17:44
课件是说用##连在一起

实践出真知嘛,多查查知识,相互对照下,谁能百分百对呢?是吧……
不过,你可以@下小甲鱼大佬啊,跟他探讨下,看看到底怎么回事,善于发现问题的好孩子(大概就是视频里说的有些皮的吧),哈哈,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-18 12:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表