功能包装:意见和批评所需 [英] Function Wrapper: Opinions and Critique Desired

查看:47
本文介绍了功能包装:意见和批评所需的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

前段时间,我正在使用递归功能。为了

简洁,我会这样定义:


int func_recurs(int arg1,int arg2,int prev_pos)

{

int crnt_pos = 0;

int result;


/ *东西发生在arg1, arg2和crnt_pos * /


func_recurs(arg1,arg2,(prev_pos + crnt_pos));


返回结果;

}


这里的关键部分(因为我确定你已经弄明白了)是

prev_pos(之前的)最后一次递归的位置与当前递归的
crnt_pos(当前位置)结合并传递给
成为下一次递归的prev_pos。


但是这样编写,我必须记住任何对func_recurs()

的调用总是看起来像这样:


func_recurs(arg1,arg2,0);


坦率地说,我认为在最后摇摇晃晃的不变是相当不错的。然后让我感到震惊的是,也许我可以隐藏 func_recurs

在另一个函数里面,所以我不必紧张我的大脑

记住那个讨厌的第三个论点;类似于:


func_lazymemory(int arg1,int arg2)

{

func_recurs(arg1,arg2,0);

}


作为C的新手,我觉得非常聪明,想要在我的

上拥有这一切。但后来我想:呸!肮脏的气味。必须有一个

更好的方式。


所以我把它更改为:


int func_recurs( int arg1,int arg2)

{

- static int prev_pos; / *方便地在第一次通话时初始化为0 * /

int crnt_pos = 0;

int result;


/ *东西发生在arg1,arg2和crnt_pos * /


- prev_pos + = crnt_pos; / *调整下一次递归* /

- func_recurs(arg1,arg2);

- prev_pos - = crnt_pos; / *恢复当前递归* /


返回结果;

}


提请注意四个" - >"然后,我想:男孩是

丑陋的,但我不再觉得我在某些方面欺骗了我的代码。我打算把这个功能收起来,忘记了......直到今晚。


今晚我在clc上浏览了几个月的老线程来了

讨论了函数包装器。 "酷,"我想。一个

响应引用了常见问题解答,所以我把它拉了起来并阅读了。所以,我的b / b
聪明的想法是老套的。数据! :-B


我开始重新思考我是如何处理这个功能的,并提出了一些问题和担忧:
$ / b >
1a)我是否使用了适当的包装(或者我不知道某些包装

规则或样式约定)?


1b)如果它被重写以传递这样的指针值,那么包装器是否会被改进(并且该程序可以节省一些

存储空间)?


func_lazymemory (int * arg1,int * arg2)

{

func_recurs(arg1,arg2,0);

}


2a)我的解决方案之一是更好/更清洁/更好吗?


2b)或者它们是等价的,选择一个是(我的问题) )个人

风格?


3)是否还有一些其他(可能是显而易见的)解决方案可以放弃我的第三个

论点莫名其妙地被忽视了?

感谢您的关注。

-

IM(绝对)!Knuth

A while back, I was mucking around with a recursive function. For
brevity''s sake, I''ll define it like this:

int func_recurs(int arg1, int arg2, int prev_pos)
{
int crnt_pos = 0;
int result;

/* stuff happens to arg1, arg2, and crnt_pos */

func_recurs(arg1, arg2, (prev_pos + crnt_pos) );

return result;
}

The critical part here (as I''m sure you''ve figured out already) is that
prev_pos (the previous position) of the last recursion is combined with
crnt_pos (the current positon) of the present recursion and passed along
to become the prev_pos of the next recursion.

But written this way, I had to remember that any call to func_recurs()
always had to look like this:

func_recurs(arg1, arg2, 0);

Frankly, I thought that constant 0 dangling at the end was rather
inelegant. Then it struck me that maybe I could "hide" func_recurs
inside another function so that I wouldn''t have to strain my brain
remembering about that pesky third argument; something like:

func_lazymemory(int arg1, int arg2)
{
func_recurs(arg1, arg2, 0);
}

Being new to C, I felt pretty clever for coming up with this all on my
own. But then I thought: "Bah! Smells of kludge. There must be a
better way."

So I changed it to:

int func_recurs(int arg1, int arg2)
{
-- static int prev_pos; /* conveniently init''d to 0 on 1st call */
int crnt_pos = 0;
int result;

/* stuff happens to arg1, arg2, and crnt_pos */

-- prev_pos += crnt_pos; /* adjust for next recursion */
-- func_recurs(arg1, arg2);
-- prev_pos -= crnt_pos; /* restore for current recursion */

return result;
}

Drawing your attention to the four "-->" lines, I then thought: "Boy is
that ugly", but I no longer felt I''d somehow cheated inside my code. I
packed away the function and forgot about it ... until tonight.

Tonight I was browsing through some months'' old threads on clc and came
across one that discussed function wrappers. "Cool," I thought. A
response referenced the FAQ, so I pulled it up and had a read. So, my
clever idea is old hat. Figures! :-D

I started thinking again about how I dealt with that function and came
up with some questions and concerns:

1a) Is my use of a wrapper appropriate (or am I ignorant of some wrapper
rule or style convention)?

1b) Wouldn''t the wrapper be improved (and the program conserve some
storage) if it were re-written to pass pointer values like this?

func_lazymemory(int *arg1, int *arg2)
{
func_recurs(arg1, arg2, 0);
}

2a) Is one of my solutions better/cleaner/preferable over the other?

2b) Or are they equivalent, and picking one is a matter of (my) personal
style?

3) Is there some other (maybe obvious) solution to ditching that third
argument that I''ve somehow overlooked?
Thanks for your attention.
--
I.M. (definitely) !Knuth

推荐答案

I.M。 !Knuth(在Xn*********************@81.174.50.80)说:


| 3)是否有一些其他(可能是显而易见的)解决方案,即抛弃

|我忽略了第三个论点?


通常还有其他一些方法(无论你在做什么):-)


我有两个简短的递归代码,你可能会发现

有趣:

http://www.iedu.com/mrd/c/getsm.c
http://www.iedu.com/mrd/c/getsmx.c 该交易类似的情况。


两者功能相同;但是第二个模块作弊在

中,它使用gcc扩展名允许在另一个函数中嵌入一个函数

声明。这是非标准但可能有一些价值

作为一个发人深省的设备。


-

莫里斯Dovey

DeSoto Solar

德索托,爱荷华州美国
http://www.iedu.com/DeSoto
I.M. !Knuth (in Xn*********************@81.174.50.80) said:

| 3) Is there some other (maybe obvious) solution to ditching that
| third argument that I''ve somehow overlooked?

There is usually some other method (no matter what you''re doing) :-)

I have two short pieces of recursive code that you might find
interesting:

http://www.iedu.com/mrd/c/getsm.c and
http://www.iedu.com/mrd/c/getsmx.c that deal with a similar situation.

The two are functionally equivalent; but the second module "cheats" in
that it uses a gcc extension to allow embedding one function
declaration inside another. It''s non-standard but may have some value
as a thought-provoking device.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto


2006年7月19日星期三06:33:14 +0000(UTC ),IM !Knuth"

< no ******* @ yoyodyne.comwrote:
On Wed, 19 Jul 2006 06:33:14 +0000 (UTC), "I.M. !Knuth"
<no*******@yoyodyne.comwrote:

>前段时间,我是用递归功能捣乱。为了简洁起见,我将这样定义:


int func_recurs(int arg1,int arg2,int prev_pos)
{

int crnt_pos = 0;

int结果;


/ *东西发生在arg1,arg2和crnt_pos * /


func_recurs(arg1,arg2,(prev_pos + crnt_pos));


返回结果;
}
这里的关键部分(因为我确定你已经弄清楚了)是
上一次递归的prev_pos(前一个位置)与
crnt_pos(当前位置)相结合目前的递归和传递
成为下一次递归的prev_pos。

但是这样写,我必须记住任何对func_recurs()的调用总是不得不看起来像这样:


func_recurs(arg1,arg2,0);

坦率地说,我认为最后摇摇晃晃的是0而不是
不雅。然后让我感到震惊的是,也许我可以隐藏 func_recurs
在另一个函数里面,这样我就不必紧张我的大脑了解那个讨厌的第三个论点;类似于:


func_lazymemory(int arg1,int arg2)

{

func_recurs(arg1,arg2,0);

}

作为C的新手,我觉得自己非常聪明地想出这一切。但后来我想:呸!肮脏的气味。必须有一个更好的方法。

所以我把它改为:

int func_recurs(int arg1,int arg2)
{
- static int prev_pos; / *方便地在第一次通话时初始化为0 * /
>A while back, I was mucking around with a recursive function. For
brevity''s sake, I''ll define it like this:

int func_recurs(int arg1, int arg2, int prev_pos)
{
int crnt_pos = 0;
int result;

/* stuff happens to arg1, arg2, and crnt_pos */

func_recurs(arg1, arg2, (prev_pos + crnt_pos) );

return result;
}

The critical part here (as I''m sure you''ve figured out already) is that
prev_pos (the previous position) of the last recursion is combined with
crnt_pos (the current positon) of the present recursion and passed along
to become the prev_pos of the next recursion.

But written this way, I had to remember that any call to func_recurs()
always had to look like this:

func_recurs(arg1, arg2, 0);

Frankly, I thought that constant 0 dangling at the end was rather
inelegant. Then it struck me that maybe I could "hide" func_recurs
inside another function so that I wouldn''t have to strain my brain
remembering about that pesky third argument; something like:

func_lazymemory(int arg1, int arg2)
{
func_recurs(arg1, arg2, 0);
}

Being new to C, I felt pretty clever for coming up with this all on my
own. But then I thought: "Bah! Smells of kludge. There must be a
better way."

So I changed it to:

int func_recurs(int arg1, int arg2)
{
-- static int prev_pos; /* conveniently init''d to 0 on 1st call */



只是一个人。静态变量在你的程序之前被初始化

开始执行并独立于你的函数。

删除del的电子邮件

Just a nit. Static variables are initialized prior to your program
beginning execution and independent of your function.
Remove del for email


Barry Schwarz< sc ****** @ doezl.netwrites:
Barry Schwarz <sc******@doezl.netwrites:

2006年7月19日星期三06:33:14 +0000(UTC), " IM !Knuth"

< no ******* @ yoyodyne.comwrote:
On Wed, 19 Jul 2006 06:33:14 +0000 (UTC), "I.M. !Knuth"
<no*******@yoyodyne.comwrote:



[...]

[...]


>>所以我将其更改为:

int func_recurs(int arg1,int arg2)
{
- static int prev_pos; / *方便地在第一次通话时初始化为0 * /
>>So I changed it to:

int func_recurs(int arg1, int arg2)
{
-- static int prev_pos; /* conveniently init''d to 0 on 1st call */



只是一个人。静态变量在您的程序之前初始化

开始执行并独立于您的函数。


Just a nit. Static variables are initialized prior to your program
beginning execution and independent of your function.



True - 但是,按照as-if规则,一个可以实现* * * $ / b
的实现将初始化延迟到第一次调用。 (

函数之外的任何内容都可以在此之前看到变量并检测到它没有初始化
。可以通过指针看到局部静态变量

在定义它们的函数之外,但是在调用函数之前没有办法
初始化这样的指针。)


但是我不能想到一个很好的理由来实现这样一个愚蠢的事情。


-

Keith Thompson(The_Other_Keith) ks***@mib.org < http://www.ghoti.net/~kst>

圣地亚哥超级计算机中心< *< http://users.sdsc.edu/~kst>

我们必须做点什么。这是事情。因此,我们必须这样做。

True -- but, by the as-if rule, an implementation conceivably *could*
delay the initialization until the first call. (Nothing outside the
function can see the variable before that and detect that it hasn''t
been initialized. Local static variables can be seen via pointers
outside the function that defines them, but there''s no way to
initialize such a pointer before calling the function.)

But I can''t think of a good reason for an implementation to do such a
silly thing.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


这篇关于功能包装:意见和批评所需的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆