精华内容
下载资源
问答
  • O,渐进表示法,接下来我尝试用最简单的方式进行说明。 学习算法我经常听到这个词汇,我一开始很难理解,什么鬼?其实简单的说,就是描述一个算法的好坏词。 大O,可以认为它的含义是“order of”(大约是)...

    感谢作者分享,原文链接:http://blog.csdn.net/u012816041/article/details/49888631

    大O,渐进表示法,接下来我尝试用最简单的方式进行说明。

    学习算法我经常听到这个词汇,我一开始很难理解,什么鬼?其实简单的说,就是描述一个算法的好坏词。

    大O,可以认为它的含义是“order of”(大约是)。

    简单列举几个,当人们形容:

    某个算法的时间复杂度是O(1),就说明这是一个优秀的算法。

    某个算法的时间复杂度是O(logn),就说明这是一个良好的算法。

    某个算法的时间复杂度是O(n),就说明这个算法还不错。

    某个算法的时间复杂度是O(n2),就说明这个算法差一些了。

    上面那些记住后,至少让你,听到这个词后不会呆。。额。。


    其实知其然不知其所以然是很可怕的,不过上面内容,起码保证了过一段时间不会一无所知。接下来是具体的数学分析和其他的一些表示法,直接上维基百科了。


    大O符号

    注:“order”在全文中被译为“”,也可以另译为“数量级”。

    大O符号英语Big O notation)是用于描述函数渐近行为数学符号。更确切地说,它是用另一个(通常更简单的)函数来描述一个函数数量级渐近上界。在数学中,它一般用来刻画被截断的无穷级数尤其是渐近级数的剩余项;在计算机科学中,它在分析算法复杂性的方面非常有用。

    大O符号是由德国数论学家保罗·巴赫曼(Paul Bachmann)在其1892年的著作《解析数论》(Analytische Zahlentheorie)首先引入的。而这个记号则是在另一位德国数论学家艾德蒙·朗道(Edmund Landau)的著作中才推广的,因此它有时又称为朗道符号(Landau symbols)。代表“order of ...”(……阶)的大O,最初是一个大写的希腊字母'Ο'(omicron),现今用的是大写拉丁字母O’,但从来不是阿拉伯数字‘0’

    使用

    这个符号有两种形式上很接近但迥然不同的使用方法:无穷大渐近与无穷小渐近。然而这个区别只是在运用中的而不是原则上的——除了对函数自变量的一些不同的限定, “大O”的形式定义在两种情况下都是相同的。[来源请求]

    无穷大渐近

    大O符号在分析算法效率的时候非常有用。举个例子,解决一个规模为n的问题所花费的时间(或者所需步骤的数目)可以表示为:T(n)=4n^2-2n+2。当n增大时,n^2项将开始占主导地位,而其他各项可以被忽略。 举例说明:当n=5004n^2项是 2n项的1000倍大,因此在大多数场合下,省略后者对表达式的值的影响将是可以忽略不计的。

    进一步看,如果我们与任一其他级的表达式比较,n^2项的系数也是无关紧要的。例如:一个包含n^3n^2项的表达式,即使 T(n)=1,000,000\cdot n^2,假定 U(n)=n^3,一旦n增长到大于1,000,000,后者就会一直超越前者(T(1,000,000)=1,000,000^3=U(1,000,000))。

    这样,大O符号就记下剩余的部分,写作:

    T(n)\in\Omicron(n^2)

    T(n)=\Omicron(n^2)

    并且我们就说该算法具有n^2阶(平方阶)的时间复杂度。

    无穷小渐近

    大O也可以用来描述数学函数估计中的误差项。例如e^x泰勒展开

    e^x=1+x+\frac{x^2}{2}+\hbox{O}(x^3)\qquadx \to 0

    这表示,如果x足够接近于0,那么误差e^x - \left(1 + x + \frac{x^2}{2}\right)绝对值小于x^3的某一常数倍。

    形式化定义

    给定两正值函数fg,定义:

    f(n)=\Omicron(g(n)),条件为:存在正实数cN,使得对于所有的n \geq N,有|f(n)| \leq |cg(n)|

    上述的定义表明,当n足够大,大过一个特定的N时,且存在一个正数c,使得|f|不大于|cg|,则fg\Omicron表示。fg的关系可以理解为g(n)f(n)的一个上界,也可以理解为f最终至多增涨的速度与g一样快,但不会超过g的增涨速度。

    常用的函数阶

    下面是在分析算法的时候常见的函数分类列表。所有这些函数都处于n趋近于无穷大的情况下,增长得慢的函数列在上面。c是一个任意常数。

    符号 名称
    \Omicron(1)\!常数(阶,下同)
    \Omicron(\log n)\!对数
    \Omicron[(\log n)^c]\!多对数
    \Omicron(n)\!线性,次线性
    \Omicron(n\log^*n)\!\log^*n迭代对数
    \Omicron(n \log n)\!线性对数,或对数线性、拟线性、超线性
    \Omicron( n^2)\!平方
    \Omicron(n^c), \operatorname{Integer}(c>1)多项式,有时叫作“代数”(阶)
    \Omicron(c^n)\!指数,有时叫作“几何”(阶)
    \Omicron(n!)\!阶乘,有时叫做“组合”(阶)

    一些相关的渐近符号

    大O是最经常使用的比较函数的渐近符号。

    符号 定义
     f(n)=\Omicron (g(n))渐近上限
    f(n)=o(g(n))asymptotically negligible(\lim{} \frac{f(n)}{g(n)} = 0
     f(n)=\Omega(g(n))渐近下限 (当且仅当 g(n) = \Omicron(f(n))
     f(n) = \omega (g(n)) asymptotically dominant(当且仅当g(n)=o(f(n))
     f(n) = \Theta(g(n))asymptotically tight bound(当且仅当f(n) = \Omicron(g(n))f(n)=\Omega(g(n))

    注意

    大O符号经常被误用:有的作者可能会使用大O符号表达大Θ符号的含义。因此在看到大O符号时应首先确定其是否为误用。

    大Ω符号

    大Ω符号的定义与大O符号的定义类似,但主要区别是,大O符号表示函数在增长到一定程度时总小于一个特定函数的常数倍,大Ω符号则表示总大于。

    用数学语言描述即是,f(\nu)=\Omega[g(\nu)]若存在x_1, \kappa使得:

    对于所有\forall x>x_1, f(x)>\kappa g(x).

    特性

    大Ω符号与大O符号正好相反,即:\begin{cases}f(\nu)=\Omicron[g(\nu)]\\g(\nu)=\Omega[f(\nu)]\end{cases}

    大Θ符号

    Θ符号大O符号大Ω符号的结合。即:f(\nu)=\Theta[g(\nu)]\!\begin{cases}f(\nu)=\Omicron[g(\nu)]\\f(\nu)=\Omega[g(\nu)]\end{cases}

    这一符号首先由高德纳于1970年提出[1]

    注意

    大Θ符号经常被误用;有的作者可能会使用大O符号表达大Θ符号的含义。因此在看到大O符号时应首先确定其是否为误用。


    我发现读完维基百科还是有一些不清晰的地方,或者不好理解的地方,再加上这些。

    设函数f ( n )代表某一算法在输入大小为n的情况下的工作量(效率),则在n趋向很大的时候,我们将f (n)与另一行为已知的函数g(n)进行比较:

    1)如果0,则称f (n)在数量级上严格小于g(n),记为f (n)=o( g(n))。

    2)如果,则称f (n)在数量级上严格大于g(n),记为f (n)=w( g(n))。

    3)如果c,这里c为非0常数,则称f (n)在数量级上等于g(n),即f (n)和g(n)是同一个数量级的函数,记为:f (n)=Θ( g(n))。

    4)如果f (n)在数量级上小于或等于g(n),则记为f (n)=O( g(n))。

    5)如果f(n)在数量级上大于或等于g(n),则记为f (n)=Ω( g(n))。

    这里我们假定f (n),g (n)是非负单调的,且极限存在。如果这个极限不存在,则无法对f (n)和g (n)进行比较。在进行此种计算时,一个经常用到的技术是洛必达(L'Hopital)法则。该法则由17世纪法国数学家Guillaume de L'Hopital发现(也有人认为是瑞士数学家Johann Bernoulli发现的)。该法则声称,两个函数的比率极限等于两个函数的导数的比率极限,这里当然假定两个函数的导数比率的极限存在,即有:


     

    有了这个定义,就可以对素性测试的两个算法进行比较了。

    展开全文
  • 大写“O符号详解

    千次阅读 2015-01-12 12:51:20
    Big-O 或者 landau notation(朗道标记法)是一种 定义一个函数尺度随着参数变化研究函数运行情况 的数学原理。

    通常您会开发一个测试数据库。它可能只供 10 人访问,所以你的编程和测试工作可以流畅地进行。一旦完成开发和 QA’d (通过质量检验),它将会正式上线(发布), 人们开始访问该网站。过了一年左右,该网站的响应速度越来越慢。在添加更多的数据库服务器没有起到作用后,您的系统管理员在my.cnf’s度过了他的”假期”, 甚至为系统新增了许多内存容量也无济于事。听起来像是在大批量访问网站的情况下程序(代码)结构制约了访问效果。系统对40000人的用户列表信息不能完成排序或处理,或者数组的元素超过了100万项,甚至简单的校验函数减缓了访问速度。为什么?到底发生了什么?

    大多数PHP 开发人员从未听说过Big-O ,然而在Web开发中 Big-O 也许比其他任何部分都更加重要(好吧,也许除了系统和操作系统编程以外:) )。代码块一天也许只被 10个用户执行,但是相同的代码很可能每分钟运行了成千上万次。

    什么是 Big-O ?

    Big-O 或者 landau notation(朗道标记法)是一种 定义一个函数尺度随着参数变化研究函数运行情况 的数学原理。换句话说:Big-O 会告诉你,一个strpos()函数在分别接收 10个和1000000 个 字符长度的字符串参数时运行时间的关系。它不会告诉你明确的运行时间,但是它(Big-O)会告诉你参数和运行时间的趋势关系。

    那么,也许你会问:这是怎么回事?

    具体来说...

    假设您有一个函数,它根据一定的条件将数组中的数据进行排序。例如,按照姓氏的字母顺序排序。 每个人都可以想象出: 对10个用户将会比 对1000万个用户排序快很多。但是(排序)如何更快或更好:后者将会大概花费多长时间?当知道问题的答案后,你会清楚在大量用户访问的环境下你的代码(系统)运行的速度。您将会明白系统的首要瓶颈因素:您的代码 或 硬件?换句话说,你要开始意识到系统的可扩展性。

    示例 1 :

    假设您有一个函数IsEven() :

    function isEven ($iNumber) { // 方法a
        return ( ($iNumber & 1) == 0);
    }

    此函数将会判断一个数值是否是偶数,如果是则返回值true, 否则返回值false 。

    对于此函数,无论传入的参数是 int(1) 还是int(100000005),都没关系;如果函数总是使用同样的时间去判断参数并返回值。

    现在,假设我们把函数修改成以下形式:

    </pre><pre name="code" class="php">function isEven ($iNumber) { // 方法b
        $bEven = true;
        for ($i=0; $i!=abs($iNumber); $i++) {
        if ($bEven == true) {
            $bEven = false;
        } else {
            $bEven = true;
        }
        return $bEven;
    }

    当然,(函数)这种写法没有多大意义。但是我偶尔会看到使用低效率算法的代码,所以上面的例子足以证明我的观点。

    当函数(方法b)接收的参数是 int(1) ,for循环语句只执行一次。 函数运行的很快,没有问题出现。然而,当我们想判断数值1000000是否是偶数时(接收的参数是 int(1000000) ) ,我们可能会遇到一点麻烦,因为for循环必须执行1000000次函数才能返回判断结果。

    如果我们把函数(方法a)放到一个图表中, X 轴表示参数 $iNumber( 取值范围 :1 ~ 1000 ) ,Y 轴表示函数得到判断结果所花费的时间,那么我们将会得到一条水平线的图形。这就表明函数无论接收什么样的 int数值,得到判断结果所花费的时间总是相同的。这可以标记为 O(1),这种函数的性能是最优的。无论您传入的参数是什么,函数得到处理结果所花费的时间总是一样。代码(函数)可扩展性的梦想成真了 :)

    现在,我们一起来分析函数(方法b) 。同样 X 轴表示参数 $iNumber , 我们将会看到一条上升的直线。我们用 O(N)标记此函数(N代表参数本身或循环的次数,函数运算规模) 。

    参数的数值大小与函数运算时间有直接关系。

    示例 2 :

    function getModuleInfoByID ($iModuleID) { // 方法 c
        foreach ($this->_aModuleInfo as $aInfo) {
            if ($aInfo['id'] == $iModuleID) return $aInfo;
        }
        return null;
    }

    当参数id在遍历的对象中能匹配上时,函数(方法c)则返回对应的module信息;否则返回null值。这是一种非常常见的方式通过遍历数组来查找数据。 这类函数可以标记为O(N) , 其中N是模块信息的数量,也是集合 $_aModuleInfo 元素的个数。

    我们如何来优化这种类型函数的性能呢?

    如果不使用遍历(迭代)而能实现查找数据的功能,将会是很好的选择。通过优化代码结构提高运算效率(降低 O-line 的斜率)总是麻烦的事情 :) 为了做到这一点,我们要对函数(方法c)做一些修改。例如,如果我们把集合元素存放到一个关联数组中,并且把元素的id 作为key(键),如下所示:

    function getModuleInfoByID ($iModuleID) { //方法 d
        if(isset($this->_aModuleInfo[$iModuleID]))
            return $this-> _aModuleInfo[$iModuleID];
        return null;
    }

    在函数(方法d)中,我们不用担心 $_aModuleInfo 数组的长度是多少。此函数运行时不需要执行遍历操作,而且无论是1个还是 1000000个 moduleInfo 元素都没关系。

    然而,我们需要注意以下几点:

    ● 函数isset()起什么作用?它可以用 O(1)还是用O(N)来标记?或者更糟?您必须要知道函数(包括它调用的函数)的运算性能。

    ● 您的以上对函数运算性能的检查是基于 PHP-level 。基于 CPU-level,结果也许是另一回事儿。例如:CPU处理数值数组要比处理关联数组快很多(前者不涉及哈希查找)。

    然而,在PHP中处理数值数组和关联数组的时间没有多大差别。

    各种各样的O的区别

    O’s的类型有很多并且很复杂 :) 坚持往下看哦,瞧瞧下面哪一种O’s能匹配您编写的函数。您可能从来不需要一个精确的公式,但是只要您知道您的函数运算性能模型类 似 O(log N),而不是 O(N),您已经知道了很多...

    下面是O-functions列表,按性能从优到劣依次排序:

    ● O(1)

    常数时间,无论参数是什么,函数运算的时间总是相同的。

    ● O(log N)

    对数时间,函数运算时间在开始时快速增长,但是过了一会儿,函数运算时间增长缓慢。这是个好消息,当您知道有许多对象要处理时(例如用户、文章、评论排序)。

    ● O(n) Linear(线性)

    参数的大小与函数运算时间有直接关系。两倍参数大小意味着两倍的运算时间。

    ● O(n^2) Quadratic(平方)

    大多数时候,这意味着拥有相同数据集的两个迭代器要参与运算(像许多未优化的排序算法)。

    ● O(n^3) Cubic(立方)

    与Quadratic(平方)一样,只是多了一个额外的循环。这对函数的运算性能来说是灾难性的。

    ● O(n!) Factorial(阶乘)

    这些图形几乎是直线上升(例如,10的阶乘是 3628800 ,这意味着大量的迭代操作)。如果您的函数性能模型与此类似,建议重写函数,这种函数的运算性能很糟糕。


    说明:图片来源 -- http://nl.wikipedia.org/wiki/Bestand:Exponential.png

    其中,红线是 O(n)线性图,蓝线是O(n^3)立方图,绿线是O(2^n)指数图。

    注意,尽管在x<=8范围内绿线的y值(时间)是最优的,但是在x>10范围内,绿线的y值(时间)是最差的。

    在读取数据时,我们至少统计查询了一半的数组元素。获取一个在 0 到 100范围内的随机数,有50%的机会这个随机数小于 50,同时有50%的机会这个随机数大于等于50 。然而,Big-O 要考虑最坏的情况。所以按顺序搜索长度为N的数组应该标记为O(N), 而不是 O(N/2) 。

    Big-O 注意事项

    请注意,O(*)标记没有说任何关于运算速度本身的事情。它只是告诉您函数的运算速度和参数是相对应的。例如,在某些情况下,一个 O(n)性能的函数可能比一个O(log n)或O(1) 性能的函数运算的快。然而,会有一个转折点,其它的函数运算的更快。您需要在函数、算法复杂性以及运算速度之间找一个平衡点。反复测试您函数的运算时间(性能)并比较结果。它们的运算性能也许没有您想象的那么糟糕(也许比你想的还要差;) )。测试中代码会告诉你结果,但是不经测试您是不知道的 :)

    总结

    了解您的函数以及它的运算性能。但是要确保优化函数性能不能过度。让每个函数的运算性能达到 O(1)水平是件完美的事情,但是实际上优化工作是没有尽头的,而且总要在开发时间、预算和速度以及优化工作之间寻找一个平衡点。



    1. 本文由mathew翻译,由程序员学架构校审

    2. 本文译自https://www.adayinthelifeof.nl/2009/12/21/big-o-notation/

    原文作者:Joshua Thijssen December 21, 2009

    3. 转载请务必注明本文出自程序员学架构(微信号:archleaner )

    4. 更多文章请扫码:

    展开全文
  • 今天复习C语言,发现short变量长度有点问题,希望大神来看看。第一段代码:#include ...有符号和无符号所占字节不一样吗? 就算是short占了4个字节,那65534也不该输出37777777776吧?希望大神帮忙解答一下,感激不尽!
  • 首先,O,Omega,Theta这三个符号并不一定和算法分析有关,这三个符号只是用来刻画函数的增长速度的(比如,微积分里那些什么什么余项也用到了小o记号)。假设有函数f(n)=3n^2+100n+1000,那么我们就可以说f(n)=O(n^2)...


    首先,O,Omega,Theta这三个符号并不一定和算法分析有关,这三个符号只是用来刻画函数的增长速度的(比如,微积分里那些什么什么余项也用到了小o记号)。假设有函数f(n)=3n^2+100n+1000,那么我们就可以说f(n)=O(n^2)=O(n^3),f(n)=Omega(n^2)=Omega(n), f(n)=Theta(n^2)。这里可以不涉及任何算法的什么最好最坏情况。 

      
    然后,具体到算法复杂度分析上。比如插入排序,在最坏情况下(原序列是倒序时),如果我们仔细计算此时需要的比较和交换次数,会发现它是一个f(n)=An^2+...的形式。于是我们就可以说,插入排序在*最坏情况*下的时间复杂度是Theta(n^2),也是O(n^2),也是Omega(n^2)。另一方面,在最好情况下(原序列已有序时),需要的比较次数是大约n次,于是我们说,在*最好情况*下的时间复杂度是Theta(n),也是O(n),也是Omega(n)。 
      
    如果我们笼统地问:插入排序(在*所有情况*下)的时间复杂度是多少?这个问题就不能用Theta回答了,因为最好情况和最坏情况的Theta是不一样的。我们只能回答,在所有情况下都是O(n^2),也可以回答,在所有情况下都是Omega(n) 
      
    回到你原帖的前两句话,O(f(n))不一定非要表示最坏情况下的时间复杂度,它表示的只是一个函数的增长速度的上界,至于这个函数是算法的最好情况还是最坏情况,随你的便。当然,一般情况下我们用到O时,一般想要表示的还是最坏情况,但这并不是必须。如我上面所述,最好情况下的时间复杂度也可以用O(n)来表示,只是没什么意义而已。 
      
    关于你后面的几个疑问,O(f(n))当然不是确界,对于f(n)=n^2+n+1,我们可以说f(n)=O(n^2),也可以说f(n)=O(n^100)。在分析算法时我们是希望这个界越紧越好,太松的界虽然是正确的但是意义不大。有很多时候,一个算法一眼看过去会有一个粗略的上界,但通过仔细分析可以得出一个紧很多的上界出来,典型的例子就是网络流的各种算法的复杂度分析。 
      
    一般讲时间复杂度多用O记号,原因已经说了,主要是算法在不同情况下的增长速度未必是一致的,但如果能够确定是一致的(比如只考虑最坏情况),并且能证明那个也是下界的话,就可以用Theta。我觉得算法导论上对此处理是比较严谨的,一般来讲能用Theta的地方它就会用Theta,不能的地方就用O。 
    展开全文
  • 符号与强符号

    千次阅读 2011-06-27 09:25:00
    3.5.5 弱符号与强符号2009-04-22 12:52 俞甲子/石凡/潘爱民 人民邮电出版社 《程序员的自我修养:链接、装载与库》第3章目标文件里有什么。本章介绍COFF目标文件格式和源代码编译后如何在目标文件中存储。本节为大家...

    3.5.5 弱符号与强符号

    2009-04-22 12:52 俞甲子/石凡/潘爱民 人民邮电出版社

    《程序员的自我修养:链接、装载与库》第3章目标文件里有什么。本章介绍COFF目标文件格式和源代码编译后如何在目标文件中存储。本节为大家介绍弱符号与强符号。

    AD:

     

    3.5.5  弱符号与强符号

    我们经常在编程中碰到一种情况叫符号重复定义。多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误。比如我们在目标文件A和目标文件B都定义了一个全局整形变量global,并将它们都初始化,那么链接器将A和B进行链接时会报错:

     

    b.o:(.data+0x0): multiple definition of `global'
    a.o:(.data+0x0): first defined here
    这种符号的定义可以被称为强符号(Strong Symbol)。有些符号的定义可以被称为弱符号(Weak Symbol)。对于C/C++语言来说,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。我们也可以通过GCC的"__attribute__((weak))"来定义任何一个强符号为弱符号。注意,强符号和弱符号都是针对定义来说的,不是针对符号的引用。比如我们有下面这段程序:
    extern int ext;
    int weak;
    int strong = 1;
    __attribute__((weak)) weak2 = 2;
    int main()
    {
    return 0;
    }

    上面这段程序中,"weak"和"weak2"是弱符号,"strong"和"main"是强符号,而"ext"既非强符号也非弱符号,因为它是一个外部变量的引用。针对强弱符号的概念,链接器就会按如下规则处理与选择被多次定义的全局符号:

    规则1:不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号);如果有多个强符号定义,则链接器报符号重复定义错误。

    规则2:如果一个符号在某个目标文件中是强符号,在其他文件中都是弱符号,那么选择强符号。

    规则3:如果一个符号在所有目标文件中都是弱符号,那么选择其中占用空间最大的一个。比如目标文件A定义全局变量global为int型,占4个字节;目标文件B定义global为double型,占8个字节,那么目标文件A和B链接后,符号global占8个字节(尽量不要使用多个不同类型的弱符号,否则容易导致很难发现的程序错误)。

    弱引用和强引用  目前我们所看到的对外部目标文件的符号引用在目标文件被最终链接成可执行文件时,它们须要被正确决议,如果没有找到该符号的定义,链接器就会报符号未定义错误,这种被称为强引用(Strong Reference)。与之相对应还有一种弱引用(Weak Reference),在处理弱引用时,如果该符号有定义,则链接器将该符号的引用决议;如果该符号未被定义,则链接器对于该引用不报错。链接器处理强引用和弱引用的过程几乎一样,只是对于未定义的弱引用,链接器不认为它是一个错误。一般对于未定义的弱引用,链接器默认其为0,或者是一个特殊的值,以便于程序代码能够识别。弱引用和弱符号主要用于库的链接过程,我们将在"库"这一章再来详细讲述。弱符号跟链接器的COMMON块概念联系很紧密,我们在后面"深入静态链接"这一章中的"COMMON块"一节还会回顾弱符号的概念。

    在GCC中,我们可以通过使用"__attribute__((weakref))"这个扩展关键字来声明对一个外部函数的引用为弱引用,比如下面这段代码:

    __attribute__ ((weakref)) void foo();
    int main()
    {
    foo();
    }
    我们可以将它编译成一个可执行文件,GCC并不会报链接错误。但是当我们运行这个可执行文件时,会发生运行错误。因为当main函数试图调用foo函数时,foo函数的地址为0,于是发生了非法地址访问的错误。一个改进的例子是:
    __attribute__ ((weakref)) void foo();
    int main()
    {
    if(foo) foo();
    }

    这种弱符号和弱引用对于库来说十分有用,比如库中定义的弱符号可以被用户定义的强符号所覆盖,从而使得程序可以使用自定义版本的库函数;或者程序可以对某些扩展功能模块的引用定义为弱引用,当我们将扩展模块与程序链接在一起时,功能模块就可以正常使用;如果我们去掉了某些功能模块,那么程序也可以正常链接,只是缺少了相应的功能,这使得程序的功能更加容易裁剪和组合。

    在Linux程序的设计中,如果一个程序被设计成可以支持单线程或多线程的模式,就可以通过弱引用的方法来判断当前的程序是链接到了单线程的Glibc库还是多线程的Glibc库(是否在编译时有-lpthread选项),从而执行单线程版本的程序或多线程版本的程序。我们可以在程序中定义一个pthread_create函数的弱引用,然后程序在运行时动态判断是否链接到pthread库从而决定执行多线程版本还是单线程版本:

    #include <stdio.h>
    #include <pthread.h>
    int pthread_create(
    pthread_t*,
    const pthread_attr_t*,
    void* (*)(void*),
    void*) __attribute__ ((weak));
    int main()
    {
    if(pthread_create) {
    printf("This is multi-thread version!/n");
    // run the multi-thread version
    // main_multi_thread()
    } else {
    printf("This is single-thread version!/n");   
    // run the single-thread version
    // main_single_thread()
    }
    }
    编译运行结果如下:
    $ gcc pthread.c -o pt
    $ ./pt
    This is single-thread version!
    $ gcc pthread.c -lpthread -o pt
    $ ./pt
    This is multi-thread version!

    展开全文
  • LaTeX 各种命令,符号

    万次阅读 多人点赞 2016-06-12 15:27:42
    函数、符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} latex数学符号表(2)" style="border:none; max-width:100%"> \acute{\eta} latex数学符号表(2)" style="border:none; max...
  • 符号和弱符号

    千次阅读 2018-01-06 18:08:56
    在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是强符号。关于多个强弱符号定义类型不一致的主要有下面三种情况: 1.两个或两个以上强符号类型不一致 2.有一个强符号,其他都是...
  • LaTeX常用符号整理

    千次阅读 2019-05-21 17:57:35
    在$$中插入LaTeX数学符号 一、常用的数学符号 1、小写希腊字母 符号格式 LaTeX语法 符号格式 LaTeX语法 α\alphaα ...o δ\deltaδ \delta π\piπ \pi ϵ\epsilonϵ \epsilon ρ\...
  • 函数、符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} \acute{\eta} \check{\alpha} \grave{\eta} \breve{a} \ddot{y} \dot{x} \hat{\alpha} \t...
  • C语言中的强符号与弱符号

    万次阅读 多人点赞 2012-09-22 23:31:02
    在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号。 对于它们,下列三条规则使用: ① 同名的强符号只能有一个,否则编译器报"重复定义"错误。 ② 允许一个强符号和...
  • Latex各种命令、符号、公式、数学符号、排版等

    万次阅读 多人点赞 2017-12-01 10:56:03
    本文仅供学习参考使用,一切版权和解释权均归原作者所有,转载地址:...数学符号详细内容见:http://mohu.org/info/symbols/symbols.htm 直接查看链接  http://www.mo
  • GCC中的弱符号与强符号

    千次阅读 2017-02-09 17:45:38
    我们经常在编程中碰到一种情况叫符号重复定义。多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误...1 b.o:(.data+0x0): multiple definition of `global' 2 a.o:(.dat
  • C语言符号

    千次阅读 2012-12-05 14:03:50
    C 语言的符号众多,由这些符号又组合成了各种各样的运算符。既然是运算符就一定有其特定的优先级,下表就是C 语言运算符的优先级表: 注:同一优先级的运算符,运算次序由结合方向所决定。 上表不容易...
  • 一、符号符号表 Global symbols(模块内部定义的全局符号) – 由模块m定义并能被其他模块引用的符号。 例如,非static函数和非static的全局变量(指不带static的全局变量) 如,main.c 中的全局变量名buf ...
  • ❂特殊符号大全

    千次阅读 2020-02-04 18:12:26
    数字符号 ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⑯ ⑰ ⑱ ⑲ ⑳ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂ ⒃ ⒄ ⒅ ⒆ ⒇ ⒈ ⒉ ⒊ ⒋ ⒌ ⒍ ⒎ ⒏ ⒐ ⒑ ⒒ ⒓ ⒔ ⒕ ⒖ ⒗ ⒘ ⒙ ⒚ ⒛ ㊀ ㊁ ...
  • 首先我表示很悲剧,在看《程序员的自我修养--链接、装载与库》之前我竟不知道C有强符号、弱符号、强引用和弱引用。在看到3.5.5节弱符号和强符号时,我感觉有些困惑,所以写下此篇,希望能和同样感觉的朋友交流也希望...
  • 如何在word中LaTeX一样键入公式

    万次阅读 多人点赞 2018-01-30 16:38:42
    如何在word中LaTeX一样键入公式 小伙伴们下学期就要开始写毕业论文了,大多数同学应该会选择word,不可避免的会有很多嵌套的公式需要大家添加在文本当中。 在LaTeX中,公式、矩阵等都可以用键盘键入,操作起来...
  • hhd,hhx,hhu, 这几个都是输出8位的, hd, hx, hu, 这几个都是输出16位数据的, d, lx, ld, lu, 这几个都是输出32位的...%llu 是64位无符号 %llx才是64位16进制数 Dev-C++下基本数据类型学习小结 环境...
  • 算法中的渐进符号 (符号总结说明)

    千次阅读 2015-08-25 09:18:34
    在看有些算法书或资料的时候,经常看到时间复杂度,空间复杂度的符号描述。参考算法导论,在这里做个小总结,和大家分享。 1.记号:(渐进确界): : 表示={ f(n):存在常数c1,c2,,对所有的,有:}     2.O...
  • LaTex符号应用

    万次阅读 2018-07-13 19:03:57
    原文链接:http://blog.csdn.net/anxiaoxi45/article/details/39449445函数、符号及特殊字符声调语法效果语法效果语法效果\bar{x}\acute{\eta}\check{\alpha}\grave{\eta}\breve{a}\ddot{y}\dot{x}\hat{\alpha}\...
  • c++符号表解析

    万次阅读 多人点赞 2019-01-10 14:59:43
    约在20世纪70年代以前,编译器编译源代码产生目标文件时,符号名与相应的变量和函数的名字是一样的。比如一个汇编源代码里面包含了一个函数foo,那么汇编器将它编译成目标文件以后,foo在目标文件中的相对应的符号名...
  • } 五、堆栈符号化 通过系统 api 获取的堆栈信息可能只是一串内存地址,很难从中获取有用的信息协助排查问题,因此,需要对堆栈信息符号化: // 未符号化前 Thread 0 name: Dispatch queue: ...
  • 微积分学和算法分析中的O, o

    千次阅读 2018-03-09 10:47:07
    类似的,在算法分析中也有渐近上/下界、非紧上/下界和紧渐近界的概念,对应的符号分别为O/Ω,oO/Ω,oO/\Omega, o/\omega和ΘΘ\Theta。 既然前两个符号相同,那么这些符号有什么联系呢? 比较 根据微积分...
  • %llu 64位无符号  (2011-05-20 22:35:39) 转载▼ 标签:  杂谈 分类: c语言 d,lx,ld,,lu,这几个都是输出32位的 hd,hx,hu,这几个都是输出16位数据的, hhd,hhx,hhu,这几个都是输出8位...
  • 数学符号在论文中的格式规范

    万次阅读 2018-05-31 11:22:44
    另外写几点投稿时新学到的几点:1,mathtype中敲空格:ctrl+al+space2,多行公式编号要和最后一行靠右,这可以通过调整公式上升达到(这个时候一般是公式下降了很多,下降的太多了,所以才把编号搞的居中一样,...
  • c语言之无符号/有符号数加减法运算

    万次阅读 2015-08-28 17:09:17
    c语言之无符号/有符号数加减法运算 转自:http://www.360doc.com/content/12/1129/15/1317564_250977880.shtml 1.加减运算指令是不区分有符号和无符号的,编程人员自己要心理有数; 2.在PC系统中,有符号数用...
  • Linux系统的I/O也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于Linux平台。而标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。两者...
  • Python常用的格式化符号

    千次阅读 2017-09-04 13:09:19
    常用的如下:   格式符号 转换 %c 字符 ... %o 八进制整数 %x 十六进制整数(小写字母) %X 十六进制整数(大写字母) %e 用科学计数法格式化浮点数 %E 作用和%e...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 206,020
精华内容 82,408
关键字:

像o一样的符号