标签: stringification

这个C代码如何工作?

什么是a##b&#a

  #define f(a,b) a##b
  #define g(a)   #a
  #define h(a) g(a)

  main()
  {
          printf("%s\n",h(f(1,2)));  //how should I interpret this?? [line 1]
          printf("%s\n",g(f(1,2)));  //and this? [line 2]
  }
Run Code Online (Sandbox Code Playgroud)

这个程序如何运作?


输出是

12
f(1, 2)
Run Code Online (Sandbox Code Playgroud)

现在我明白了如何a##b#a工作.但为什么两种情况(第1行和第2行)的结果不同?

c stringification c-preprocessor

6
推荐指数
2
解决办法
3986
查看次数

试图理解C预处理器

为什么这些代码块产生不同的结果?

一些常用代码:

#define PART1PART2 works
#define STRINGAFY0(s) #s
#define STRINGAFY1(s) STRINGAFY0(s)
Run Code Online (Sandbox Code Playgroud)

情况1:

#define GLUE(a,b,c) a##b##c  
STRINGAFY1(GLUE(PART1,PART2,*))
//yields
"PART1PART2*"
Run Code Online (Sandbox Code Playgroud)

案例2:

#define GLUE(a,b) a##b##*
STRINGAFY1(GLUE(PART1,PART2))
//yields
"works*"
Run Code Online (Sandbox Code Playgroud)

案例3:

#define GLUE(a,b) a##b
STRINGAFY1(GLUE(PART1,PART2*))
//yields
"PART1PART2*"
Run Code Online (Sandbox Code Playgroud)

我正在使用VS.net 2005 sp1中的MSVC++

编辑:目前我认为预处理器在扩展宏时的工作方式如下:步骤1: - 取出正文 - 删除##运算符周围的任何空格 - 解析字符串,如果找到的标识符与名称匹配一个参数: - 如果它在##运算符旁边,用参数的文字值(即传入的字符串)替换标识符 - 如果它不在##运算符旁边,则运行整个解释过程首先是参数的值,然后用该结果替换标识符.(忽略stringafy单个'#'case atm) - 删除所有##运算符

第2步: - 获取结果字符串并解析任何宏

现在,我认为所有3个案例都应该产生完全相同的结果字符串:

PART1PART2*

因此,在第2步之后,应该导致

作品*

但至少应该导致同样的事情.

c c++ stringification c-preprocessor

6
推荐指数
1
解决办法
463
查看次数

令牌贴在C中

看完VA_NARG后

我尝试使用宏根据C中的参数数量实现函数重载.现在的问题是:

void hello1(char *s) { ... }
void hello2(char *s, char *t) { ... }
// PP_NARG(...)           macro returns number of arguments :ref to link above
 // does not work
#define hello(...)         hello ## PP_NARG(__VA_ARGS__)  

int main(void)
{
   hello("hi");   // call hello1("hi");
   hello("foo","bar"); // call hello2("foo","bar");
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我从C-faq那里读到了这个.但仍然无法让它工作......

c c99 stringification c-preprocessor variadic-macros

6
推荐指数
1
解决办法
1773
查看次数

如何使用cpp将宏转换为字符串?

GNU的cpp允许您将宏参数转换为字符串

#define STR(x) #x
Run Code Online (Sandbox Code Playgroud)

然后,STR(hi)被替换为"hi"

但是,如何将宏(不是宏参数)转换为字符串?

假设我有一个具有某些值的宏CONSTANT,例如

#define CONSTANT 42
Run Code Online (Sandbox Code Playgroud)

这不起作用:STR(CONSTANT).这产生"CONSTANT"的不是我们想要的.

c++ string constants stringification

6
推荐指数
2
解决办法
1187
查看次数

如何将修饰符添加到带引号的常规(qr)表达式中

有没有一种简单的方法可以将正则表达式修饰符(如"i")添加到引用的正则表达式中?例如:

$pat = qr/F(o+)B(a+)r/;
$newpat = $pat . 'i'; # This doesn't work
Run Code Online (Sandbox Code Playgroud)

我能想到的唯一方法就是print "$pat\n"回过头来(?-xism:F(o+)B(a+)r)尝试?-xism:用替换去除'i'

regex perl modifier stringification qr-operator

6
推荐指数
1
解决办法
677
查看次数

Any.match有什么作用?

它有一个欺骗性的简单代码:

 method match(Any:U: |) { self.Str; nqp::getlexcaller('$/') = Nil }
Run Code Online (Sandbox Code Playgroud)

但是,这是它的行为:

(^3).match(1) # OUTPUT: «?1??»
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

say (1,3 ... * ).match(77); # OUTPUT: «Nil?»
Run Code Online (Sandbox Code Playgroud)

Ooookey.现在发生了什么?

say (1,3 ... * ).match(1);    # OUTPUT: «Nil?»
say (1,3 ... * ).match(/\d/); # OUTPUT: «Nil?»
Run Code Online (Sandbox Code Playgroud)

不喜欢序列.

say (^10).match(/\d/); # OUTPUT: «?0??»
Run Code Online (Sandbox Code Playgroud)

好的,再次有意义.

say <a b c>.match(/\w/); # OUTPUT: «?a??»
Run Code Online (Sandbox Code Playgroud)

恢复正常.它不喜欢Seqs吗?我假设,因为我查看了其他类的代码并且match没有重新实现,所有这些代码都调用了代码.但是我没有看到如何返回字符串并从NPQ设置变量,或者为什么它不能用于序列.

match stringification perl6 seq

6
推荐指数
1
解决办法
117
查看次数

Visual C++和gcc之间的宏##连接运算符的差异

我有一个这样的宏(不完全是,但功能相当):

#define STRUCTMEMBER(Member,Value) GlobalStructInstance. ## Member = Value
...
STRUCTMEMBER(Item,1);
Run Code Online (Sandbox Code Playgroud)

这在Visual C++中完美地工作,但是gcc 3.4.5(MingGW)会产生以下错误:

粘贴"." 并且"Item"不提供有效的预处理令牌

当我使用" - >"运算符时也会发生这种情况.我没有找到关于连接的提示,禁止使用这些运算符.

有没有人有想法?

gcc stringification visual-c++ c-preprocessor

5
推荐指数
2
解决办法
7348
查看次数

使用%s格式化时的#是什么

我遇到了一个断言的例子,并想知道它#是为了什么:

#define ASSERT( x ) if ( !( x ) ) { \
    int *p = NULL; \
    DBGPRINTF("Assert failed: [%s]\r\n Halting.", #x); \
    *p=1; \
  } 
Run Code Online (Sandbox Code Playgroud)

c c++ stringification c-preprocessor

5
推荐指数
2
解决办法
230
查看次数

C预处理器字符串怪异

我正在定义一个宏,它计算为一个常量字符串,保存文件名和行号,用于记录目的.

它工作正常,但我无法弄清楚为什么需要2个额外的宏 - STRINGIFY而且TOSTRING,当直觉暗示时__FILE__ ":" #__LINE__.

#include <stdio.h>

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define THIS_ORIGIN (__FILE__ ":" TOSTRING(__LINE__))

int main (void) {
  /* correctly prints "test.c:9" */
  printf("%s", THIS_ORIGIN);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说似乎是一个丑陋的黑客.

具体是什么,这样逐步发生阶段有人能解释__LINE__正确字符串化,为什么既不__FILE__ ":" STRINGIFY(__LINE__)__FILE__ ":" #__LINE__作品?

c stringification c-preprocessor

5
推荐指数
1
解决办法
3441
查看次数

将#defined常数转换为字符串

我有一个常量定义:

#define MAX_STR_LEN 100
Run Code Online (Sandbox Code Playgroud)

我想这样做:

scanf("%" MAX_STR_LEN "s", p_buf);
Run Code Online (Sandbox Code Playgroud)

但当然这不起作用.

可以使用什么预处理器技巧将MAX_STR_LEN数字转换为字符串,以便我可以在上面的scanf调用中使用它?基本上:

scanf("%" XYZ(MAX_STR_LEN) "s", p_buf);
Run Code Online (Sandbox Code Playgroud)

XYZ()应该是什么?

注意:我当然可以直接做"%100s",但这样做会失败.我也可以#define MAX_STR_LEN_STR"100",但我希望有一个更优雅的解决方案.

c macros c-strings stringification c-preprocessor

5
推荐指数
1
解决办法
6441
查看次数