TikZ从零开始(二)A Petri Net for Hagen_tikz rectangle-程序员宅基地

技术标签: latex  LaTeX  

0、前言

本教程翻译自TikZ官方文档,在这里我们学习节点(node)的绘制

1、问题陈述

要画一个这样的图
在这里插入图片描述

2、创建环境

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{arrows} 
\usetikzlibrary{decorations.pathmorphing} % 用于绘制图中心的蛇形线
\usetikzlibrary{backgrounds} % 用于绘制灰色背景
\usetikzlibrary{positioning} % 用于通过相对位置摆放节点
\usetikzlibrary{fit} % 可以容易地计算背景矩形的尺寸
\usetikzlibrary{petri}
\begin{document}
\begin{tikzpicture}
	\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{document}

3、节点引论

原则上来说,除了蛇形线,我们已经可以用上节知识画出这幅图了。但是那种方法有严重的弊端,就是如果之后要添加位置(places,指Petri Net中的圆圈),会很麻烦,所有坐标都要重新计算;另外,代码可读性会差,因为全是一些坐标,从而遗漏了Petri Net的一些内在结构信息。

幸运的是,TikZ可以用node来改善这种情况。我们在前节已经提到了node,现在我们深入学习它。node创建时,我们要提供位置信息与形状参数,node里还可以放一些文本。此外,node还可以被命名,以便后续引用。

在这里我们用node来实现places和transition(指图中的小矩形),就是说,这儿我们不用上节学到的circle和rectangle,而是用node来画他们。

\path ( 0,2) node [shape=circle,draw] {}
( 0,1) node [shape=circle,draw] {}
( 0,0) node [shape=circle,draw] {}
( 1,1) node [shape=rectangle,draw] {}
(-1,1) node [shape=rectangle,draw] {};

这代码是怎么运作的呢?\path创建了一个路径,先move到(0,2),然后画一个节点,这个节点形状是圆圈,并且指定了draw就是要画出来,{}说明不添加任何文本;然后move到(0,1),再画节点……注意在move时没有进行任何操作,如果要把连线画出来,一方面在{}后面加上--表示连线,另一方面要把命令改成\path[draw]或者\draw。(\drawnode[draw]两个draw是不一样的,前者是绘制路径,后者是绘制节点)。
在这里插入图片描述

4、用At语句放置节点

上面这么略显繁琐,因为加入了移动操作。实际上可以通过at来简化这个过程。at直接指定了放置的节点,这样就回避了节点定位“node紧跟在哪个后面,就以哪个为参考系”(详见上一节)这个规则了。

\path node at ( 0,2) [shape=circle,draw] {}
node at ( 0,1) [shape=circle,draw] {}
node at ( 0,0) [shape=circle,draw] {}
node at ( 1,1) [shape=rectangle,draw] {}
node at (-1,1) [shape=rectangle,draw] {};

这样就省略了move操作了,但还是有个路径path,其实可以更简洁,path也省了:

\node at ( 0,2) [circle,draw] {};
\node at ( 0,1) [circle,draw] {};
\node at ( 0,0) [circle,draw] {};
\node at ( 1,1) [rectangle,draw] {};
\node at (-1,1) [rectangle,draw] {};

与之前代码的不同:每一个画节点操作后面都加了分号、shape参数名省略了(像color shape这种不会引起歧义的参数名就可以省略)、\path命令省了。
在这里插入图片描述
P.S. 我发现这种语法画出的node时自带轮廓的,如果不想画轮廓,只想标注文字,则可以用\draw (1,1) node {2}这种语法,参见此篇博客第20节。

5、使用样式(Styles)

下面我们把这个图上色,让它更好看。

\node at ( 0,2) [circle,draw=blue!50,fill=blue!20] {};
\node at ( 0,1) [circle,draw=blue!50,fill=blue!20] {};
\node at ( 0,0) [circle,draw=blue!50,fill=blue!20] {};
\node at ( 1,1) [rectangle,draw=black!50,fill=black!20] {};
\node at (-1,1) [rectangle,draw=black!50,fill=black!20] {};

在这里插入图片描述
图倒是变好看了,但代码段变丑了,我们在这儿想清楚地表达由三个places两个transitions,不要看那么多颜色规定的语句。为此,我们可以预设样式。

[place/.style={circle,draw=blue!50,fill=blue!20},
transition/.style={rectangle,draw=black!50,fill=black!20}]
\node at ( 0,2) [place] {};
\node at ( 0,1) [place] {};
\node at ( 0,0) [place] {};
\node at ( 1,1) [transition] {};
\node at (-1,1) [transition] {};

6、节点大小

如果文本为空,TikZ自动给其设置一些空白,如果要改变大小,我们可以把空白设置大一些,通过inner sep参数。

[inner sep=2mm,
place/.style={circle,draw=blue!50,fill=blue!20,thick},
transition/.style={rectangle,draw=black!50,fill=black!20,thick}]
\node at ( 0,2) [place] {};
\node at ( 0,1) [place] {};
\node at ( 0,0) [place] {};
\node at ( 1,1) [transition] {};
\node at (-1,1) [transition] {};

在这里插入图片描述
但一个更好的方式是设定最小尺寸minimum size,有了最小尺寸,如果添加一些文本,节点会自动变大,如文本为空,则它为最小尺寸。通过minimum heightminimum width我们还可以设置最小高度和最小宽度。

[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=0pt,minimum size=4mm}]
\node at ( 0,2) [place] {};
\node at ( 0,1) [place] {};
\node at ( 0,0) [place] {};
\node at ( 1,1) [transition] {fffffffff};
\node at (-1,1) [transition] {};

在这里插入图片描述
文字有些太挤,可以通过调大transition的inner sep解决

[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=1pt,minimum size=4mm}]
\node at ( 0,2) [place] {};
\node at ( 0,1) [place] {};
\node at ( 0,0) [place] {};
\node at ( 1,1) [transition] {fffffffff};
\node at (-1,1) [transition] {};

在这里插入图片描述

7、命名节点

下面要添加箭头,但似乎很麻烦,因为箭头肯定不是从图形的中心开始画的,而是从圆圈和矩形边缘开始画的,要是还得计算坐标的话(比如圆心向右平移一个半径是哪个点),那可就麻烦了。
好在PGF可以自动帮我们做这些事,不过那样的话,我们得先命名节点。

命名节点有两种方式,一种是通过name=的选项,另一种是把命名放在圆括号里。这里我们介绍第二种。

\node[place] (waiting 1) at ( 0,2) {};
\node[place] (critical 1) at ( 0,1) {};
\node[place] (semaphore) at ( 0,0) {};
\node[transition] (leave critical) at ( 1,1) {};
\node[transition] (enter critical) at (-1,1) {};

为了更易读,把选项放在了紧跟\node的位置。名字随便定,可以包括下划线、连字符,只要没有逗号、句点、圆括号、冒号和其他一些特殊字符就行。

8、使用相对位置放置节点

在连接节点之前, 我们还要解决一个问题,就是节点的摆放问题。at语句很有用,但没法体现节点的相互关联,比如critical 1要在waiting 1 的下方,有不少方法来实现,比较好的是下面的below选项,通过positioning库来实现。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

在这里插入图片描述

9、在节点旁添加标注

连接节点前,我们先给底部的semaphore places添加 s ≤ 3 s\le 3 s3的capacity。
有两种方式。

  • 在semaphore节点的北部添加新节点(任何情况下均适用)。
[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=1pt,minimum size=4mm}]
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\node[red,above] at (semaphore.north) {$s\le 3$};

在这里插入图片描述

  • 使用标注选项,它是node的一个可选参数。
[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=1pt,minimum size=4mm}]
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:\textcolor{red}{$ s\le 3 $}] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

除了above,我们还可以设置位置为low left、60(代表极坐标里的60度)。

\node[circle,draw,label=below:$ -90^\circ $,label=60:$ 60^\circ $] {my circle};

在这里插入图片描述
为了把标注颜色变成红色,可以通过label=above:\textcolor{red}{text}来实现,也可以通过label={[red]above:text}来实现,还可以预设样式every label/.style={red},以下为预设样式的完整代码

[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=1pt,minimum size=4mm},
every label/.style={red}]
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

10、连接节点

终于要开始连接节点了,我们先从简单的开始,连接从enter critical到critical的线。为此,我们调用节点的锚(anchor),通过<node's name>.<anchor's name>来调用。

... % define styles
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\draw[->](enter critical.east)--(critical.west);

现在,让我们画从waiting到enter critical的曲线。通过<a> .. controls <b> and <c> .. <d>画弧来实现。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\draw[->] (enter critical.east)--(critical.west);
\draw[->] (waiting.west)..controls +(left:5mm) and +(up:5mm)..(enter critical.north);

这边+(left:5mm)+(up:5mm)都描述相对位置(从而定位切线),表示waiting.west左边5mm处,enter critical.north上方5mm处。在这里插入图片描述

这个代码可以优化,因为TikZ可以智能地帮助我们判断锚会在节点的哪一侧,从而我们可以把anchor略去。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\draw[->](enter critical)--(critical);
\draw[->](waiting)..controls+(left:5mm)and+(up:5mm)..(enter critical);

在这里插入图片描述
似乎弧线有点像直线了,可能TikZ还没那么智能,所以我选择给弧线代码保留anchor,直线省略之。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\draw[->](enter critical)--(critical);
\draw[->](waiting.west)..controls+(left:5mm)and+(up:5mm)..(enter critical.north);

在这里插入图片描述
弧线代码还可以做进一步优化,我们可以用to语句来代替control-and语句,并且通过指定出节点的切线角度和入节点的切线角度(均指与极轴的夹角,你可以想象一个单位圆,逆时针方向为正角)。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {};

\draw[->](enter critical)--(critical);
\draw[->](waiting.west) to[out=180,in=90] (enter critical.north);

在这里插入图片描述
这比control-and语句画出的更接近1/4圆弧,爱了。
还有一个bend rightbend left选项也可以用,但是我觉得它比较费解,我觉得right和left反了吧,明明是往左转,它却是bend right,明明是转90度,却是bend right=45。。

还有一种指定边的方式,就是edge语句,一般是紧跟在定义节点之后,随之给出它到其他节点的连线。
为了真正搞懂bend rightbend left参数,我用edge语句试了四个例子,我发现他画出来的弧线型状跟[->]还是[<-]没有任何关系

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {};
\node[transition] (enter critical) [left=of critical] {}
edge [->] (critical)
edge [bend left=45,red] (waiting)
edge [bend right=45,blue] (waiting)
edge [bend left=45,red] (semaphore)
edge [bend right=45,blue](semaphore);

在这里插入图片描述
我给出的解释是bend right还是bend left取决于从定义的节点和要达到的节点之间的连线段,从出节点的方向看,要是把线往左边掰就是bend left,反之就是bend right。但是对于to语句,我是真的没法解释,,,

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {}
edge [<-] (critical)
edge [<-,in=0,out=270] (semaphore)
edge [->,bend right=45] (waiting);
\node[transition] (enter critical) [left=of critical] {}
edge [->] (critical)
edge [<-,bend left=45] (waiting)
edge [->,bend right=45](semaphore);

注意:edge 语句里,[<-][->]不影响方向,只影响箭头(arrow tip)的位置,用in-out选项也不太正常,感觉要自己多试几个才能试出来,我不是很懂他的原理是什么了。
在这里插入图片描述
我们可以预设箭头连线的样式,预设掰弯角度为45度,通过prepost,注意,所有样式的代码要放在同一个方括号里。

[place/.style={circle,draw=blue!50,fill=blue!20,inner sep=0pt,minimum size=6mm},
transition/.style={rectangle,draw=black!50,fill=black!20,inner sep=1pt,minimum size=4mm},every label/.style={red},
bend angle=45,
pre/.style={<-,shorten <=1pt,>={Stealth[round]},semithick},
post/.style={->,shorten >=1pt,>={Stealth[round]},semithick}]
\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {}
edge [pre] (critical)
edge [pre,bend left] (semaphore)
edge [post,bend right] (waiting);
\node[transition] (enter critical) [left=of critical] {}
edge [post] (critical)
edge [pre,bend left] (waiting)
edge [post,bend right](semaphore);

还有一种比较好看的连线方法,不完全是弧线,是直线与弧线的结合。
\draw[post,rounded corners=5mm] (e1)|-(s);
在这里插入图片描述
还记得|-记号吗?我们在第一节指定坐标里学过,这里表示的是我先竖直画一条线,再水平画一条线。如果我不设置rounded corners就是方角,调大圆角半径可以使得转弯更smooth。当然了,也可以用-|那就是先水平画线再竖直画线。

11、给连线添加标注

在这里插入图片描述
在9种我们给节点旁边添加了标注,这里我们学习如何给连线添加标注。
当然我们可以手动添加节点,但是通过auto参数我们可以自动地把文本添加在连线旁边的位置而不是连线上;通过swap我们进行了镜像操作,因为默认是在内侧添加的。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {}
edge [pre] (critical)
edge [pre,bend left] (semaphore)
edge [post,bend right] node[auto,swap]{2} (waiting);
\node[transition] (enter critical) [left=of critical] {}
edge [post] (critical)
edge [pre,bend left] (waiting)
edge [post,bend right](semaphore);

在这里插入图片描述

12、添加蛇形线与多行文本

为此,我们需要在可选参数里面添加decoratedecoration=snake。这需要导入TikZ的decorations.pathmorphing库。
在这里插入图片描述这么画可不对劲,因为箭头看起来很糟糕,其实我们可以设定更多的参数。

\draw[->,decorate,decoration={snake,amplitude=.4mm,segment length=10mm,post length=1mm}] (0,0)--(2,0);
\draw[->,decorate,decoration={snake,amplitude=1mm,segment length=4mm,post length=1mm}] (0,-1)--(2,-1);
\draw[->,decorate,decoration={snake,amplitude=1mm,segment length=10mm,post length=1mm}] (0,-2)--(2,-2);
\draw[->,decorate,decoration={snake,amplitude=.4mm,segment length=10mm,post length=5mm}] (3,0)--(5,0);
\draw[->,decorate,decoration={snake,amplitude=1mm,segment length=4mm,post length=5mm}] (3,-1)--(5,-1);
\draw[->,decorate,decoration={snake,amplitude=1mm,segment length=10mm,post length=5mm}] (3,-2)--(5,-2);

amplitue指定振幅,segment length类似于周期长度,post length大概是arrow tip一端的直线段长度
在这里插入图片描述
下面是添加多行文本,有两种方法,在这两种方法中,我们都需要首先指定align=center(或者left right都行,但一定要指定对齐方式,否则无法换行)

  • 然后用\\强制换行。
\draw[->,decorate,decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}](0,0)--(3,0)node[above,midway,align=center]
{replacement of\\the capacity\\by two places};

因为我们已经制定了位置是midway,所以node放在语句的哪个位置无所谓。
在这里插入图片描述

  • 通过指定文本宽度来实现 TeX \TeX TEX自动换行。
\draw[->,decorate,decoration={snake,amplitude=.4mm,segment length=2mm,post length=1mm}](0,0)--(3,0)node[above,midway,align=center,text width=3cm]
{replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}};

在这里插入图片描述

13、使用图层:矩形背景

这有点棘手,我们必须在画完Petri Net之后再画矩形,因为画好之前我们并不知道我们画的Petri Net有多大。这可以通过TikZ的background库来实现。加载background库之后,我们就可以把图的一部分放在设置了on background layer选项的scope里。当tikzpicture环境结束时,图层依次往上叠放,首先叠放的就是背景层。

另一个棘手的问题是,如果确定背景矩形的尺寸呢?当然可以去手工计算横纵坐标,但更好的方式是让TikZ来算出一个适合(fit)所有节点的矩形。这就要导入fit库了,它定义了fit选项,当给到一个节点的时候,它会重新调整节点的尺寸、移动节点以使得所有节点都被背景所覆盖。

\node[place] (waiting) {};
\node[place] (critical) [below=of waiting] {};
\node[place] (semaphore) [below=of critical,
label=above:$ s\le 3 $] {};
\node[transition] (leave critical) [right=of critical] {}
edge [pre] (critical)
edge [pre,bend left] (semaphore)
edge [post,bend right] node[auto,swap]{2} (waiting);
\node[transition] (enter critical) [left=of critical] {}
edge [post] (critical)
edge [pre,bend left] (waiting)
edge [post,bend right](semaphore);

\begin{scope}[on background layer]
	\node [fill=black!30,fit=(waiting)(critical)(semaphore)(enter critical)(leave critical)] {};
\end{scope}

注意:node形状默认为矩形,所以可以不指定rectanglefit各节点放在用圆括号内,圆括号之间不能有除了空格以外的任何分隔符,记得在最后加上表示空文本的{}
在这里插入图片描述

14、完整代码

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{arrows.meta} 
\usetikzlibrary{decorations.pathmorphing} % 用于绘制图中心的蛇形线
\usetikzlibrary{backgrounds} % 用于绘制灰色背景
\usetikzlibrary{positioning} % 用于方便的确定节点位置
\usetikzlibrary{fit} % 可以容易地计算矩形尺寸
\usetikzlibrary{petri}
\begin{document}
	\begin{tikzpicture}
		[
		node distance=1.3cm,on grid,>={Stealth[round]},bend angle=45,auto,
		every place/.style={minimum size=6mm,thick,draw=blue!75,fill=blue!20},
		every transition/.style={thick,draw=black!75,fill=black!20},
		red place/.style= {place,draw=red!75,fill=red!20},
		every label/.style={red}
		]
		\node [place,tokens=1] (w1) {};
		\node [place] (c1) [below=of w1] {};
		\node [place] (s) [below=of c1,label=above:$s\le 3$] {};
		\node [place] (c2) [below=of s] {};
		\node [place,tokens=1] (w2) [below=of c2] {};
		\node [transition] (e1) [left=of c1] {}
		edge [pre,bend left] (w1)
		edge [post,bend right] (s)
		edge [post] (c1);
		\node [transition] (e2) [left=of c2] {}
		edge [pre,bend right] (w2)
		edge [post,bend left] (s)
		edge [post] (c2);
		\node [transition] (l1) [right=of c1] {}
		edge [pre] (c1)
		edge [pre,bend left] (s)
		edge [post,bend right] node[swap] {2} (w1);
		\node [transition] (l2) [right=of c2] {}
		edge [pre] (c2)
		edge [pre,bend right] (s)
		edge [post,bend left] node {2} (w2);
		
		\begin{scope}[xshift=6cm]
			\node [place,tokens=1] (w1') {};
			\node [place] (c1') [below=of w1'] {};
			\node [red place] (s1') [below=of c1',xshift=-5mm]
			[label=left:$s$] {};
			\node [red place,tokens=3] (s2') [below=of c1',xshift=5mm]
			[label=right:$\bar s$] {};
			\node [place] (c2') [below=of s1',xshift=5mm] {};
			\node [place,tokens=1] (w2') [below=of c2'] {};
			\node [transition] (e1') [left=of c1'] {}
			edge [pre,bend left] (w1')
			edge [post] (s1')
			edge [pre] (s2')
			edge [post] (c1');
			\node [transition] (e2') [left=of c2'] {}
			edge [pre,bend right] (w2')
			edge [post] (s1')
			edge [pre] (s2')
			edge [post] (c2');
			\node [transition] (l1') [right=of c1'] {}
			edge [pre] (c1')
			edge [pre] (s1')
			edge [post] (s2')
			edge [post,bend right] node[swap] {2} (w1');
			\node [transition] (l2') [right=of c2'] {}
			edge [pre] (c2')
			edge [pre] (s1')
			edge [post] (s2')
			edge [post,bend left] node {2} (w2');
		\end{scope}
		\begin{scope}[on background layer]
			\node (r1) [fill=black!10,rounded corners,fit=(w1)(w2)(e1)(e2)(l1)(l2)] {};
			\node (r2) [fill=black!10,rounded corners,fit=(w1')(w2')(e1')(e2')(l1')(l2')] {};
		\end{scope}
		\draw [->,shorten >=1mm,
		-to, % 用于加载下面的pre选项
		thick,decorate,
		decoration={snake,amplitude=.4mm,segment length=2mm,
			pre=moveto,
			pre length=1mm, %箭头始端的直线段长度
			post length=2mm}]
		(r1) -- (r2) node [above=1mm,midway,text width=3cm,align=center]
		{replacement of the \textcolor{red}{capacity} by \textcolor{red}{two places}};
	\end{tikzpicture}
\end{document}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jasminefeng/article/details/120920416

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf