这一篇要探讨的是“杨辉三角形的实现以及如何人工走循环”。涉及的知识点和内容很少,主要是想说明如何看懂循环,如何跟着循环走。属于C语言基础篇


学习编程的人,在学习的初期,几乎都会接触杨辉三角形。但与其说用代码实现输出杨辉三角形是一道编程题,倒不如说它是一道IQ题。因为在杨辉三角形的代码实现过程中,所涉及语法知识编程概念其实很少。

类似于杨辉三角形这类的编程题还有很多,它们在真正的实际开发中,用的很少,几乎可以说是除了在初学编程阶段以及在面试过程中会接触到之外,你就再也不会遇到了。

这类问题真正难的地方在于它逻辑上面的复杂,很多时候,即便拿到了实现代码,看的也云里雾里的。特别是那些涉及双重循环三重循环递归调用二叉树双向循环内核链表等等等等的,更烦的是这些东西之间还互相交叉重叠,绕来绕去的简直不要太恶心了。

虽然大多数情况下,我们都不用真正独立写出这些逻辑算法,只要套用前人已有算法的就行了。但是看的懂还是必要的。


所以这篇就简单的分析一下杨辉三角形实现过程中代码运行的流程。跟着流程从头到尾的走一遍程序。虽然对于一些大工程来说,跟着流程走这个过程往往是交由机器来帮我们完成的,像是GDB之类的调试工具。

但是提高自身的阅读代码能力还是很有必要的,否则你跟着GDB一步一步走,程序走错了,你也看不出来,那就毫无意义了。GDB只能说是作为辅助工具,能否调试好代码,还是得看你的代码阅读能力。


好了,先来看一下杨辉三角的实现代码,这篇代码引用自百度百科词条“杨辉三角”(https://baike.baidu.com/item/杨辉三角/215098?fr=aladdin),这里我就不用自己的代码了,以后有机会我想办法会把它再优化一下更新上来的。

#include <stdio.h>int main()
{int s = 1, h;         // 数值和高度int i, j;           // 循环的计数变量scanf("%d", &h);        // 用户输入层数printf("1\n");           // 输出第一行 1for (i = 2; i <= h; s = 1, i++)   // 行数 i 从 2 到层高{printf("1 ");     // 输出该行的第一个 1for (j = 1; j <= i - 2; j++)//列位置 j 绕过第一个直接开始循环printf("%d ", (s = (i - j) * s / j));printf("1\n");         // 输出最后一个 1,换行}getchar();            // 暂停等待return 0;
}

运行结果:

下面我们开始一步一步的跟着程序走下去(建议在电脑上面看的时候把代码复制到编辑器上面,编辑器和浏览器左右分屏对照着看,虽然我每一步都会配图片)。


第一步:程序先是创建了两个变量,一个“s”一个“h”,其中“s”用来临时储存算法运算出来的结果(也就是当前应该输出的值),“h”则是杨辉三角形的高度(也就是需要输出的行数)。


第二步:接收用户的输入,由用户决定杨辉三角形的高度


第三步:输出一个“1”同时换行,也就是手动把第一行给输出完成了。


第四步:然后就是进入了代码的关键算法了(为了方便说明,下面我以用户输入数字“6”为例进行分析,用“-”代替空格方便显示)。
当用户输入“6”的时候,最外层循环的判断条件为“i =2; i<= 6”循环会执行5次。

最外层循环有一个不太常见的用法需要说明一下,在外层循环的末尾循环体中,同时有两个表达式,多出来的“s = 1”的作用是在于控制“s”在每次外层循环开始之前初始化为1。

其实程序中的这一段也可以改为下面这个样子:


外层第一次循环

输出第二行的时候(此时“i = 2, s = 1”):
首先输出“1-”(此时缓冲区里面有“1-”)。
  内层循环(“j = 1, j <= 0”)不进入循环(此时缓冲区里面有”1-”)。
结尾输出“1\n”,把缓冲区里面的数据输出到用户的控制面板(此时缓冲区里面有“1-1”)。


外层第二次循环

输出第三行的时候(此时“i = 3, s = 1”):
首先输出“1-”(此时缓冲区里面有“1-”)。
  内层循环(“j = 1, j <= 1”)进入一次循环(此时缓冲区里面有”1-”)。
    内层第一次循环(“i = 3, j = 1, s = 1”):
    s = (3 - 1)*1/1 = 2 输出“2-”(此时缓冲区里面有“1-2-”)。
  退出内层循环。
结尾输出“1\n”,把缓冲区里面的数据输出到用户的控制面板(此时缓冲区里面有“1-2-1”)。


外层第三次循环

输出第四行的时候(此时“i = 4, s = 1”):
首先输出“1-”(此时缓冲区里面有“1-”)。
  内层循环(“j = 1, j <= 2”)执行两次循环(此时缓冲区里面有”1-”)。
    内层第一次循环(“i = 4, j = 1, s = 1”):
    s = (4 - 1)*1/1 = 3 输出“3-”(此时缓冲区里面有“1-3-”)。
    内层第二次循环(“i = 4, j = 2, s = 3”):
    s = (4 - 2)*3/2 = 3 输出“3-”(此时缓冲区里面有“1-3-3-”)。
  退出内层循环。
结尾输出“1\n”,把缓冲区里面的数据输出到用户的控制面板(此时缓冲区里面有“1-3-3-1”)。


外层第四次循环

输出第五行的时候(此时“i = 5, s = 1”):
首先输出“1-”(此时缓冲区里面有“1-”)。
  内层循环(“j = 1, j <= 3”)执行三次循环(此时缓冲区里面有”1-”)。
    内层第一次循环(“i = 5, j = 1, s = 1”):
    s = (5 - 1)*1/1 = 4 输出“4-”(此时缓冲区里面有“1-4-”)。
    内层第二次循环(“i = 5, j = 2, s = 4”):
    s = (5 - 2)*4/2 = 6 输出“6-”(此时缓冲区里面有“1-4-6-”)。
    内层第三次循环(“i = 5, j = 3, s = 6”):
    s = (5 - 3)*6/3 = 4 输出“4-”(此时缓冲区里面有“1-4-6-4-”)。
  退出内层循环。
结尾输出“1\n”,把缓冲区里面的数据输出到用户的控制面板(此时缓冲区里面有“1-4-6-4-1”)。


外层第五次循环

输出第六行的时候(此时“i = 6, s = 1”):
首先输出“1-”(此时缓冲区里面有“1-”)。
  内层循环(“j = 1, j <= 4”)执行四次循环(此时缓冲区里面有”1-”)。
    内层第一次循环(“i = 6, j = 1, s = 1”):
    s = (6 - 1)*1/1 = 5 输出“5-”(此时缓冲区里面有“1-5-”)。
    内层第二次循环(“i = 6, j = 2, s = 4”):
    s = (6 - 2)*5/2 = 10 输出“10-”(此时缓冲区里面有“1-5-10-”)。
    内层第三次循环(“i = 6, j = 3, s = 6”):
    s = (6 - 3)*10/3 = 10 输出“10-”(此时缓冲区里面有“1-5–10-10-”)。
    内层第四次循环(“i = 6, j = 4, s = 10”):
    s = (6 - 4)*10/4 = 5 输出“5-”(此时缓冲区里面有“1-5-10-10-5-”)
  退出内层循环。
结尾输出“1\n”,把缓冲区里面的数据输出到用户的控制面板(此时缓冲区里面有“1-5–10-10-5-1”)。


第五步暂停等待程序退出。


好了,至此杨辉三角的实现过程就算分析完了。


下面这个例子的功能是画一个由字母按照特定顺序排列组成的三角形,感兴趣的也可以看一下。

先看代码

#include <stdio.h>int main()
{int i,j;char ch, n;scanf("%c",&ch);//Cn = ch-'A'+1;    //n=3      //第一次进入  第二次进入  第三次进入//最外层循环//一次循环代表输出一行for(i=1; i<=n; i++)      //(i=1;i<=3)  (i=2;i<=3)       (i=3;i<=3){//内层第一个循环for(j=1; j<=n-i; j++) //(j=1;j<=2)  (j=1;j<=1)       (j=1;j<=0)printf(" ");   //打了2个空格   打了1个空格        打了0个空格//内层第二个循环for(j=1; j<=i; j++)      //(j=1;j<=1)  (j=1;j<=2)       (j=1;j<=3)printf("%c",ch-n+j);//C-3+1=A    C-3+1=A,C-3+2=B   C-3+2=B,C-3+3=C//打了个A 打了A和B        打了B和C//内层第三个循环for(j=i-1; j>=1; j--) //(j=0;j>=1)   (j=1;j>=1)      (j=2;j>=1)printf("%c",ch-n+j);//不进入循环     C-3+1=A   C-3+2=B,C-3+1=A//什么也没打  打了个A        打了个B和Aprintf("\n");    //||A      |ABA        ABCBA}return 0;          //         ||A//       |ABA//      ABCBA
}

运行结果。

其实过程分析在代码中已经写明白了,不过在这里,我还想逐条逐句再分析一遍,我尽量写的通俗易懂一些。在这个例子里面,分析起来应该还没有太大问题。以后有机会我可能还会分享另外一篇类似这种的人工走循环的逻辑分析文章,在那篇文章中的例子涉及到一个很复杂(至少在我当时是这么觉得的)的三层循环,那个分析起来可能就很费劲了。说实话那篇文章的话,我也不太有信心能把里面的逻辑关系说的很清楚明白。有些东西,你知道是那么一回事,但是却不一定能说的明白,你觉得你自己说明白了,别人却又不一定能听的懂。


在这个例子里面用的是printf()输出,由于printf()缓冲区的存在,所以输出的数据不会立即出现在用户面板上,只有当遇到要输出“/n”的时候,缓冲区里面的内容才会被推出来。虽然在这个程序里面看不出区别,不过还是要意识到这个缓冲区的存在。

如果不想要缓冲区的存在这里可以用putchar()来代替printf()作为输出函数,理论上你应该是可以看到用putchar()输出比用printf()输出顺畅不少的,但实际上由于在这个程序里面的输出之间的间隔时间太短,你的肉眼是察觉不到区别的。但是速度快的同时也不是没有牺牲的,这样子做会造成程序对于CPU的占用率提高,降低整体的效率,综合考虑下还是用printf()会比较好。

在开始之前,先说一下这篇代码的整体思路架构。
最外层的for循环用于控制输出的行数。n等于要输出的行数。
内层第一个for循环用于控制输出该行“第一个字母前面的空格”个数。
内层第二个for循环用于控制输出该行“第一个字母该行中间的最大字母”。
内层第三个for循环用于控制输出该行“中间的最大字母该行的最后一个字母。

下面我们开始一步一步的跟着程序走下去(建议在电脑上面看的时候把代码复制到编辑器上面,编辑器和浏览器左右分屏对照着看,虽然我每一步都会配图片)。


首先,程序运行到scanf()函数的时候,要求输入(这里其实应该检测一下输入是否合法的,为了方便讲解,就不弄那么麻烦了),这里我们以输入“C”为例进行分析。

当我们输入“C”的时候程序中的n就等于3了。n的作用就在于确定该三角形的层数(既输出的行数),同时也用于计算应该输出的字母。这个代码中用的是分而治之的方法。整体从上到下一行一行的输出。先是控制输出每一行前面的空格,再控制输出从第一个字母开始到该行中间的最大那个字母,然后输出剩下的字母。

题外话:在这里突然想起了一个挺有意思的阅读技巧。有时候看别人的分析解释说明的时候,如果不怎么看的懂,可以试着在脑海中把某些字眼改为自己易于理解的东西。比如把上面那段话中的”输出“两个字改成”画“字,再试着看一遍。

当n = 3的时候,最外层循环一共循环3遍,也就是输出三行。


为了便于说明用“|”代替空格。

输出第一行的时候(i = 1):

内层第个for循环的时候(此时缓冲区里面什么都没有:“”):
  初始化是“j = 1”判断条件是“j <= 2”所以会循环2次,每一遍输出1个空格,输出2个空格。
内存第个for循环的时候(此时缓冲区里面有两个空格:“||”):
  初始化是“j = 1”判断条件是“j <= 1”所以会循环1次,输出一个A。
内存第个for循环的时候(此时缓冲区里面有两个空格和一个A:“||A”):
  初始化是“j = 0”判断条件是“j >= 1”所以不会进入循环,什么也不输出。
把缓冲区里面的内容输出(此时缓冲区里面有两个空格和一个A:“||A”)。

输出第二行的时候(i = 2):

内层第个for循环的时候(此时缓冲区里面什么都没有:“”):
  初始化是“j = 1”判断条件是“j <= 1”所以会循环1次,每一遍输出1个空格,输出1个空格。
内层第个for循环的时候(此时缓冲区里面有一个空格:“|”):
  初始化是“j = 1”判断条件是“j <= 2”所以会循环2次,输出一个A和一个B。
内层第个for循环的时候(此时缓冲区里面有一个空格一个A一个B:“|AB”):
  初始化是“j = 1”判断条件是“j >= 1”所以会循环1次,输出一个A。
把缓冲区里面的内容输出(此时缓冲区里面有一个空格一个A一个B一个A:“|ABA”)。

输出第三行的时候(i = 3):

内层第个for循环的时候(此时缓冲区里面什么都没有:“”):
  初始化是“j = 1”判断条件是“j <= 0”所以不会进入循环,什么也不输出。
内层第个for循环的时候(此时缓冲区里面什么都没有:“”):
  初始化是“j = 1”判断条件是“j <= 3”所以会循环3次,输出一个A和一个B一个C。
内层第个for循环的时候(此时缓冲区里面有一个空格一个A一个B一个C:“ABC”):
  初始化是“j = 2”判断条件是“j >= 1”所以会循环2次, 输出一个B一个A。
把缓冲区里面的内容输出(此时缓冲区里面有一个空格一个A一个B一个C一个B一个A:“ABCBA”)。


最后退出循环结束程序。

好了,说到这里整个程序就算分析完了。初学者阅读一些比较复杂的代码的时候,可以先尝试像代码中那样用注释跟着程序走上一遍。接触多了之后,慢慢的就可以做到把这些步骤都在脑海中走完而不需要写出来了。


附上这个例子的精简版代码:

#include <stdio.h>
int main()
{int i,j;char ch;scanf("%c",&ch);for(i=0; i<ch-'A'+1; i++){for(j=0; j<=ch-'A'-i; j++)putchar(' ');for(j=0; j<=i; j++)putchar('A'+j);for(j=i-1; j>=0; j--)putchar('A'+j);putchar('\n');}return 0;
}

以及数字版的三角形实现代码(这个代码目前只能实现10层以下的三角形,以后有机会再优化):

#include <stdio.h>
int main()
{int i,j,n; scanf("%d",&n);   for(i=0; i<n; i++){for(j=0; j<=n-i-1; j++)putchar(' ');for(j=0; j<=i; j++)putchar(j+'1');for(j=i-1; j>=0; j--)putchar(j+'1');putchar('\n');}return 0;
}

还有星号符版三角形实现代码(单位为“*”):

#include <stdio.h>
int main()
{int i,j,n;scanf("%d",&n);for(i=0; i<n; i++){for(j=0; j<=n-i-1; j++)putchar(' ');for(j=0; j< 2*i+1; j++)putchar('*');putchar('\n');}return 0;
}

题外话(纯属瞎扯,感兴趣的可以看下)

其实阅读程序不是什么太难的事情,难的还是自己想出来这么一个算法,这个我还真没法说明白是怎么想的出来这些算法的。很多人可以看的懂别人写的算法,知道别人算法的巧妙性,但是要是自己去写的话,却怎么也写不出来,没这个思路,不知道该怎么去写。

感觉嘛,写算法这件事情还是挺需要一点灵性和一点运气的,先是要有个大概的思路,但有时候同一个需求你会想到有很多种不同的实现思路,而且每一个思路都是那种感觉可能行,又有可能不行的样子。在你没有着手去实现这思路之前,你都不知道它的真正可行性。

这就好像你面前同时有好几条路可以走,但是在你没有跟着走下去之前,你又不知道到底那条路是可以走到终点的,有可能是A思路,有可能是B思路,也有可能是AB思路都可以, 更有可能是ABC思路都不可以,走到最后你还是要回到原点去寻找D思路。又或者,可能ABC思路都是可以的,只是你走到了半路以为自己走错路了,走不下去了,没耐心了,看不到希望了,你半路回头去寻找渺茫的D思路去了而已。这些都有可能。

或者,你运气还算好,一开始就选对了路,一路坚持走到了终点。但是,你有没有想过,除了你选的A思路是可行的以外,C思路也是可行的。而且如果你一开始顺着C思路走,整个代码实现的流程将会更加简洁,逻辑结构将会更加清晰,同时程序运行的效率也会更加高效呢?而这所有的所有,如果你不先尝试性的走出第一步,你永远都不会知道。

我的方法是,觉得这个思路可行,就尝试性的去实现它,不撞南墙不回头,撞了再回头。很多时候,你一开始只有一个思路,但是在你实现这个思路的过程中,你慢慢的又会突然之间灵光一闪,又想到了另外一个思路。有时候人脑就是这么一个神奇的东西。你不断的去接触一个问题,接触的多了,灵感就这么突然来了。

实现一个算法是一件很有成就感又很惊喜的事情。就好像第二篇代码中的那个变量n,它本身即可以用来控制输出的行数,又可以参与到内层循环中通过运算实现别的功能。这种感觉就好像是自己一开始定义n这个变量仅仅只是为了用来控制输出行数的,但是你写代码的过程中却突然发现这么一个自己随手写的变量,在你想实现别的功能的时候,竟然很巧合的可以用来干一些别的事情。你突然就会很惊喜自己怎么这么聪明啊,竟然写出了这么巧妙的代码(虽然你一开始真没这么想过),然后你就会把你的代码拿给你的同学看,然后自豪的说你在写这篇代码的时候,一开始就想好了这个算法了,巧妙的利用了这个地方的重合,减少了代码重复性的同时又节约了内存,满满的成就感油然而生(此处应该有掌声)。哈哈哈,开个玩笑(虽然我经常就是这么干的)。

但是写算法的过程中确实经常会遇到这种情况的,有时候一个变量同时有好几种用途,这种情况我也不知道该怎么解释,感觉冥冥中总有某些东西连接着整个算法,使得某些算法可以做到很巧妙,很完美,很无可挑剔。
这说的有点玄,就像是你为了一个大需求下面的某个小需求创建了一个变量,那么这个变量就很有可能会和大需求下面的其他小需求产生一些直接或者间接的关系,然后这个变量就很有可能会有多种用途。可能是由于事物不同属性之间总会或多或少有着某种联系的原因吧。
就好像你的需求是计算一个长方体,你在计算它的面积的时候创建了长宽的变量,然后你在计算它的体积的时候突然发现你前面的长宽变量也可以用来二次使用。虽然这种关系在平时编程开发面对具体需求的时候可能表现不是那么明显,虽然我没法证明,但我觉得这种东西是真的存在的。
否则为什么有些代码的算法就是可以做到那么巧妙,那么完美,那么无可挑剔呢?或者也仅仅是巧合,是由于人类的主观能动性,使得我们更倾向于去寻找程序算法中的各种巧合然后加以利用吧!不过我感觉嘛,应该是要先存在着那层巧妙的联系,而后我们才能把这层巧妙的联系寻找出来加以利用的。

其实有时候我真觉得这个世界真是奇妙,明明你在写一个算法的时候没有想过太多,就这么用最笨的办法一路跌跌撞撞的走到了终点,但是当你回过头来看一下你原来走过的路,你又总能找到一些捷径,就好像这些捷径是必然存在一样。说的有点玄对吧?我其实就是在说算法优化啦。


写在后面

一开始我在翻找我以前写的代码寻找素材的时候,找到了一个画三角形的代码,而且乍一看还挺像杨辉三角形的,于是这篇文章我的创作初衷就是为了详细分析一下杨辉三角形的实现流程的。但在分析的过程中越写越觉得不对劲,因为杨辉三角形的概念我大概还是有点印象的。
最后不放心才再去查了一下杨辉三角形的结构,才发现我找到的代码不是画杨辉三角形的,但是我整篇文章都快要定稿了都。然后我看着文章发呆了很久,在想怎么去改。最终的决定方案是——我同时再把杨辉三角形也给分析完算了。
当时22点(原本计划是十二点之前完成这篇文章然后美美的睡一觉的,结果熬到了现在),然后我就先去洗了个澡,洗完衣服再晾起来之后就已经23点多了。从23点半到1点半这段时间,我都是在想办法用自己的算法去实现画杨辉三角形的功能,但是很惭愧的说,一直到2点我都没想到很好的办法。
这期间我也不是没想过用数组来储存然后再输出,网上的代码也大多数是用这个方法的,但用数组的方法就和这篇文章要讨论循环算法内容不太对的上,就放弃了。我甚至想过用链表来创建队列,利用队列或栈的存储特点来实现,还想过用二叉树来实现。但都不是我想要的,我真正想要的实现过程就是像这篇文章中的第一个例子那样,单纯的用循环和算法来实现画杨辉三角形。
只有用这种方式的代码才是最高效的。所以我才引用了文章中那个例子的代码来分析,感谢原作者。大概3点的时候我才开始动手写分析,现在刚好5点完稿,还要上传加排版,希望6点前能睡觉吧!


零BUG是原则性问题。

杨辉三角形实现过程详解-C语言基础相关推荐

  1. #转载:杨辉三角形实现过程详解-c语言基础

    杨辉三角形实现过程详解-C语言基础 十一一个人 2018-12-26 06:45:45 6465 收藏 28 最后发布:2018-12-26 06:45:45首发:2018-12-26 06:45:4 ...

  2. Keras深度学习实战(1)——神经网络基础与模型训练过程详解

    Keras深度学习实战(1)--神经网络基础与模型训练过程详解 0. 前言 1. 神经网络基础 1.1 简单神经网络的架构 1.2 神经网络的训练 1.3 神经网络的应用 2. 从零开始构建前向传播 ...

  3. python脚本语言采用声音作为手段_python 利用pyttsx3文字转语音过程详解

    这篇文章主要介绍了python 利用pyttsx3文字转语音过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下# -*- coding: utf ...

  4. python发音语言-python 利用pyttsx3文字转语音过程详解

    这篇文章主要介绍了python 利用pyttsx3文字转语音过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下# -*- coding: utf ...

  5. U-Boot 之一 零基础编译 U-Boot 过程详解、Image 镜像介绍及使用说明、DTB 文件使用说明

      最近,工作重心要从裸机开发转移到嵌入式 Linux 系统开发,在之前的博文 Linux 之八 完整嵌入式 Linux 环境.(交叉)编译工具链.CPU 体系架构.嵌入式系统构建工具 中详细介绍了嵌 ...

  6. c语言的编译过程详解

    c语言的编译过程详解 IDE的使用让很多和我一样的人对C/C++可执行程序的底层生成一知半解,不利于我们深入理解原理.在这里小结一下,望路过的大神指正~ 前言:从一个源文件(.c文件)到可执行程序到底 ...

  7. U-Boot 之一 零基础编译 U-Boot 过程详解 及 编译后的使用说明

      在之前的博文 Linux 之八 完整嵌入式 Linux 环境介绍及搭建过程详解 中我们说了要一步步搭建整个嵌入式 Linux 运行环境,今天就开始编译 U-Boot.我所使用的硬件平台及整个要搭建 ...

  8. html语言怎么打出红色心形,使用HTML-CSS画爱心的过程详解

    如何使用HTML-CSS来画出一个爱心呢,下面我就教大家使用HTML-CSS画爱心的方法. 第一步: 先画一个正方形.如图: css画桃心 .heart-body { width: 500px; ma ...

  9. centos7 启动流程图_Linux启动过程详解

    Linux启动过程详解 作者:江远航 一.启动流程图如下 图1 Linux启动流程图 BIOS ---> MBR ---> Kernel---> Init 二.Linux启动顺序 一 ...

最新文章

  1. 程序员拯救乐坛?OpenAI用“逆天”GPT2.0搞了个AI音乐生成器
  2. java sleep不能使用_java无主窗口GUI程序主线程不能调用sleep(long)方法,会产生异常...
  3. 【Sql server: T-Sql 技术内幕 系列】之索引篇
  4. TCP、UDP以及HTTP的简单讲解
  5. 专访 | 执拗、纯粹的网易阮良,和他的梦想团队
  6. 控制SAP Spartacus shipping address页面spinner显示的逻辑
  7. 论文《learning to link with wikipedia》
  8. linux mysql导出导入表_linux mysql 数据库操作导入导出 数据表导出导入
  9. java exception信息_可能通过Java Exceptions暴露敏感信息?
  10. java tlv协议_看懂通信协议:自定义通信协议设计之TLV编码应用
  11. 总结UIViewController的view在有navBar和tabBar影响下布局区域的问题
  12. 【Unity】UGUI无法修改UI元素的Pivot锚点位置
  13. 如何使用qtp检查网页中显示的文字颜色为指定的颜色
  14. 用python建云盘_超简单!基于Python搭建个人“云盘”
  15. win7 计算机不显示u盘启动不了,Win7系统下bios中找不到U盘启动项如何解决
  16. sparkui 界面地址_Spark UI界面原理
  17. oracle查询日期当天,oracle获取今天时间数据
  18. was compiled with optimization - stepping may behave oddly; variables may not be available.
  19. 直播服务器不能正常运行,解决人人商城互动直播通信服务无法通信问题
  20. 最短路径模板+解析——(FLoyd算法)

热门文章

  1. cmd 更新 pip版本指令
  2. 视频教程-Javascript DOM操作-JavaScript
  3. 前端学习从入门到高级全程记录之39 (PHP基础Ⅱ)
  4. matlab 将图片转为视频
  5. 基于php微信小程序购物商城 校园二手商品 图书鲜花商城 毕业设计(3)微信用户登录
  6. 通信-SCADA系统
  7. 消气机器人_星新一少年科幻·淘气的机器人最新章节_星新一著_掌阅小说网
  8. 看这你已经赢麻了,勿以赢小而不麻,2022软件测试八股文最全音
  9. mysql 编程 备份_mysql 容灾备份
  10. 深入 javascript 之 call函数 用法