全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 SAS专版
5813 8
2009-05-29
<p>The following SAS program is submitted:<br/>%let rc = Begin;<br/>%macro test;<br/>data out;<br/>set sashelp.prdsale nobs = totalobs;<br/>if totalobs > 10 then do;<br/>%let rc = high;<br/>end;<br/>else do;<br/>%let rc = low;<br/>end;<br/>run;<br/>%mend;<br/>%let rc = Before Execution;<br/>%test<br/>The data set SASHELP.PRDSALE has 50 observations. What is the value of the variable RC when the macro finishes<br/>execution?<br/>(A) low<br/>(B) high<br/>(C) Begin<br/>(D) Before Execution<br/>答案为:a</p><p>不明白为什么是a,请高手解答,谢谢了。</p>
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2009-5-30 11:31:00

SAS公司专门出这些花哨又不适用的题目来忽悠在校的学生,唉,可悲啊。答案的确是a,原因如下:

1)语句%let rc = Begin;将宏变量rc第一次设置成全局宏变量。

2)第二步:if totalobs > 10 then do;
%let rc = high;
end;
else do;
%let rc = low;
x=3;
end;

这步它设置了一个陷阱,一定要注意其中的if else语句是data步的条件语句,所以此时的rc宏变量其实应该是全局宏变量。也就是会说,不管你把这两个rc语句放在什么地方,只要在包含data步内部,那么它就一定是全部宏变量,原因请参考宏变量的help资料。所以,如果你把上面的判断语句改成如下:

%if totalobs > 10 %then %do;
%let rc = high;
%end;
%else %do;
%let rc = low;
%end;;

那么结果就是high.原因就是这时候的%if语句已经变成宏的判断语句,显然,%if totalobs > 10 条件为真,故执行%let rc = high;而不会执行$else后面的%let rc = low;
3)第三步:%let rc = Before Execution;这个很简单,因为此时已经跳出data步,但是又在Macro内部,故它又是一个局部变量,局部宏变量只要宏退出,它就从内存退出。

综上,你看到的rc其实包含在不同的符号表里面,如下:

%let rc = Begin;包含在全局宏变量符号表;

%let rc = high;包含在全局宏变量符号表;并覆盖%let rc = Begin;

%let rc = low;包含在全局宏变量符号表;并覆盖%let rc = high;

%let rc = Before Execution;包含在局部宏变量符号表;与上面的全局宏变量不在同一个符号表里面,两者占用不同的内存空间。且%let rc = Before Execution会随着宏程序执行完毕而推出内存,所以最后你看到的当然是全局宏变量的那个值Low了。

明白了没有?

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-30 11:38:00
另外我告诉你,不要做这些没有的,忽悠人的东西,真正在开发程序的时候谁也不敢这样把全局宏变量和局部宏变量名称混杂在一起。说实话,这些所谓的考级在我看来都是骗人的,你做一道实际应用的题目比考十道试题更能锻炼你的开发能力。你的明白?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-30 21:59:00

太谢谢了。呵呵,刚接触sas,想通过考级入一下门。

以后还是要多做实际应用的。请多指教。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-31 05:47:00
以下是引用nkwilling在2009-5-30 11:31:00的发言:

SAS公司专门出这些花哨又不适用的题目来忽悠在校的学生,唉,可悲啊。答案的确是a,原因如下:

1)语句%let rc = Begin;将宏变量rc第一次设置成全局宏变量。

2)第二步:if totalobs > 10 then do;
%let rc = high;
end;
else do;
%let rc = low;
x=3;
end;

这步它设置了一个陷阱,一定要注意其中的if else语句是data步的条件语句,所以此时的rc宏变量其实应该是全局宏变量。也就是会说,不管你把这两个rc语句放在什么地方,只要在包含data步内部,那么它就一定是全部宏变量,原因请参考宏变量的help资料。所以,如果你把上面的判断语句改成如下:

%if totalobs > 10 %then %do;
%let rc = high;
%end;
%else %do;
%let rc = low;
%end;;

那么结果就是high.原因就是这时候的%if语句已经变成宏的判断语句,显然,%if totalobs > 10 条件为真,故执行%let rc = high;而不会执行$else后面的%let rc = low;
3)第三步:%let rc = Before Execution;这个很简单,因为此时已经跳出data步,但是又在Macro内部,故它又是一个局部变量,局部宏变量只要宏退出,它就从内存退出。

综上,你看到的rc其实包含在不同的符号表里面,如下:

%let rc = Begin;包含在全局宏变量符号表;

%let rc = high;包含在全局宏变量符号表;并覆盖%let rc = Begin;

%let rc = low;包含在全局宏变量符号表;并覆盖%let rc = high;

%let rc = Before Execution;包含在局部宏变量符号表;与上面的全局宏变量不在同一个符号表里面,两者占用不同的内存空间。且%let rc = Before Execution会随着宏程序执行完毕而推出内存,所以最后你看到的当然是全局宏变量的那个值Low了。

明白了没有?

版主好像看错了。 %let rc = Before Execution 中的rc是在宏test的外面,不是局部宏变量. %test会将其内容复盖.
觉得这道题好像是考宏里面 if condition then do 与 %if condition %then %do 的区别. 试一试下面的步骤

1。run一下下面的code,
2。把 >10 改成 <10 再run一次
3。在 if,then,do,else,end 前加上%,再 run一次
4。再把 <10 改成 >10 再 run一次
对比一下log里的宏变量的值应该明白了

%macro test;
data out;
set sashelp.prdsale nobs = totalobs;
if totalobs > 10 then do;
       %let rc = high;
       %let local_rc = high;
       end;
  else do;
       %let rc = low;
       %let local_rc = low;
  end;
run;
%put _user_;
%mend;
%let rc = Before Execution;
%test
%put _user_;

[此贴子已经被作者于2009-5-31 9:23:12编辑过]

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2009-5-31 14:35:00

是的,楼上说的完全在理。如果这题把

%let rc = Before Execution;
%test

顺序颠倒一下,答案就不一样了。正如你所说,这题就是考%if 和if的区别。补充一点,应该还有对局部变量和全局变量的理解。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

点击查看更多内容…
相关推荐
栏目导航
热门文章
推荐文章

说点什么

分享

扫码加好友,拉您进群
各岗位、行业、专业交流群