要是一个ps局部调亮变量在两次函数调用中保持其职责该变量的储存类型应当说明为

C语言函数问题_百度知道
C语言函数问题
3,必须说明成是()存储类型的.一个变量的()指明该变量可以使用的程序区域.函数形式参数的作用域是().直接或间接调用自己的函数称为()函数。21。5。4.要使一个局部变量在两次函数调用中保持其值.在所有函数之外说明的变量成为()
提问者采纳
3,必须说明成是(static 静态)存储类型的.一个变量的(定义)指明该变量可以使用的程序区域.函数形式参数的作用域是(函数内部).直接或间接调用自己的函数称为(递归)函数。 21.在所有函数之外说明的变量成为(全局变量).要使一个局部变量在两次函数调用中保持其值。 4。 5
提问者评价
其他类似问题
为您推荐:
c语言函数的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁下面的例子说明:函数可以返回局部变量的引用,欢迎讨论!
[问题点数:40分,结帖人yifuyou]
下面的例子说明:函数可以返回局部变量的引用,欢迎讨论!
[问题点数:40分,结帖人yifuyou]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年8月 C/C++大版内专家分月排行榜第三2012年7月 C/C++大版内专家分月排行榜第三
2013年 总版技术专家分年内排行榜第三
2012年 总版技术专家分年内排行榜第七
2012年8月 C/C++大版内专家分月排行榜第三2012年7月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。随笔 - 130&
文章 - 26&评论 - 2625&trackbacks - 29
问题:由于在多线程中使用了匿名函数外的局部变量而导致的Bug
static&void&Main(string[]&args)
&&&&for&(int&i&=&<span style="color: #;&i&&&<span style="color: #;&i++)
&&&&&&&&Thread&t&=&new&Thread(delegate()
&&&&&&&&&&&&Thread.Sleep(new&Random().Next(<span style="color: #,&<span style="color: #000));
&&&&&&&&&&&&Console.Write(i&+&",&");
&&&&&&&&});
&&&&&&&&t.Start();
将得到输出:<span style="background-color: #, 10, 10, 10, 10, 10, 10, 10, 10, 10,
而不是我们期望的类似于:<span style="color: #c0c0c0; background-color: #, 5, 6, 1, 0, 7, 9, 8, 4, 2, 这样的输出。这是为什么呢?(在实际项目中出现这个Bug的代码请参考[1])
分析:使用Reflector查看编译之后的代码
下面是编译前后的代码对比。(使用Reflector的具体方法请参考[2],这里仅展现结果)
可以发现,i 对于匿名方法来说算得上是&#8220;全局&#8221;变量,如果在线程处理 i 之前,i 的值就被改变了的话,就会出现我们不希望出现的结果。
解决方法1:使用更小范围的局部变量
我们做一个小小的更改,在for循环里面定义一个变量 j ,让匿名函数只访问这个 j
所以运行程序,可得到正确的输出:<span style="color: #c0c0c0; background-color: #, 5, 6, 1, 0, 7, 9, 8, 4, 2,
由此,我们可以做出一个假设:编译器会在声明匿名函数所使用的局部变量的地方声明AutoGenClass的实例。那么,可以推出另一个结论:如果匿名函数里面使用了成员变量,那么ThreadStart对象也会变成成员变量,有兴趣的话可以自己用Reflector看一下。
&&&&& 这个方法虽然能有效解决问题,但有一个缺点:声明临时变量的意图不明显。为了避免哪天有个十分热心又不明就里的程序员觉得&#8220;变量 j 根本和 i 一样嘛&#8221;而把 j 给移除了,我强烈建议在 j 的后面加一个注释:&#8220;这里声明一个临时变量 j 是有深意的,谁敢动它老子跟谁玩命!!&#8221;。为避免这个缺点,可考虑使用下面的解决方法。
解决方法2:在匿名函数中只使用它的参数
这次匿名函数压根就没使用&#8220;全局&#8221;变量,所以同样可得到正确的结果:<span style="color: #c0c0c0; background-color: #, 7, 0, 5, 3, 8, 1, 6, 4, 2,
如果需要使用线程池,代码大同小异:
static&void&Main(string[]&args)
&&&&for&(int&i&=&<span style="color: #;&i&&&<span style="color: #;&i++)
&&&&&&&&ThreadPool.QueueUserWorkItem(delegate(object&arg)
&&&&&&&&&&&&Thread.Sleep(new&Random().Next(<span style="color: #,&<span style="color: #00));
&&&&&&&&&&&&Console.Write(arg&+&",&");
&&&&&&&&},&i);
&&&&Thread.Sleep(<span style="color: #000);
&&&&& 让我们再一次仔细思考一下为什么会出现Bug,以及解决方法1和解决方法2是如何生效的。为什么会出现Bug呢?表面上看是因为使用了多线程。但为什么使用了多线程结果就不对了呢?是因为我们期望的执行顺序是&#8220;把i的值增加1、输出i、把i的值再增加1、再输出i&#8230;&#8230;&#8221;,而实际上由于输出 i 的操作由另一个线程来执行,导致输出 i 的操作进入了另一个平行宇宙——呃,我是说异步操作之中。这样,i 的值在不停地改变,而输出 i 的操作随时都可能被执行,所以输出的 i 的值就成了随机的,程序的行为也成了随机的,这可真是个不折不扣的Bug。想想看,如果另一个平行宇宙里的1-2-3脱掉裤子,会影响到我的裤子也一同掉下来,这是件多可怖的事情!
&&&&& 要解决这个问题,就要使 i 一但被传递给线程来执行,就不再受到主线程里对 i 的改变的影响。解决方法1通过每次创建新的线程前都创建一个新的AutoGenClass实例,并Copy i 的值(因为 i 是值类型)给AutoGenClass实例的成员变量达到这个目标。解决方法2通过在启动线程时把 i 的值压入匿名方法的参数堆栈来达到这个目标。
&&&&& 既然确保 i 的值在传递给线程执行之后就不再改变这么重要,我们是否应该去微软总部门前示威,要求在匿名函数里只能使用只读的局部变量呢?就这么定了!机票钱老赵出,现在报名&#8230;&#8230;
&&&&& 冷静。不应该做这样的限制,因为 1)匿名函数既可以用作同步执行,也可被异步执行。在同步执行的时候更改局部变量是没问题的,而且同步执行的情况比较多,我们哪能因噎废食呢?2)即使限制成只读变量也没用。因为如果 i 是个复杂类型的实例的话,即使声明成只读的,一样可以更改它的属性的值,而如果匿名函数正巧依赖它的属性值,Bug还是会发生。3)有时我们需要故意让线程共享可修改的对象,请看下文。
&&&&& &#8220;这TMD是怎么回事?&#8221;突然听到 Boss 吼道,&#8220;为什么你的程序输出的结果是无序的?马上给我改成输出 0,1,2,3,4,5,6,7,8,9, !&#8221;
&&&&&&可是我们用的多线程呀,怎么能保证各个线程按顺序取得数据呢?这种时候,我们就需要故意使用一个可被主线程和其它线程共享、修改的对象,当然一些同步操作也是必须的,请看下面的例子。
解决方法3:使用泛型Queue传递数据
代码如下:
static&void&Main(string[]&args)
&&&&Queue&int&&q&=&new&Queue&int&();
&&&&for&(int&i&=&<span style="color: #;&i&&&<span style="color: #;&i++)
&&&&&&&&q.Enqueue(i);
&&&&&&&&Thread&t&=&new&Thread(delegate()
&&&&&&&&&&&&Thread.Sleep(new&Random().Next(<span style="color: #,&<span style="color: #000));
&&&&&&&&&&&&lock&(q)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if&(q.Count&&&<span style="color: #)
&&&&&&&&&&&&&&&&&&&&Console.WriteLine(Thread.CurrentThread.Name&+&":&do&"&+&q.Dequeue());
&&&&&&&&&&&&}
&&&&&&&&});
&&&&&&&&t.Name&=&"线程"&+&i;
&&&&&&&&t.Start();
线程2:&do&0
线程1:&do&1
线程7:&do&2
线程9:&do&3
线程3:&do&4
线程5:&do&5
线程6:&do&6
线程8:&do&7
线程0:&do&8
线程4:&do&9
请按任意键继续.&.&.
&&&&& 使用了线程同步之后,线程们排着队去Queue里取数据,然后执行,在效率上就体现不出多线程的优势了。不过,如果换成用线程池利用后台空闲线程还是有意义的。
&&&&& 聪明的你一定想到了,泛型Queue一样可以通过参数传递进去。
static&void&Main(string[]&args)
&&&&Queue&int&&q&=&new&Queue&int&();
&&&&for&(int&i&=&<span style="color: #;&i&&&<span style="color: #;&i++)
&&&&&&&&q.Enqueue(i);
&&&&&&&&Thread&t&=&new&Thread(delegate(object&arg)
&&&&&&&&&&&&Thread.Sleep(new&Random().Next(<span style="color: #,&<span style="color: #000));
&&&&&&&&&&&&Queue&int&&qq&=&arg&as&Queue&int&;
&&&&&&&&&&&&lock&(qq)
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&if&(qq.Count&&&<span style="color: #)
&&&&&&&&&&&&&&&&&&&&Console.WriteLine(Thread.CurrentThread.Name&+&":&do&"&+&qq.Dequeue());
&&&&&&&&&&&&}
&&&&&&&&});
&&&&&&&&t.Name&=&"线程"&+&i;
&&&&&&&&t.Start(q);
&&&&& 既然.net提供了由线程向匿名函数传递参数值的功能,你想要定下一条&#8220;多线程回调的匿名函数只允许使用它的参数,禁止使用函数外的变量&#8221;的规矩是可以理解的。不过即使这样做,当变量是复杂类型的实例的时候,同样会有产生Bug的危险。所以,要理解为什么以及如何同步变量和线程的执行,灵活运用,别莫名其妙地掉了裤子。
&&&&& 由于Thread.Start()的参数只能有一个,所以需要传递多个数值的时候就必须提前构造一个数组或Struct,这多少还是有些不便。让我们去微软门前游行,要求为Thread.Start()提供一个可变参数的重载吧,机票钱老赵出&#8230;&#8230;
[1] JeffreyZhao,。cnblogs,2009.
[2] 菩提树下的杨过,。cnblogs,2009.
[3] overred,&&。cnblogs, 2009.
阅读(...) 评论()PHP引用操作以及外部操作函数的局部静态变量的方法_PHP教程_编程技术
您的位置: &
& PHP引用操作以及外部操作函数的局部静态变量的方法
通过引用方式在外部操作函数或成员方法内部的静态变量
下面举个简单的例子,说明三个关于引用方面的问题:
1. 参数引用后函数内进行类型转换同样是地址操作
2. 参数引用后再传递给其他函数时需要再次添加引用符才能保持地址操作
3. 函数返回&#20540;引用必须在函数申明时以及调用时都添加引用操作符
该例子使用的是对象方法的操作,同样适用于函数
test2($a);
var_dump($a);
var_dump($i);
return $i;
protected function test2(& $a) {
$a[&#39;name&#39;] = &#39;蜗牛&#39;;
$obj = new A();
$a = &#39;&#39;;
$c = & $obj->test1($a);
var_dump($a);
$obj->test1($a);
var_dump($a);
输出的结果
( 01:58:53)
( 17:09:59)
( 18:36:32)
相关排行总榜5.下列的描述中( )是错误的.(a) 使用全局变量可以从被调用函数中获取多个操作结果(b) 局部变量可以初始化,若不初始化,则系统默认它的值为0(c) 当函数调用完后,静态局部变量的值不会消失(_百度作业帮
5.下列的描述中( )是错误的.(a) 使用全局变量可以从被调用函数中获取多个操作结果(b) 局部变量可以初始化,若不初始化,则系统默认它的值为0(c) 当函数调用完后,静态局部变量的值不会消失(
5.下列的描述中( )是错误的.(a) 使用全局变量可以从被调用函数中获取多个操作结果(b) 局部变量可以初始化,若不初始化,则系统默认它的值为0(c) 当函数调用完后,静态局部变量的值不会消失(d) 全局变量若不初始化,则系统默认它的值为0正确的怎么正确了?感觉这题有点不好弄额
a 是正确的,全局变量在整个程序中都有效,可以被其他函数调用,每调用一次,并用调用的时候改变它的值,那么它就会获取一个新值,而多个函数调用,就会产生多个值,即操作结果,当你改变全局变量的值时,其他引用这个全局变量的地方的值也会发生改变的,所以全局变量要慎用.b是错的,定义变量的时候,系统会为它开辟一个内存空间,是随机的,如果你不为它赋值,那么这个内存空间中的值就是这个变量的值,并且这个值是不确定的,系统并不会默认它为0.例如,系统为它开辟了一个内存空间,而这个内存空间中原来有一个值为6,而这个变量并没有被赋值,那么,调用输出这个变量的时候,将会输出这个内存空间中原来就有的值6,系统是不会为它默认0值的.c 静态局部变量即定义为static的局部变量,这个静态局部变量的值在函数调用完后,其所占用的内存是不会被释放的,即它在程序结束前是一直占据这个内存而不会消失的,自然其内的值也就不会消失了,而如果不是静态局部变量 ,而只是普通的变量的话,在函数调用完后,它所占据的内存将会被释放,那么这个值也就没了,即消失.d
全局变量如果不初始化,那么它的值是0,局部变量不初始化,它的值不确定.}

我要回帖

更多关于 局部保持投影算法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信