创建宏变量方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了创建宏变量方法相关的知识,希望对你有一定的参考价值。
参考技术A 方法1:通过宏函数创建宏变量
%let dsid=%sysfunc(open(sashelp.class));
%let nvars=%sysfunc(attrn(&dsid,nvars));
%let nobs=%sysfunc(attrn(&dsid,nobs));
%let dsid=%sysfunc(close(&dsid));
%put &nvars.;
%put &nobs.;
方法2:通过SQL过程用变量值创建一个宏变量
proc sql noprint;
select distinct sex
into : list_a separated by \' \'
from sashelp.class;
quit;
%put &list_a.;
方法3:通过SQL过程用变量值创建多个宏变量
proc sql noprint;
select nvar, nobs
into dictionary.tables
where libname=\'SASHELP\' and memname=\'CLASS\';
/ 注意SASHELP\'和CLASS要大写 /
quit;
%put &nvar.;
%put &nobs.;
方法4:通过CONTENTS和SQL过程用变量名创建宏变量
proc contents data=sashelp.class out=con_class;
run;
proc sql noprint;
select name,put(count(name),5,-1)
into :clist separated by \' \',:charct
from con_class
where type=2;
quit;
%put &clist.;
%put &charct.;
方法5:通过SQL过程用变量名创建宏变量列表
proc sql noprint;
select name
into :clist1-:clist999
from dictionary.columns
where libname=\'SASHELP\' and memname=\'CLASS\';
quit;
%put &clist1.;
%put &clist2.;
方法6:通过SQL过程用变量值创建宏变量列表
proc sql noprint;
select count(distinct sex)
into :n
from sashelp.class;
select distinct sex
into :type1 - :type%left(&n)
from sashelp.class;
quit;
%put &n.;
%put &type1.;
方法7:通过DATA步接口子程序CALL SYMPUTX
data null ;
set sashelp.class nobs=obs;
call symputx(\'m1\',obs);
call symput(\'m2\',obs);
stop;
run;
%put &m1.;
%put &m2.;
使用 __LINE__ 为不同的变量名创建宏[重复]
【中文标题】使用 __LINE__ 为不同的变量名创建宏[重复]【英文标题】:Creating macro using __LINE__ for different variable names [duplicate] 【发布时间】:2012-05-09 22:00:32 【问题描述】:可能重复:Creating C macro with ## and LINE (token concatenation with positioning macro)
我正在尝试使用__LINE__
宏来生成不同的变量名。我有一个名为 Benchmark 的范围基准类(位于 utils 命名空间中),它的构造函数接受一个字符串。这是我创建的宏定义:
#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))
不幸的是,这会导致以下错误:
<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization
这使我得出结论,__LINE__
宏没有得到扩展。我根据this post 创建了我的宏。你知道为什么__LINE__
没有得到扩展吗?
编辑:可能编译器信息也是相关的。我正在使用 Visual Studio 2010。
【问题讨论】:
嗯。你试过bm## __LINE__
(带空格)吗?
@Cameron 感谢您的评论,但没有任何改变。
好的,再尝试一个技巧:#define _BENCHMARK_SCOPE(line) utils::Benchmark bm##line(...
和 #define BENCHMARK_SCOPE _BENCHMARK_SCOPE(__LINE__)
@Cameron - 仍然无法正常工作。这是 ideone 上的一个示例:ideone.com/5r5l1(试图使其尽可能简单)
【参考方案1】:
您需要使用 2 个宏的组合:
#define COMBINE1(X,Y) X##Y // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)
然后将其用作,
COMBINE(x,__LINE__);
【讨论】:
您知道我为什么需要为此使用两个宏吗? @izomorphius,实际上你的问题是另一个问题的重复,在那里它得到了很好的解释。我已经对你的问题发表了评论,请检查一下。【参考方案2】:试试这个代码,我在旧项目中使用过它
#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif
int ANONYMOUS_VARIABLE(var)
编辑:
我认为您应该在 Visual Studio 中使用 COUNTER,前提是还使用预编译的标头。
【讨论】:
它也适用于 LINE。【参考方案3】:您正在使用令牌粘贴。这发生在递归宏之前 扩展(以便您可以标记粘贴以获取您的宏的名称 想调用)。因此:
#define PASTE(a,b) a ## b
将准确的参数粘贴到PASTE
,然后尝试展开
生成的新令牌。为了达到你想要的效果,你需要一个
额外的间接级别:
#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)
这里,PASTE
的参数将在 PASTE_HELPER
之前展开
调用。
【讨论】:
以上是关于创建宏变量方法的主要内容,如果未能解决你的问题,请参考以下文章