精华内容
下载资源
问答
  • 题目描述:ABCDE五个人传球,由A开始第一次传球,经5次传球后传回到A的手上。其中A与B不会相互传球,C只会传给D,E不会传给C,共有多少种传法?解题思路:由于就5个人传球,人数比较少,可以定义枚举类型ABCDE,...


    题目描述:ABCDE五个人传球,由A开始第一次传球,经5次传球后传回到A的手上。其中A与B不会相互传球,C只会传给D,E不会传给C,共有多少种传法?

    解题思路:由于就5个人传球,人数比较少,可以定义枚举类型ABCDE,里面有5个人:A,B,C,D,E。设接球人的序列为:AXXXXA,其中中间4位是未知的。前面说了,人数比较少。所以对于中间4位数,可以定义为枚举类型ABCDE的变量来遍历所有可能的取值,通过与&&、或||运算来判定当前情况是否符合题目要求。好了,上结果:


    程序在我的资源里面,欢迎大家下载。ps:CSDN内搜索“”ABCDE五个人传球”就可以找到啦。

    展开全文
  • mkfontscale mkfontdir fc-cache
  • URL后面传递参数,后面可以byte数组吗 URL后面传递参数,后面可以byte数组吗 URL后面传递参数,后面可以byte数组吗 URL后面传递参数,后面可以byte数组吗 URL后面传递参数,后面可以byte数组吗
  • 这篇文章写的有点过于细节,因此考虑到可读性和日的可查阅性,我以两个问题作为引子。作为TCP相关项目的招聘,也可以作为面试题,不过,我敢肯定,大多数人都不能回答第一个问题,第二个问题可能会模棱两可。问题1...
    这篇文章写的有点过于细节,因此考虑到可读性和日后的可查阅性,我以两个问题作为引子。作为TCP相关项目的招聘,也可以作为面试题,不过,我敢肯定,大多数人都不能回答第一个问题,第二个问题可能会模棱两可。
    

    问题1:请描述TCP快速重传的细节

    场景描述:

    假设TCP进入快速重传时有以下的序列:



    你能给出重传的序列吗?

    答案:

    重传的序列如下:




    但是这是为什么呢?

    问题解析

    这里到了问题1的正文。
    TCP在快速重传的时候,会依照以下的优先级来传输数据段:
    优先级1:标记为LOST的数据段
    优先级2:新的尚未发送的数据段
    优先级3:在UNA和HIGH区间内没有标记为LOST,没有标记为SACKed,没有重传过的数据段

    下面我来解释一下这三类数据段各自是怎么定义的。
            首先,优先级1所述的标记为LOST的数据段是由RFC3517的IsLost例程定义的,其定义如下:
    IsLost (SeqNum):

        This routine returns whether the given sequence number is
        considered to be lost.  The routine returns true when either
        DupThresh discontiguous SACKed sequences have arrived above
        'SeqNum' or (DupThresh * SMSS) bytes with sequence numbers greater
        than 'SeqNum' have been SACKed.  Otherwise, the routine returns
        false.

    我们以下仍然以问题1的场景描述中的图示来解析,时不时的可能会变动一下细节,但不伤大雅。
            Linux在实现快速重传的时候,依照RFC3517的建议维护了一个计分板,该计分板中统计了哪些数据段是SACKed的,哪些数据段是LOST的,我们发现,上图正好是一个计分板的绝佳体现。
            在计分板上标记LOST数据段的时候,其要求是要满足RFC3517的IsLost例程,简单点说,就是任何一个被标记为LOST的数据段后面都要有至少DupThresh个被SACKed的数据段。为了满足这个要求,我们在计分板(也就是上图)中标记LOST数据段的方法也就简单了:
    从前往后遍历,只要碰到没有被SACKed的数据段就标记为LOST,遍历的过程以SACKed数据段剩余DupThresh个时停止!
    因此, 可以在遍历的过程中数SACKed数据段的数量,记为cnt,直到cnt的数量达到SACKed数据段总量与DupThresh的差为止退出。在Linux中,这个逻辑正是由函数tcp_mark_head_lost来实现的,可以查看Linux源码详细研究该函数,本文就不再赘述了。但是还是给出伪代码,如下:
    for each skb in write-queue
        if skb.SACKed == TRUE
            cnt++
        if cnt > SACKed_count - DupThresh
            break
        if skb.SACKed == FALSE
            skb.LOST = TRUE

    现在我们的计分板更新了,如下所示:




    然后,我们假设在拥塞窗口足够的前提下,当标记为LOST的数据段全部重传完毕之后,接下来传输什么。
            现在看优先级2传输的数据段,即尚未发送的新数据,也就是说在图中HIGH标记之后的数据段。这里也许你会有一点困惑,为什么新数据的传输优先级会更高。简单的解释就是,LOST标记的数据段数量是由SACKed数据段的数量决定的,理论上在数据包守恒的原则下二者是相等的,但考虑到网络乱序的存在,LOST标记的数据段数量会比SACKed数据段数量少一些,二者之差就是一个乱序度的度量值,也就是RFC3517中的DupThresh。因此,剩下那些既没有被SACKed,又没有标记为LOST的数据段,我们称为未决数据。理论上它们没有丢失,只是还在路上,之所以还没有收到ACK或者SACK的原因有三类:
    1).乱序了
    2).慢了
    3).ACK丢了

    不管是哪一个原因,它们并没有丢,起码是理论上认为它们并没有丢失,所以此时还需要再等待一下,不管是乱序了,慢了,还是ACK丢了,再等一下都是可以等到确认的,因此此时这类数据段的传输优先级自然就没有新的数据更高,于是在传输完LOST标记的数据段后,就要传输新数据,而不是上述的未决数据。
            最后,我们想一下最坏的可能性,即那些未决数据真的丢失了,这很可能是我们的预判过于乐观了,当这些未决数据真的丢失了时,滑动窗口会因为它们而被阻滞无法前行,因此必须在合适的时候去重传它们,这个时机可以尽可能地保守向后,于是它们的传输优先级自然而然也就排在了新数据之后了。

    现实场景确认

    如果仅仅是上面的理论分析,可能会比较枯燥,另外也不便于彻底理解,你只有看到它实实在在就是那样运作的,才能放心。本节用实例来打消最后的疑惑。依然采用packetdrill,脚本如下:
    +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
    +0 bind(3, ..., ...) = 0
    +0 listen(3, 1) = 0
    
    // 三次握手
    +0 < S 0:0(0) win 32792 <mss 1000, sackOK, nop, nop, nop, wscale 7>
    +0 > S. 0:0(0) ack 1 <...>  
    +.1 < . 1:1(0) ack 1 win 257
    
    +0 accept(3, ..., ...) = 4   
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 1001 win 257
    
    // 随意写一些数据
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 4001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 5001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 6001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 7001 win 257
    
    // 场景自此开始
    +0 write(4, ..., 1000) = 1000    // seq:7001-8001
    +0 write(4, ..., 1000) = 1000    // seq:8001-9001
    +0 write(4, ..., 1000) = 1000    // seq:9001-10001
    +0 write(4, ..., 1000) = 1000    // seq:10001-11001
    +0 write(4, ..., 1000) = 1000    // seq:11001-12001
    +0 write(4, ..., 1000) = 1000    // seq:12001-13001
    +0 write(4, ..., 1000) = 1000    // seq:13001-14001
    +0 write(4, ..., 1000) = 1000    // seq:14001-15001
    +0 write(4, ..., 1000) = 1000    // seq:15001-16001
    +0 write(4, ..., 1000) = 1000    // seq:16001-17001
    // 此时窗口已经塞满(初始窗口为10),17001-18001仅仅pending到发送队列,未实际发送
    +0 write(4, ..., 1000) = 1000    // seq:17001-18001
    
    // 窗口为10
    +0 %{ print tcpi_snd_cwnd }%
    
    // 我关闭了fack,以下仅仅触发sack的快速重传
    +0 < . 1:1(0) ack 7001 win 257 <sack 8001:12001 13001:14001, nop, nop>
    // 这里预期会重传7001-8001,由于窗口还够传1个段,预期还会传输尚未发送的17001-18001
    +0 < . 1:1(0) ack 7001 win 257 <sack 8001:12001 13001:16001, nop, nop>
    // 由于前面又SACK了2个新段14001-16001,按照计分板标记LOST的规则,会将12001-13001标记为LOST进而重传
    // 请注意:如果上述SACK中的SACK段是8001:12001 13001:14001而不是8001:12001 13001:16001,则12001-13001依然会重传,只不过是作为未决数据的前向重传!
    +0 < . 1:1(0) ack 16001 win 257    // 收到16001的ACK,此ACK为partial ACK(New Reno里规定)
    // partial ACK后,无新数据,但依然有未决数据16001-18001,它们会不会被重传呢?这个问题下面在正文中解答!
    
    +0 write(4, ..., 10) = 10
    // 直到write过后,发送新的10字节数据
    
    // 最后,发语辞,无意义,类似“呜呼”这样的...
    +10.000 < . 1:1(0) ack 18001 win 257

    我不喜欢用packetdrill本身的“预期”,我觉得这个packetdrill本身的机制就是垃圾(它并没有支持除了它调通的之外的情况!)!于是,我自己来预期...我还是用tcpdump来最终确认,图示如下:




    如果说将packetdrill脚本中的第二个SACK段换成第一个SACK段的重复,即sack 8001:12001 13001:14001而不是sack 8001:12001 13001:16001的话,tcpdump抓包结果是一致的,只不过关于12001-13001这个段传输的解释不同而已,这种情况下,该段属于未决数据段的前向传输!

            现在来解释上述packetdrill脚本中那个注释的疑问,即如果收到了partial ACK,并且其后面一直到HIGH再也没有被SACK的数据段,那么这些段会被重传吗?答案是不会!那么这里就有一个风险,万一它们真的丢了怎么办?!答案是只能等后续的SACK或者超时了!我来总结一下关于partial ACK后的重传吧:




    误区之所在

    我已经阐述了理论,但是不足,于是我阐述了上面的一个实例,然而还是不足,不足在哪里呢?不足在于,很多的逻辑会混淆在一起,比如优先级1和优先级3的数据段混淆在一起发送的话,你会认为这是通过一个机制发送的两个数据段还是通过两个机制分别发送的两个数据段呢?于是,我觉得有必要说一说。我先给出一个packetdrill脚本:
    +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
    //+0 fcntl(3, F_SETFL, O_NONBLOCK) = 0
    +0 bind(3, ..., ...) = 0
    +0 listen(3, 1) = 0
    
    +0 < S 0:0(0) win 32792 <mss 1000, sackOK, nop, nop, nop, wscale 7>
    +0 > S. 0:0(0) ack 1 <...>  
    +.1 < . 1:1(0) ack 1 win 257
    
    +0 accept(3, ..., ...) = 4   
    
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 1001 win 257
    
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 4001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 5001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 6001 win 257
    +0 write(4, ..., 1000) = 1000
    +.1 < . 1:1(0) ack 7001 win 257
    
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000    seq:15001-16001
    // 注意,我只发了9个数据段!
    
    +0 %{ print tcpi_snd_cwnd }%
    +0 < . 1:1(0) ack 7001 win 257 <sack 8001:12001 13001:14001, nop, nop>
    // 此时,应该重传7001-8001这是显然的,然而你会发现,连12001-13001也重传了,这是为什么呢?难道12001-13001也被标记为LOST了么?非也!
    // 最后,发语辞,无意义,类似“呜呼”这样的...
    +10.000 < . 1:1(0) ack 18001 win 257

    和之前的packetdrill脚本不同的是,我不再发送太多的数据,而只是发送到14001为止。
            此时,你会看到,数据段7001-8001和12001-13001同时被重传了,这是怎么回事呢?如果你初看,那么你会觉得TCP的重传逻辑一次性重传了所有的“空洞”,即7001-8001以及12001-13001,然而事实上7001-8001段和12001-13001段这两个段,并不是按照同一个机制传输出去的,第一个7001-8001数据段是优先级1的传输使然,而12001-13001数据段则是优先级3的传输使然!tcpdump的结果如下:




    在抓包上看,它们确实是一起传输出去的,怎么区分呢?非常简单,本文往前看即可,只要有新数据尚未发送,Linux协议栈就优先发送新数据,而不是重传“未决数据段”!如果在packetdrill脚本中再多发2个段的数据,那么你就会发现7001-8001段和12001-13001段被新数据段17001-18001给隔开了。如果你对Linux的代码比较熟悉,那么对协议栈进行probe也能很清除的看到这个结果,你只需要跟踪TCP对象的retransmit_high指针即可确认传输优先级1的数据段到哪里截止。

    问题2:请描述快速重传被触发的细节

    这个问题相对比较简单,答案如下:
    是否触发重传,不仅仅取决于被ACK/SACK的字节数与reordering*MSS的关系,还取决于发送的skb的大小。
    假设当前的MSS为1000,reordering的值为3,那么是不是一定要重复确认的字节数超过3000才会触发快速重传呢?答案是否定的!因为协议栈其实是在计数段数与reordering的关系,而不是字节数。运行如下packetdrill脚本并抓包:
    +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
    +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
    +0 bind(3, ..., ...) = 0
    +0 listen(3, 1) = 0
    
    +0 < S 0:0(0) win 32792 <mss 1000, sackOK, nop, nop, nop, wscale 7>
    +0 > S. 0:0(0) ack 1 <...>
    +.1 < . 1:1(0) ack 1 win 257
    
    +0 accept(3, ..., ...) = 4
    
    +0 write(4, ..., 1000) = 1000
    +0 > P. 1:1001(1000) ack 1
    +.1 < . 1:1(0) ack 1001 win 257
    
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    // 注意这里只发10个字节,即将10个字节封装在一个数据段中。
    +0 write(4, ..., 10) = 10
    +0 write(4, ..., 1000) = 1000
    +0 write(4, ..., 1000) = 1000
    
    +.1 < . 1:1(0) ack 1001 win 257 <sack 2001:3001, nop, nop>
    +0 < . 1:1(0) ack 1001 win 257 <sack 2001:4001, nop, nop>
    +0 < . 1:1(0) ack 1001 win 257 <sack 2001:4002, nop, nop>
    // 此时SACK了2001个字节,显然不够1000*3字节,会触发快速重传吗?
    
    +.1 < . 1:1(0) ack 6001 win 257

    如注释中的问题,会触发快速重传吗?显然不会!但是原因真的是因为SACK字节数不够3*1000吗?非也!
    试着将packetdrill脚本中的
    +0 write(4, ..., 10) = 10
    改为
    +0 write(4, ..., 1) = 1
    再次运行脚本,你会发现,快速重传竟然触发了,数据段1001-2001被重传!
            显然,Linux是根据段数来触发快速重传的,而不是根据字节数。

    后记与吐槽

    正如我敢说,玩OpenVPN的人,大多数只是虚玩,根本很少人懂一样。不破而立也是虚的。
            什么叫盲目?对待一个事物根本还没琢磨透就想在上面玩创新,这就是盲目。这种盲目与新文化运动前后中国文化青年内心的迷茫还有大不同,那种迷茫更多的是因为旧规则已然被打碎,新规则尚未确立,在新旧之间的那种夹层里,人的内心是痛苦的。然而,不破而立这种盲目却着实不是这种夹层里的感觉,而是一种自大的狂妄。
            如果说你要证明你的东西是好的,首先你要有一个不好的做参照,而不是拿一个你尚未琢磨透的东西做参照。这是当代青年的通病,当然我也是其中一员,然则我认识到这是一个大错。如果你有机会看现在IT领域的求职简历,侧重于研发的那种,你会发现各种精通,其内容往往都是大学必修课甚至选修课的目录,还有就是看过几本书就谈精通,殊不知很多书的书名定义就有大错误!比如我经常吐槽的,中国人写的《JAVA网络编程》,《Windows网络编程》...看完了之后,让人学会了JAVA编程,学会了Windows编程,却完全忘了网络,这些书与网络有关吗?
            仅仅知道socket接口的调用,就说自己精通网络,然后大评特评BGP协议怎么不好,VLAN标准应该如何改造...此人太猛。这种态度往往都是初学者携带的特征,我老婆是学日语的,记得刚上大一那会儿,她每到超时,看到各种包装袋上只要写有日语,就会出声朗读一番,后来随着她过了一级,读了研究生...现在再也不会出声朗读了。一般的初学者往往会觉得什么都很简单,其实揭开表明那层膜,下面的水非常深,要想有真正自己的东西,把这水淌浑是必不可少的。
            因此,本文特出两道题,试考一下温州皮鞋厂老板。
    展开全文
  • 参数可可不

    千次阅读 2018-07-10 09:19:00
    遇到的就是一个方法里,可一个也行,两个也行 public static DataTable GetInvoiceByTime(string Operation, string OrderSn=null) {} 后面的OrderSn在调用这个方法的时候,就可填可不填了。 在调用的...
    遇到的就是一个方法里,可传一个也行,传两个也行
    
     public static DataTable GetInvoiceByTime(string Operation, string OrderSn=null)
            {}
    后面的OrderSn在调用这个方法的时候,就可填可不填了。
    在调用的时候只填写前面的一个就可以用,也不要抱错
    
     OrderData.GetInvoiceByTime("Time");
    

      

    转载于:https://www.cnblogs.com/ZkbFighting/p/9287197.html

    展开全文
  • 传值,指针和引用区别和联系

    万次阅读 多人点赞 2016-11-27 12:15:28
    竟然自己发现对传值,指针,引用这个每天都在用的传递方式的区别还不是很清楚。以为自己懂了,其实还理解得还不够深入,基础还需要花时间琢磨。今天参考了很多篇博客和书籍做些总结。其实,不用分为三类,只有两...

    C++写了很多年,有一天,写着写着代码。竟然自己发现对传值,传指针,传引用这个每天都在用的传递方式的区别还不是很清楚。以为自己懂了,其实还理解得还不够深入,基础还需要花时间琢磨。今天参考了很多篇博客和书籍做些总结。

    其实,不用分为三类,只有两类即可。传值和传引用。为什么会出现传地址(即传指针)呢?本质就是大家一致对传值和传地址概念的理解错误导致,也是对指针的概念的理解错误导致。

    概念

    **指针:**指针就是一个变量,如果非要说是一个特殊的变量也不为过,因为指针的初始化和解引用等不同的操作方式而已。就内存的分布来说,指针和一个变量在内存中存放是没有任何区别的,无非指针存放的是变量的地址。

    **传值:**传值无非就是实参拷贝传递给形参,单向传递(实参->形参),赋值完毕后实参就和形参没有任何联系,对形参的修改就不会影响到实参。

    **传地址:**为什么说传地址也是一种传值呢?因为传地址是把实参地址的拷贝传递给形参。还是一句话,传地址就是把实参的地址复制给形参。复制完毕后实参的地址和形参的地址没有任何联系,对形参地址的修改不会影响到实参, 但是对形参地址所指向对象的修改却直接反应在实参中,因为形参指向的对象就是实参的对象。

    **传引用:**传引用本质没有任何实参的拷贝,一句话,就是让另外一个变量也执行该实参。就是两个变量指向同一个对象。这是对形参的修改,必然反映到实参上。

    例:

    #include<iostream>
    using namespace std;
    
    void Value(int n)
    {
    	cout << "Value(int n)"<< endl;
    	cout << "{" << endl;
    	cout << "	&n=" << &n << endl; 
    	cout << "}" << endl;
    	n++;
    }
    
    void Reference(int &n)
    {
    	cout << "Reference(int &n)" << endl;
    	cout << "{" << endl;
    	cout << "	n=" << n << "  &n=" << &n << endl;
    	cout << "}" << endl;
    	n++;
    }
    
    void Pointer(int *n)
    {
    
    	cout << "Pointer(int *n)" << endl;
    	cout << "{" << endl;
    	cout << "	n=" << n << "  &n=" << &n << endl;
    	(*n)++;
    
    	int b = 20;
    	cout << "	b=" << b << "  n = &b" << endl;
    
    	n = &b;
    	cout << "	n=" << n << "  &n=" << &n << endl;
    	(*n)++;
    	cout << "}" << endl;
    }
    
    int	main()
    {
    	int n = 10;
    	cout << "n = " << 10 << "  &n=" << &n << endl<< endl;
    
    
    	Value(n);
    	cout << "after Value() n=" << n << endl << endl;
    
    	Reference(n);
    	cout << "after Reference() n=" << n << endl << endl;
    
    	Pointer(&n);
    	cout << "after Pointer() n=" << n << endl << endl ;
    
    	system("pause");
    	return true;
    }
    

    运行结果:
    这里写图片描述

    分析:
    值传递时函数操作的并不是实参本身,形参和实参是相互独立的,所以对形参进行操作并不会改变实参的值。

    引用传递操作地址是实参地址 ,形参相当于实参的一个别名,对它的操作就是对实参的操作。

    指针传递时,可以通过指针操作实参,同样可以改变实参的值。

    总结
    传引用和传指针看上去效果一样的,但本质上有区别:

    指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。
    在值传递过程中,被调函数的形式参数作为被调函数的局部变量,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,前面说过,值传递是单向传递(实参->形参),赋值完毕后实参就和形参没有任何联系。那指针传递是怎么通过这个局部变量访问实参的呢,当然是通过局部变量中存储的地址。
    既然形参和实参是相互独立的,在没有任何修饰形参时,形参是可以被修改的,形参指针可以指向任何地方,而且修改后就无法再访问到实参。例如Pointer函数中n = &b后,(*n)++不会再修改实参的值,这也是传递指针时通常会用const进行修饰的原因。
    例如
    这里写图片描述

    而在引用传递过程中,被调函数的形式参数虽然同样作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

    引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。

    为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

    程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

    最后,总结一下指针和引用的相同点和不同点:

    ★相同点:

    ●都是地址的概念;

    指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

    ★不同点:

    ●指针是一个实体,而引用仅是个别名;

    ●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;

    ●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有 的, 前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)

    ●引用不能为空,指针可以为空;

    ●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;

    ●指针和引用的自增(++)运算意义不一样;

    ●引用是类型安全的,而指针不是 (引用比指针多了类型检查)

    以上内容是网上和书籍上找到的资料结合自己的理解写的,有不对的地方,欢迎指教,一同学习。

    展开全文
  • 音频透背后的技术实现

    万次阅读 2016-05-06 20:26:54
    现在市面上流行的电视盒大部分都是Android,“音频透”是一个经常见到的词,那到底什么是音频透、音频透背后的技术实现到底如何,引起了我的兴趣,因此花了点时间研究了一下。由于是针对全志H8的电视盒方案...
  • 《腾讯》读

    千次阅读 2017-04-16 22:44:16
    来自:《腾讯
  • 和后台联调,先调后台接口获取个token,然后登陆,每次请求都带token去请求后台接口,有个下载按钮,在点击下载按钮的时候需要在header里token,我就不知道怎么在window.location.href='xxxxxxx'加heard个...
  • C++引用和传值,指针

    千次阅读 2018-10-12 18:53:19
    我们需要数据而不改变数据存储,直接传值,如int a; 我们需要数据,并且改变值大小,需要地址,如 int * pa; 我们需要数据,并改变数结构中指针的指向,需要二级指针,如链表中的 node * * l; ... ...
  • 消息透

    千次阅读 2018-04-20 20:33:54
     透消息:对于传递的通道来说无需理会消息体格式及内容,通道只负责消息的传递,对消息不做任何处理,当客户端接收到透消息,由客户端自己来决定如何处理消息。正是因为透消息可以自定义消息体,也可以...
  • vue + element-ui + 阿里云oss服务端签名实践 采用JavaScript客户端直接签名(参见JavaScript客户端签名直)时,AccessKey ID和AcessKey Secret会暴露在前端页面,因此存在严重的安全隐患。因此,OSS提供了...
  • TCP重

    千次阅读 2019-06-10 15:50:40
    一、TCP重 1、重的原因 1)发端计时器超时 TCP每发送一个报文段,就对这个报文段设置一次计时器。当计时器超时而没有收到确认时,就重该报文。 注:原来报文哪去了呢?两种可能: 1)在中间节点丢了。2)...
  • 消息和非透消息

    万次阅读 2016-03-10 12:03:46
    消息,就是消息体格式及内容,对于传递的通道来说是不去过问的,通道只负责消息的传递,对消息不做任何处理,当客户端接收到透消息,由客户端自己来决定如何处理消息。正是因为透消息可以自定义消息体,也...
  • C++传值&指针&引用

    千次阅读 2017-03-23 14:27:21
    C++参数的三种方式:参数的值(称值传递,简称传值),参数的地址(称地址传递,简称为传址),和引用传递(称为引用),相应的函数传值调用,传址调用和引用调用日常是按需参数的值或者指针的,某次上课看我们...
  • 断点续

    万次阅读 2020-09-02 18:01:06
    【1】断点续 【1】断点续 参考资料 HTTP/1.1开始支持断点续了。一般断点下载时才用到Range和Content-Range实体头。HTTP协议本身不支持断点上传,需要自己实现。 Range #用于客户端到服务端的请求,可以...
  • 用NFC贴纸DIY实现华为一碰

    万次阅读 2019-11-18 18:32:32
    参考了相关的资料,顺利使用自备的NFC贴纸实现华为一碰的功能,特此总结,提供给想要DIY或者DIY失败的朋友进行参考。 华为“一碰”简介 华为一碰的功能简介不再赘述,这些在华为官网都可以看到。以下是...
  • input置为display,值不到后台

    千次阅读 2013-08-05 14:33:21
    input置为display,值不到后台 。悲剧啊,readonly吧
  • 解惑-1 关于透与透参数

    千次阅读 2017-07-21 09:40:41
    上次很巧合的听大佬提到了透和透参数。 原来使用个推的时候也有是否透的选项,当时对于透就只有一个模糊的概念 早上让大佬详细讲解了一波: 透在个推的例子是: A ->个推服务器 个推服务器->B 定义 A-...
  • TCP重机制

    万次阅读 2018-09-18 21:47:57
    为保证数据传输的正确性,TCP会重其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重,一是基于时间,二是基于确认信息的构成。  第一种基于时间的重在其下的数据链路层、网络层乃至...
  • TCP的快速重机制

    万次阅读 多人点赞 2018-07-10 14:51:37
    当一个报文段丢失时,在其等待超时的过程中,可能会出现这种情况:其的报文段已经被接收端接收但却迟迟得不到确认,发送端会认为也丢失了,从而引起不必要的重,既浪费资源也浪费时间。 幸运的是,由于TCP采用...
  • 前后端分离,参数出现400错误

    万次阅读 2016-11-21 18:15:31
    最近在做项目中的一个模块,一直卡在一块bug一直没有解决,项目一直报400错误,上网百度了一下400错误:**HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求。不作修改,客户程序就无法重复此...
  • STM32和树莓派串口透

    万次阅读 多人点赞 2018-11-21 21:51:46
    目录 树莓派环境串口透 ...第二步:确保第一步成功,将树莓派和STM32连接,进行串口透。 下面进行具体实验吧~ 树莓派环境串口透 在开始前说明以下几点: 1、树莓派UART端口的位置:TXD位于HEA...
  • Tcp重

    千次阅读 2015-08-19 15:29:24
    Ø 为什么TCP存在重 TCP是一种可靠的协议,在网络交互的过程中,由于TCP报文是封装在IP协议中的,IP协议的无连接特性导致其可能在交互的过程中丢失,在这种情况下,TCP协议如何保障其传输的可靠性呢? T C P...
  • PHP传值和引用、地址的区别

    千次阅读 2013-03-17 20:46:07
    PHP传值和引用、地址的区别 PHP传值和引用、地址的区别是什么? 传值: 是把实参的值赋值给形参,那么对形参的修改,不会影响实参的值 地址: 是传值的一种特殊方式,只是他传递的是地址,...
  • 在jsp接收到servlet过来的List进行遍历可以用jstl对其进行遍历 在jsp页面中引入: 用这组标签进行遍历:${userList}表示接收到的List因为servlet是用req.setAttribute("userList", userList);所以这个EL...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,281,285
精华内容 512,514
关键字:

后传