diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..f578ba6 --- /dev/null +++ b/404.html @@ -0,0 +1,1481 @@ + + + + + + + + + + + + + + + + + + + + + + + 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + + + + +
+
+ + + +
+
+
+ + + + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..a39db5d --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +ckc-agc.bowling233.top \ No newline at end of file diff --git a/algebra/index.html b/algebra/index.html new file mode 100644 index 0000000..e33a39c --- /dev/null +++ b/algebra/index.html @@ -0,0 +1,574 @@ + + + + + + + + + + + + +线性代数辅学 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

线性代数辅学

+

欢迎来到竺院辅学线性代数版块🤗。你可以在左侧导航栏中详细浏览本模块的内容。

+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/analysis/2023/analysis1_review1.pdf b/analysis/2023/analysis1_review1.pdf new file mode 100644 index 0000000..0ed0242 Binary files /dev/null and b/analysis/2023/analysis1_review1.pdf differ diff --git a/analysis/2023/analysis1_review2.pdf b/analysis/2023/analysis1_review2.pdf new file mode 100644 index 0000000..2553914 Binary files /dev/null and b/analysis/2023/analysis1_review2.pdf differ diff --git a/analysis/2023/analysis1_review2_answer.pdf b/analysis/2023/analysis1_review2_answer.pdf new file mode 100644 index 0000000..6f8cd71 Binary files /dev/null and b/analysis/2023/analysis1_review2_answer.pdf differ diff --git a/analysis/2023/curves_surfaces_integrals.pdf b/analysis/2023/curves_surfaces_integrals.pdf new file mode 100644 index 0000000..4d01347 Binary files /dev/null and b/analysis/2023/curves_surfaces_integrals.pdf differ diff --git a/analysis/2023/indefinite_integral.pdf b/analysis/2023/indefinite_integral.pdf new file mode 100644 index 0000000..0f4a175 Binary files /dev/null and b/analysis/2023/indefinite_integral.pdf differ diff --git a/analysis/2023/index.html b/analysis/2023/index.html new file mode 100644 index 0000000..de35dc7 --- /dev/null +++ b/analysis/2023/index.html @@ -0,0 +1,604 @@ + + + + + + + + + + + + +2023 年辅学资料 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/analysis/2023/series.pdf b/analysis/2023/series.pdf new file mode 100644 index 0000000..79ddc49 Binary files /dev/null and b/analysis/2023/series.pdf differ diff --git a/analysis/2023/series_answer.pdf b/analysis/2023/series_answer.pdf new file mode 100644 index 0000000..e68bf83 Binary files /dev/null and b/analysis/2023/series_answer.pdf differ diff --git a/analysis/2024/analysis_lecture1_sequence_limits.pdf b/analysis/2024/analysis_lecture1_sequence_limits.pdf new file mode 100644 index 0000000..e9b2e71 Binary files /dev/null and b/analysis/2024/analysis_lecture1_sequence_limits.pdf differ diff --git a/analysis/2024/analysis_lecture1_sequence_limits/index.html b/analysis/2024/analysis_lecture1_sequence_limits/index.html new file mode 100644 index 0000000..7d7b5b9 --- /dev/null +++ b/analysis/2024/analysis_lecture1_sequence_limits/index.html @@ -0,0 +1,1060 @@ + + + + + + + + + + + + +第一讲 数列极限 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

第一讲 数列极限

+ +

实数完备性定理

+

要求

+
    +
  1. +

    给出概念、定理的名字可以使用数学语言准确叙述。

    +
  2. +
  3. +

    掌握基本的定理证明链(详细参考 1.4.1 1.4.2

    +
      +
    • +

      确界原理 \(\rightarrow\) 单调有界定理 \(\rightarrow\) 致密性定理 \(\rightarrow\)Cauchy 准则

      +
    • +
    • +

      单调有界定理 \(\rightarrow\) 闭区间套定理 \(\rightarrow\) 有限覆盖定理(聚点原理和 Dedekind 分割定理不要求)

      +
    • +
    • +

      确界原理 \(\rightarrow\) 各个定理

      +
    • +
    +
  4. +
  5. +

    期末考试会在这几个定理里出叙述题和证明题;小测会考各个定理的数学叙述细节。

    +
  6. +
+

概念叙述

+
    +
  1. +

    有界,无界

    +
    \[ +\begin{align} +数列有界: &\quad\forall n>0,\exists M\in \text{R},使|x_n|<M恒成立\\ +数列无界: &\quad\forall M\in \text{R},\exists n>0,使|x_n|>M \\ +错误(?): &\quad\exists n>0,\forall M\in \text{R},使x_n>M +\end{align} +\]
    +

    数学语言的否定:转换全称量词和存在量词,注意量词顺序,改变符号

    +
  2. +
  3. +

    最大数,最小数

    +
    \[ +\begin{align} +\max\{S\}=a &\iff a\in S且\forall x\in S,a\ge x\\ +\min\{S\}=b &\iff b\in S且\forall x\in S,b\le x +\end{align} +\]
    +
  4. +
  5. +

    上确界,下确界

    +
    \[ +\begin{align} +M=\sup\{S\}\iff& \forall x\in S,x\le M且\forall\epsilon>0,\exists x'\in S有x'>M-\epsilon\\ +m=\inf\{S\}\iff& \forall x\in S,x\ge m且\forall\epsilon>0,\exists x'\in S有x'<M+\epsilon +\end{align} +\]
    +
  6. +
+

定理叙述

+
    +
  1. +

    确界原理

    +

    非空有界集必有上下确界

    +
  2. +
  3. +

    单调有界定理

    +

    单调有界数列必收敛

    +
  4. +
  5. +

    致密性定理

    +

    任何有界数列必有收敛子列

    +
  6. +
  7. +

    Cauchy 准则

    +
    \[ +a_n收敛\iff\forall \epsilon>0,\exists N>0,\forall m,n>N,均有|a_m-a_n|<\epsilon \\ +\iff \forall \epsilon>0,\exists N>0,\forall n>N,p>0,均有|a_{n+p}-a_n|<\epsilon +\]
    +
  8. +
  9. +

    区间套定理

    +
    \[ +\begin{align} +& 设闭区间列\{[a_n,b_n]\}满足:\\ +& 1.[a_{n+1},b_{n+1}]\subset[a_n,b_n],n=1,2,3..\\ +& 2.\lim_{n\to\infty}(b_n-a_n)=0 \\ +& 则存在唯一实数\xi,满足\xi\in[a_n,b_n],n=1,2.. +\end{align} +\]
    +
  10. +
  11. +

    有限覆盖定理

    +
    \[ +\begin{align} +& 设[a,b]是一个闭区间,\{E_\lambda\}_{\lambda\in\Lambda}是[a,b]的任意一个开覆盖,\\ +& 则必存在\{E_\lambda\}_{\lambda\in\Lambda}的一个子集构成[a,b]的一个有限覆盖。 \\ +\iff & 在\{E_\lambda\}_{\lambda\in\Lambda}必有有限个开区间E_1,E_2..E_N使[a,b]\subset\cup_{j=1}^NE_j +\end{align} +\]
    +
  12. +
+

常用技巧

+
    +
  1. +

    证明集合相等的常用方法:相互包含

    + +
    +

    例题:确界的关系式

    +

    \(A,B\) 是两个由非负数组成的任意数集 , 试证明 \(\sup_{x\in A}\{x\}\cdot \sup_{y\in B}\{y\}=\sup_{x\in A,y\in B}\{xy\}\)

    +
    + +
  2. +
  3. +

    对于实数完备性定理的证明题,首先将给的条件和证明内容均翻译成数学语言(方便骗分,再观察条件和证明内容的联系。

    +
  4. +
+

例题 & 习题

+
    +
  1. 用确界原理证明单调有界原理、致密性定理、Cauchy 准则、闭区间套定理、有限覆盖定理。
  2. +
  3. 用单调有界定理证明闭区间套定理,用闭区间套定理证明有限覆盖定理;用致密性定理证明 Cauchy 收敛准则。
  4. +
  5. \(f,g为D上有界函数,\text{pf:}\inf\{f(x)+g(x)\}\le\inf{f(x)}+\sup{g(x)}\)
  6. +
  7. \(f(x)在[0,1]上递增,f(0)>0,f(1)<1,求证:\exists x_0\in(0,1),使得f(x_0)=x_0^2\) (Hint: 确界原理 or 区间套定理 )
  8. +
  9. \(f(x)\) \([a,b]\) 上有定义且在每一点处函数的极限存在,求证 \(f(x)\) \([a,b]\) 上有界 (Hint: 有限覆盖 )
  10. +
  11. \(设f(x)在(a,b)内有定义,\forall\xi\in(a,b),\exists\delta>0,当x\in(\xi-\delta,\xi+\delta)\cap(a,b)时,\) 有当 \(x<\xi\) ,\(f(x)<f(\xi), 当x>\xi\) ,\(f(x)>f(\xi)\). 请证明 :\(f(x)在(a,b)\) 内严格递增 (Hint: 有限覆盖 )
  12. +
+

数列极限

+

要求

+
    +
  1. 从小测的角度来说,概念,定理以及判断题是比较重要(搞脑子)的,当然也会有计算题
  2. +
  3. 期末考试可能会出 1-2 道求极限,1 道非常简单的极限证明题(附在定理叙述上)
  4. +
  5. 计算也需要掌握,但是技巧性强的可以不掌握
  6. +
  7. 学好数列极限对函数极限和级数都很有帮助,而学好了函数极限就可以学好导数和积分,然后你就学会了数分 1
  8. +
+

概念叙述

+
    +
  1. 数列极限(\(\epsilon-N\) 语言)
  2. +
+
\[ +\forall\epsilon>0,\exists N>0,\forall n>N,|x_n-A|<\epsilon称\lim_{x\rightarrow\infty}x_n=A\\ + *:|x_n-A|<f(\epsilon),f(x)满足\lim _{x\rightarrow0}f(x)=0即可 +\]
+
    +
  1. 数列发散
  2. +
+
\[ +\forall A\in R,\exists\epsilon_0>0,\forall N>0,\exists n_N>N,|x_n-A|\ge\epsilon_0 +\]
+
    +
  1. +

    子列

    +
    \[ +\{a_n\}收敛\iff \{a_n\}的任意子列都收敛于A(请注意减弱命题) +\]
    +
  2. +
  3. +

    无穷小量和无穷大量

    +
    \[ +\begin{align} +& 无穷小量 : \lim_{x\rightarrow\infty}= 0 \\ +& 无穷大量 : \forall M>0,\exists N,\forall n>N,|x_n|>M +\end{align} +\]
    +
  4. +
+

定理叙述

+
    +
  1. +

    Stolz 定理

    +

    常用于计算形式需要洛必达的极限

    +
  2. +
  3. +

    Cauchy 收敛准则、等价形式及否定

    +
  4. +
+
\[ +\begin{align} + a_n收敛& \iff\forall \epsilon>0,\exists N>0,\forall m,n>N,均有|a_m-a_n|<\epsilon \\ + & \iff \forall \epsilon>0,\exists N>0,\forall n>N,p>0,均有|a_{n+p}-a_n|<\epsilon \\ + 否定形式:a_n发散& \iff\exists\epsilon_0>0,\forall N,\exists n_0>N,p>0,|x_{n_0+p}-x_{n_0}|\ge\epsilon_0 + \end{align} +\]
+

常用技巧

+
    +
  1. +

    一些关系链:

    +
      +
    1. \(n\rightarrow\infty时\)
    2. +
    +
    \[ + \log\log n\ll \log n \ll n^a\ll b^n\ll n!\ll n^n\quad(a,b>0) +\]
    +
      +
    1. \(x\rightarrow0时\)
    2. +
    +
    \[ +\begin{align} + x \sim &\sin x\sim \tan x \sim \arcsin x\sim \arctan x \\ + \sim &\ln{(1+x)} \sim \text{e}^x-1 \sim \frac{a^x-1}{\ln a}\sim \frac{(1+x)^b-1}b \quad(a>0,b\neq0)\\ + & 1-\cos x \sim \frac12 x^2 + \end{align} +\]
    +
  2. +
  3. +

    证明数列极限存在:

    +
      +
    1. 定义(\(\epsilon-N\) 方法)
    2. +
    +

    技巧:放大法 ( 常用 )/ 分步法 / 构造形式类似的项 / 拟合法 ( 技巧性较强 )

    +
      +
    1. +

      Cauchy 准则:不需要知道极限值

      +
    2. +
    3. +

      Cauchy 准则的推论:常用于判断数项级数是否收敛 (\(a_n=\sum_{n=1}^{\infty}f(n)\))

      +
    4. +
    5. +

      单调有界原理:不动点,递推式考虑

      +
    6. +
    7. +

      极限的运算性质:本身存在极限 有限项运算

      +
    8. +
    +
  4. +
  5. +

    证明数列极限不存在:

    +
      +
    1. Cauchy 命题的否定形式
    2. +
    3. 子列不收敛或收敛于不同的数
    4. +
    +
  6. +
  7. +

    求数列 ( 函数 ) 极限:

    +
      +
    1. 极限的运算性质
    2. +
    +

    一些重要极限:\(\lim\limits_{n\rightarrow\infty}n^\frac1n=1\)\(\lim\limits_{n\rightarrow\infty}(1+\frac1n)^n=e\)

    +
      +
    1. +

      Stolz 定理

      +
    2. +
    3. +

      夹逼定理

      +
    4. +
    5. +

      等价代换与初等变形

      +
    6. +
    7. +

      递推形式的极限:单调有界原理 + 证明 / 压缩映像 ( 略难 )/Stolz 公式的应用

      +
    8. +
    9. +

      Taylor/L'Hospital/ 积分定义 / 数项级数 / 级数的连续性 ...: +很重要,但这是后事了

      +
    10. +
    +
  8. +
+

例题 & 习题

+
    +
  1. +

    判断下列关于子列的命题

    +
      +
    1. \(\{a_n\}\) 是一个数列,若在任一子列 \(\{a_{n_k}\}\) 中均存在收敛子列 \(\(\{a_{n_{k_r}}\}\)\), \(\(\{a_n\}\)\) 必收敛
    2. +
    3. \(\{a_n\}单调递增,\{a_{n_k}\}为其中一个子列,\lim\limits_{k\rightarrow\infty}a_{n_k}=a,则\lim\limits_{n\rightarrow\infty}{a_n}=a\)
    4. +
    5. \(\{a_{2k}\}\{a_{2p+1}\}\{a_{2023t+2024}\}均收敛,则\{a_n\}收敛\)
    6. +
    7. \(\{a_{2k}\}\{a_{2t+1}\}\{a_{6p+5}\}均收敛,则\{a_n\}收敛\)
    8. +
    +
  2. +
  3. +

    判断下列关于无穷小量的命题

    +
      +
    1. 无穷多个无穷小量之和是无穷小量
    2. +
    3. 无穷多个无穷小量之积是无穷小量
    4. +
    5. 无穷小量与有界量之积为无穷小量
    6. +
    +
  4. +
  5. +

    判断下列关于数列极限的命题

    +
      +
    1. 数列 \(a_n\) 收敛 \(\iff \forall p\in N,\lim\limits_{n\rightarrow+\infty}{|a_{n+p}-a_n|=0}\)
    2. +
    3. \(\lim\limits_{n\rightarrow\infty}x_n=A\iff\forall k\in \text{N},\exists N>0,\forall n>N,|x_n-A|<\frac1k\)
    4. +
    5. \(a_n收敛 \iff \exists N>0,\forall \epsilon>0,\forall m,n>N,均有|a_m-a_n|<\epsilon\)
    6. +
    +
  6. +
  7. +

    重要的二级结论:

    +
  8. +
+
\[ +Cauchy定理:\lim_{n\rightarrow\infty}x_n=A,则\lim_{n\rightarrow\infty}\frac{x_1+x_2+...+x_n}{n}=A +\]
+
    +
  1. +

    \(x_n=\sum_{i=1}^n\sin(\frac{2i-1}{n^2}a),\text{pf:}\lim\limits_{n\rightarrow\infty}x_n=a\) (Hint: 拟合法 )

    +
  2. +
  3. +

    求极限 \(\lim\limits_{n\rightarrow\infty}x_n\)

    +
      +
    1. \(x_n=\cos\frac x2\cos\frac x{2^2}\cdots\cos\frac x{2^n}\)
    2. +
    3. \(x_n=(\frac{\sqrt[n]a+\sqrt[n]b}{2})^n\)
    4. +
    5. \(x_n=\frac 1{\sqrt[n]{n!}}\)
    6. +
    7. \(x_n={(n!)}^{\frac1{n^2}}\)
    8. +
    9. \(x_n=\sqrt[6]{x^6+x^5}-\sqrt[6]{x^6-x^5}\)
    10. +
    +
  4. +
  5. +

    (2019(?) 年数分 1 期末 )

    +
  6. +
+
\[ +\begin{align} + & 对于数列x_0=a,0<a<\frac\pi2,x_n=\sin x_{n-1}(n=1,2,\cdots). \\ &\text{pf:}(1)\lim\limits_{n\rightarrow\infty}x_n=0;(2)\lim\limits_{n\rightarrow\infty}{\sqrt\frac n3}x_n=1 + \end{align} +\]
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/analysis/analysis1_paper/20exam.pdf b/analysis/analysis1_paper/20exam.pdf new file mode 100644 index 0000000..7f389cb Binary files /dev/null and b/analysis/analysis1_paper/20exam.pdf differ diff --git a/analysis/analysis1_paper/21exam.pdf b/analysis/analysis1_paper/21exam.pdf new file mode 100644 index 0000000..03116fa Binary files /dev/null and b/analysis/analysis1_paper/21exam.pdf differ diff --git a/analysis/analysis1_paper/21exam_answer.pdf b/analysis/analysis1_paper/21exam_answer.pdf new file mode 100644 index 0000000..69822b2 Binary files /dev/null and b/analysis/analysis1_paper/21exam_answer.pdf differ diff --git a/analysis/analysis1_paper/21test.pdf b/analysis/analysis1_paper/21test.pdf new file mode 100644 index 0000000..03e19a6 Binary files /dev/null and b/analysis/analysis1_paper/21test.pdf differ diff --git a/analysis/analysis1_paper/21test_answer.pdf b/analysis/analysis1_paper/21test_answer.pdf new file mode 100644 index 0000000..ed330fe Binary files /dev/null and b/analysis/analysis1_paper/21test_answer.pdf differ diff --git a/analysis/analysis1_paper/22exam.pdf b/analysis/analysis1_paper/22exam.pdf new file mode 100644 index 0000000..d338b70 Binary files /dev/null and b/analysis/analysis1_paper/22exam.pdf differ diff --git a/analysis/analysis1_paper/22test1.pdf b/analysis/analysis1_paper/22test1.pdf new file mode 100644 index 0000000..c366944 Binary files /dev/null and b/analysis/analysis1_paper/22test1.pdf differ diff --git a/analysis/analysis1_paper/22test2.pdf b/analysis/analysis1_paper/22test2.pdf new file mode 100644 index 0000000..7f24046 Binary files /dev/null and b/analysis/analysis1_paper/22test2.pdf differ diff --git a/analysis/analysis2_paper/20exam.pdf b/analysis/analysis2_paper/20exam.pdf new file mode 100644 index 0000000..14e9145 Binary files /dev/null and b/analysis/analysis2_paper/20exam.pdf differ diff --git a/analysis/analysis2_paper/21exam.pdf b/analysis/analysis2_paper/21exam.pdf new file mode 100644 index 0000000..405e859 Binary files /dev/null and b/analysis/analysis2_paper/21exam.pdf differ diff --git a/analysis/analysis2_paper/21exam_answer.pdf b/analysis/analysis2_paper/21exam_answer.pdf new file mode 100644 index 0000000..c53151e Binary files /dev/null and b/analysis/analysis2_paper/21exam_answer.pdf differ diff --git a/analysis/analysis2_paper/22exam.pdf b/analysis/analysis2_paper/22exam.pdf new file mode 100644 index 0000000..dad2ab5 Binary files /dev/null and b/analysis/analysis2_paper/22exam.pdf differ diff --git a/analysis/analysis2_paper/22exam_answer.pdf b/analysis/analysis2_paper/22exam_answer.pdf new file mode 100644 index 0000000..58cc34b Binary files /dev/null and b/analysis/analysis2_paper/22exam_answer.pdf differ diff --git a/analysis/analysis2_paper/22test1.pdf b/analysis/analysis2_paper/22test1.pdf new file mode 100644 index 0000000..e6669d7 Binary files /dev/null and b/analysis/analysis2_paper/22test1.pdf differ diff --git a/analysis/analysis2_paper/22test1_answer.pdf b/analysis/analysis2_paper/22test1_answer.pdf new file mode 100644 index 0000000..cdad716 Binary files /dev/null and b/analysis/analysis2_paper/22test1_answer.pdf differ diff --git a/analysis/analysis2_paper/22test2.pdf b/analysis/analysis2_paper/22test2.pdf new file mode 100644 index 0000000..43fb206 Binary files /dev/null and b/analysis/analysis2_paper/22test2.pdf differ diff --git a/analysis/analysis2_paper/22test2_answer.pdf b/analysis/analysis2_paper/22test2_answer.pdf new file mode 100644 index 0000000..1a2cd0e Binary files /dev/null and b/analysis/analysis2_paper/22test2_answer.pdf differ diff --git a/analysis/analysis2_paper/unknow_test_answer.pdf b/analysis/analysis2_paper/unknow_test_answer.pdf new file mode 100644 index 0000000..db5812a Binary files /dev/null and b/analysis/analysis2_paper/unknow_test_answer.pdf differ diff --git a/analysis/exam/index.html b/analysis/exam/index.html new file mode 100644 index 0000000..dcc684a --- /dev/null +++ b/analysis/exam/index.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + +历年卷整理 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

数学分析 I/II(H)历年卷整理

+

数学分析 I(H)

+ +

数学分析 II(H)

+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/analysis/index.html b/analysis/index.html new file mode 100644 index 0000000..72e9580 --- /dev/null +++ b/analysis/index.html @@ -0,0 +1,618 @@ + + + + + + + + + + + + +数学分析辅学 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.aecac24b.min.js b/assets/javascripts/bundle.aecac24b.min.js new file mode 100644 index 0000000..464603d --- /dev/null +++ b/assets/javascripts/bundle.aecac24b.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var wi=Object.create;var ur=Object.defineProperty;var Si=Object.getOwnPropertyDescriptor;var Ti=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Oi=Object.getPrototypeOf,dr=Object.prototype.hasOwnProperty,Zr=Object.prototype.propertyIsEnumerable;var Xr=(e,t,r)=>t in e?ur(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,R=(e,t)=>{for(var r in t||(t={}))dr.call(t,r)&&Xr(e,r,t[r]);if(kt)for(var r of kt(t))Zr.call(t,r)&&Xr(e,r,t[r]);return e};var eo=(e,t)=>{var r={};for(var o in e)dr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&kt)for(var o of kt(e))t.indexOf(o)<0&&Zr.call(e,o)&&(r[o]=e[o]);return r};var hr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Mi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ti(t))!dr.call(e,n)&&n!==r&&ur(e,n,{get:()=>t[n],enumerable:!(o=Si(t,n))||o.enumerable});return e};var Ht=(e,t,r)=>(r=e!=null?wi(Oi(e)):{},Mi(t||!e||!e.__esModule?ur(r,"default",{value:e,enumerable:!0}):r,e));var ro=hr((br,to)=>{(function(e,t){typeof br=="object"&&typeof to!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(br,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var it=C.type,Ne=C.tagName;return!!(Ne==="INPUT"&&s[it]&&!C.readOnly||Ne==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function d(C){a(C.target)&&(o||c(C.target))&&p(C.target)}function v(C){a(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function b(C){document.visibilityState==="hidden"&&(n&&(o=!0),z())}function z(){document.addEventListener("mousemove",G),document.addEventListener("mousedown",G),document.addEventListener("mouseup",G),document.addEventListener("pointermove",G),document.addEventListener("pointerdown",G),document.addEventListener("pointerup",G),document.addEventListener("touchmove",G),document.addEventListener("touchstart",G),document.addEventListener("touchend",G)}function K(){document.removeEventListener("mousemove",G),document.removeEventListener("mousedown",G),document.removeEventListener("mouseup",G),document.removeEventListener("pointermove",G),document.removeEventListener("pointerdown",G),document.removeEventListener("pointerup",G),document.removeEventListener("touchmove",G),document.removeEventListener("touchstart",G),document.removeEventListener("touchend",G)}function G(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,K())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",b,!0),z(),r.addEventListener("focus",d,!0),r.addEventListener("blur",v,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var Vr=hr((Ot,Dr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Ot=="object"&&typeof Dr=="object"?Dr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Ot=="object"?Ot.ClipboardJS=r():t.ClipboardJS=r()})(Ot,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Ei}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(U){try{return document.execCommand(U)}catch(O){return!1}}var d=function(O){var S=f()(O);return u("cut"),S},v=d;function b(U){var O=document.documentElement.getAttribute("dir")==="rtl",S=document.createElement("textarea");S.style.fontSize="12pt",S.style.border="0",S.style.padding="0",S.style.margin="0",S.style.position="absolute",S.style[O?"right":"left"]="-9999px";var $=window.pageYOffset||document.documentElement.scrollTop;return S.style.top="".concat($,"px"),S.setAttribute("readonly",""),S.value=U,S}var z=function(O,S){var $=b(O);S.container.appendChild($);var F=f()($);return u("copy"),$.remove(),F},K=function(O){var S=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},$="";return typeof O=="string"?$=z(O,S):O instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(O==null?void 0:O.type)?$=z(O.value,S):($=f()(O),u("copy")),$},G=K;function C(U){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(S){return typeof S}:C=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},C(U)}var it=function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},S=O.action,$=S===void 0?"copy":S,F=O.container,Q=O.target,_e=O.text;if($!=="copy"&&$!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(Q!==void 0)if(Q&&C(Q)==="object"&&Q.nodeType===1){if($==="copy"&&Q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if($==="cut"&&(Q.hasAttribute("readonly")||Q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(_e)return G(_e,{container:F});if(Q)return $==="cut"?v(Q):G(Q,{container:F})},Ne=it;function Pe(U){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(S){return typeof S}:Pe=function(S){return S&&typeof Symbol=="function"&&S.constructor===Symbol&&S!==Symbol.prototype?"symbol":typeof S},Pe(U)}function ui(U,O){if(!(U instanceof O))throw new TypeError("Cannot call a class as a function")}function Jr(U,O){for(var S=0;S0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof F.action=="function"?F.action:this.defaultAction,this.target=typeof F.target=="function"?F.target:this.defaultTarget,this.text=typeof F.text=="function"?F.text:this.defaultText,this.container=Pe(F.container)==="object"?F.container:document.body}},{key:"listenClick",value:function(F){var Q=this;this.listener=p()(F,"click",function(_e){return Q.onClick(_e)})}},{key:"onClick",value:function(F){var Q=F.delegateTarget||F.currentTarget,_e=this.action(Q)||"copy",Ct=Ne({action:_e,container:this.container,target:this.target(Q),text:this.text(Q)});this.emit(Ct?"success":"error",{action:_e,text:Ct,trigger:Q,clearSelection:function(){Q&&Q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(F){return fr("action",F)}},{key:"defaultTarget",value:function(F){var Q=fr("target",F);if(Q)return document.querySelector(Q)}},{key:"defaultText",value:function(F){return fr("text",F)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(F){var Q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return G(F,Q)}},{key:"cut",value:function(F){return v(F)}},{key:"isSupported",value:function(){var F=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],Q=typeof F=="string"?[F]:F,_e=!!document.queryCommandSupported;return Q.forEach(function(Ct){_e=_e&&!!document.queryCommandSupported(Ct)}),_e}}]),S}(a()),Ei=yi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,d,v){var b=p.apply(this,arguments);return l.addEventListener(u,b,v),{destroy:function(){l.removeEventListener(u,b,v)}}}function c(l,f,u,d,v){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(b){return a(b,f,u,d,v)}))}function p(l,f,u,d){return function(v){v.delegateTarget=s(v.target,f),v.delegateTarget&&d.call(l,v)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,d,v){if(!u&&!d&&!v)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(v))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,d,v);if(s.nodeList(u))return l(u,d,v);if(s.string(u))return f(u,d,v);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,d,v){return u.addEventListener(d,v),{destroy:function(){u.removeEventListener(d,v)}}}function l(u,d,v){return Array.prototype.forEach.call(u,function(b){b.addEventListener(d,v)}),{destroy:function(){Array.prototype.forEach.call(u,function(b){b.removeEventListener(d,v)})}}}function f(u,d,v){return a(document.body,u,d,v)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Ha=/["'&<>]/;Un.exports=$a;function $a(e){var t=""+e,r=Ha.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function N(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,d)})})}function a(u,d){try{c(o[u](d))}catch(v){f(i[0][3],v)}}function c(u){u.value instanceof Ze?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,d){u(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function io(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof we=="function"?we(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function k(e){return typeof e=="function"}function at(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Rt=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function De(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=we(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(b){t={error:b}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(b){i=b instanceof Rt?b.errors:[b]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=we(f),d=u.next();!d.done;d=u.next()){var v=d.value;try{ao(v)}catch(b){i=i!=null?i:[],b instanceof Rt?i=D(D([],N(i)),N(b.errors)):i.push(b)}}}catch(b){o={error:b}}finally{try{d&&!d.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Rt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ao(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&De(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&De(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var gr=Ie.EMPTY;function Pt(e){return e instanceof Ie||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function ao(e){k(e)?e():e.unsubscribe()}var Ae={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?gr:(this.currentObservers=null,a.push(r),new Ie(function(){o.currentObservers=null,De(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new P;return r.source=this,r},t.create=function(r,o){return new ho(r,o)},t}(P);var ho=function(e){ie(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:gr},t}(x);var yt={now:function(){return(yt.delegate||Date).now()},delegate:void 0};var Et=function(e){ie(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=yt);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=lt.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(lt.cancelAnimationFrame(o),r._scheduled=void 0)},t}(jt);var go=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(Wt);var Oe=new go(vo);var L=new P(function(e){return e.complete()});function Ut(e){return e&&k(e.schedule)}function Or(e){return e[e.length-1]}function Qe(e){return k(Or(e))?e.pop():void 0}function Me(e){return Ut(Or(e))?e.pop():void 0}function Nt(e,t){return typeof Or(e)=="number"?e.pop():t}var mt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Dt(e){return k(e==null?void 0:e.then)}function Vt(e){return k(e[pt])}function zt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function qt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Pi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Kt=Pi();function Qt(e){return k(e==null?void 0:e[Kt])}function Yt(e){return no(this,arguments,function(){var r,o,n,i;return $t(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,Ze(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,Ze(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,Ze(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return k(e==null?void 0:e.getReader)}function I(e){if(e instanceof P)return e;if(e!=null){if(Vt(e))return Ii(e);if(mt(e))return Fi(e);if(Dt(e))return ji(e);if(zt(e))return xo(e);if(Qt(e))return Wi(e);if(Bt(e))return Ui(e)}throw qt(e)}function Ii(e){return new P(function(t){var r=e[pt]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Fi(e){return new P(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?M(function(n,i){return e(n,i,o)}):ue,xe(1),r?He(t):Io(function(){return new Jt}))}}function Fo(){for(var e=[],t=0;t=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,d=0,v=!1,b=!1,z=function(){f==null||f.unsubscribe(),f=void 0},K=function(){z(),l=u=void 0,v=b=!1},G=function(){var C=l;K(),C==null||C.unsubscribe()};return g(function(C,it){d++,!b&&!v&&z();var Ne=u=u!=null?u:r();it.add(function(){d--,d===0&&!b&&!v&&(f=Hr(G,c))}),Ne.subscribe(it),!l&&d>0&&(l=new tt({next:function(Pe){return Ne.next(Pe)},error:function(Pe){b=!0,z(),f=Hr(K,n,Pe),Ne.error(Pe)},complete:function(){v=!0,z(),f=Hr(K,s),Ne.complete()}}),I(C).subscribe(l))})(p)}}function Hr(e,t){for(var r=[],o=2;oe.next(document)),e}function q(e,t=document){return Array.from(t.querySelectorAll(e))}function W(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function Re(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}var na=_(h(document.body,"focusin"),h(document.body,"focusout")).pipe(ke(1),V(void 0),m(()=>Re()||document.body),J(1));function Zt(e){return na.pipe(m(t=>e.contains(t)),X())}function Je(e){return{x:e.offsetLeft,y:e.offsetTop}}function No(e){return _(h(window,"load"),h(window,"resize")).pipe(Ce(0,Oe),m(()=>Je(e)),V(Je(e)))}function er(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return _(h(e,"scroll"),h(window,"resize")).pipe(Ce(0,Oe),m(()=>er(e)),V(er(e)))}function Do(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)Do(e,r)}function T(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)Do(o,n);return o}function tr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function ht(e){let t=T("script",{src:e});return H(()=>(document.head.appendChild(t),_(h(t,"load"),h(t,"error").pipe(E(()=>Mr(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),A(()=>document.head.removeChild(t)),xe(1))))}var Vo=new x,ia=H(()=>typeof ResizeObserver=="undefined"?ht("https://unpkg.com/resize-observer-polyfill"):j(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Vo.next(t)})),E(e=>_(Ve,j(e)).pipe(A(()=>e.disconnect()))),J(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return ia.pipe(w(t=>t.observe(e)),E(t=>Vo.pipe(M(({target:r})=>r===e),A(()=>t.unobserve(e)),m(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function zo(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var qo=new x,aa=H(()=>j(new IntersectionObserver(e=>{for(let t of e)qo.next(t)},{threshold:0}))).pipe(E(e=>_(Ve,j(e)).pipe(A(()=>e.disconnect()))),J(1));function rr(e){return aa.pipe(w(t=>t.observe(e)),E(t=>qo.pipe(M(({target:r})=>r===e),A(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Ko(e,t=16){return dt(e).pipe(m(({y:r})=>{let o=he(e),n=bt(e);return r>=n.height-o.height-t}),X())}var or={drawer:W("[data-md-toggle=drawer]"),search:W("[data-md-toggle=search]")};function Qo(e){return or[e].checked}function Ke(e,t){or[e].checked!==t&&or[e].click()}function We(e){let t=or[e];return h(t,"change").pipe(m(()=>t.checked),V(t.checked))}function sa(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function ca(){return _(h(window,"compositionstart").pipe(m(()=>!0)),h(window,"compositionend").pipe(m(()=>!1))).pipe(V(!1))}function Yo(){let e=h(window,"keydown").pipe(M(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:Qo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),M(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!sa(o,r)}return!0}),le());return ca().pipe(E(t=>t?L:e))}function pe(){return new URL(location.href)}function ot(e,t=!1){if(te("navigation.instant")&&!t){let r=T("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Bo(){return new x}function Go(){return location.hash.slice(1)}function nr(e){let t=T("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function pa(e){return _(h(window,"hashchange"),e).pipe(m(Go),V(Go()),M(t=>t.length>0),J(1))}function Jo(e){return pa(e).pipe(m(t=>ce(`[id="${t}"]`)),M(t=>typeof t!="undefined"))}function Fr(e){let t=matchMedia(e);return Xt(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function Xo(){let e=matchMedia("print");return _(h(window,"beforeprint").pipe(m(()=>!0)),h(window,"afterprint").pipe(m(()=>!1))).pipe(V(e.matches))}function jr(e,t){return e.pipe(E(r=>r?t():L))}function ir(e,t){return new P(r=>{let o=new XMLHttpRequest;o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network Error"))}),o.addEventListener("abort",()=>{r.error(new Error("Request aborted"))}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{t.progress$.next(n.loaded/n.total*100)}),t.progress$.next(5)),o.send()})}function Ue(e,t){return ir(e,t).pipe(E(r=>r.text()),m(r=>JSON.parse(r)),J(1))}function Zo(e,t){let r=new DOMParser;return ir(e,t).pipe(E(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),J(1))}function en(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function tn(){return _(h(window,"scroll",{passive:!0}),h(window,"resize",{passive:!0})).pipe(m(en),V(en()))}function rn(){return{width:innerWidth,height:innerHeight}}function on(){return h(window,"resize",{passive:!0}).pipe(m(rn),V(rn()))}function nn(){return B([tn(),on()]).pipe(m(([e,t])=>({offset:e,size:t})),J(1))}function ar(e,{viewport$:t,header$:r}){let o=t.pipe(ee("size")),n=B([o,r]).pipe(m(()=>Je(e)));return B([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function la(e){return h(e,"message",t=>t.data)}function ma(e){let t=new x;return t.subscribe(r=>e.postMessage(r)),t}function an(e,t=new Worker(e)){let r=la(t),o=ma(t),n=new x;n.subscribe(o);let i=o.pipe(Z(),re(!0));return n.pipe(Z(),qe(r.pipe(Y(i))),le())}var fa=W("#__config"),vt=JSON.parse(fa.textContent);vt.base=`${new URL(vt.base,pe())}`;function me(){return vt}function te(e){return vt.features.includes(e)}function be(e,t){return typeof t!="undefined"?vt.translations[e].replace("#",t.toString()):vt.translations[e]}function Ee(e,t=document){return W(`[data-md-component=${e}]`,t)}function oe(e,t=document){return q(`[data-md-component=${e}]`,t)}function ua(e){let t=W(".md-typeset > :first-child",e);return h(t,"click",{once:!0}).pipe(m(()=>W(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function sn(e){if(!te("announce.dismiss")||!e.childElementCount)return L;if(!e.hidden){let t=W(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new x;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),ua(e).pipe(w(r=>t.next(r)),A(()=>t.complete()),m(r=>R({ref:e},r)))})}function da(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function cn(e,t){let r=new x;return r.subscribe(({hidden:o})=>{e.hidden=o}),da(e,t).pipe(w(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))}function ha(e,t){let r=H(()=>B([No(e),dt(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=he(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return Zt(e).pipe(E(o=>r.pipe(m(n=>({active:o,offset:n})),xe(+!o||1/0))))}function pn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new x,s=i.pipe(Z(),re(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),rr(e).pipe(Y(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),_(i.pipe(M(({active:a})=>a)),i.pipe(ke(250),M(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Ce(16,Oe)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(Pr(125,Oe),M(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),h(n,"click").pipe(Y(s),M(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),h(n,"mousedown").pipe(Y(s),ne(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Re())==null||p.blur()}}),r.pipe(Y(s),M(a=>a===o),ze(125)).subscribe(()=>e.focus()),ha(e,t).pipe(w(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))})}function Wr(e){return T("div",{class:"md-tooltip",id:e},T("div",{class:"md-tooltip__inner md-typeset"}))}function ln(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return T("aside",{class:"md-annotation",tabIndex:0},Wr(t),T("a",{href:r,class:"md-annotation__index",tabIndex:-1},T("span",{"data-md-annotation-id":e})))}else return T("aside",{class:"md-annotation",tabIndex:0},Wr(t),T("span",{class:"md-annotation__index",tabIndex:-1},T("span",{"data-md-annotation-id":e})))}function mn(e){return T("button",{class:"md-clipboard md-icon",title:be("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Ur(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,T("del",null,p)," "],[]).slice(0,-1),i=me(),s=new URL(e.location,i.base);te("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=me();return T("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},T("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&T("div",{class:"md-search-result__icon md-icon"}),r>0&&T("h1",null,e.title),r<=0&&T("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return T("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&T("p",{class:"md-search-result__terms"},be("search.result.term.missing"),": ",...n)))}function fn(e){let t=e[0].score,r=[...e],o=me(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreUr(l,1)),...c.length?[T("details",{class:"md-search-result__more"},T("summary",{tabIndex:-1},T("div",null,c.length>0&&c.length===1?be("search.result.more.one"):be("search.result.more.other",c.length))),...c.map(l=>Ur(l,1)))]:[]];return T("li",{class:"md-search-result__item"},p)}function un(e){return T("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>T("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?tr(r):r)))}function Nr(e){let t=`tabbed-control tabbed-control--${e}`;return T("div",{class:t,hidden:!0},T("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function dn(e){return T("div",{class:"md-typeset__scrollwrap"},T("div",{class:"md-typeset__table"},e))}function ba(e){let t=me(),r=new URL(`../${e.version}/`,t.base);return T("li",{class:"md-version__item"},T("a",{href:`${r}`,class:"md-version__link"},e.title))}function hn(e,t){return T("div",{class:"md-version"},T("button",{class:"md-version__current","aria-label":be("select.version")},t.title),T("ul",{class:"md-version__list"},e.map(ba)))}function va(e){return e.tagName==="CODE"?q(".c, .c1, .cm",e):[e]}function ga(e){let t=[];for(let r of va(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function bn(e,t){t.append(...Array.from(e.childNodes))}function sr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of ga(t)){let[,c]=a.textContent.match(/\((\d+)\)/);ce(`:scope > li:nth-child(${c})`,e)&&(s.set(c,ln(c,i)),a.replaceWith(s.get(c)))}return s.size===0?L:H(()=>{let a=new x,c=a.pipe(Z(),re(!0)),p=[];for(let[l,f]of s)p.push([W(".md-typeset",f),W(`:scope > li:nth-child(${l})`,e)]);return o.pipe(Y(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?bn(f,u):bn(u,f)}),_(...[...s].map(([,l])=>pn(l,t,{target$:r}))).pipe(A(()=>a.complete()),le())})}function vn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return vn(t)}}function gn(e,t){return H(()=>{let r=vn(e);return typeof r!="undefined"?sr(r,e,t):L})}var yn=Ht(Vr());var xa=0;function En(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return En(t)}}function xn(e){return ye(e).pipe(m(({width:t})=>({scrollable:bt(e).width>t})),ee("scrollable"))}function wn(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new x;if(n.subscribe(({scrollable:s})=>{s&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")}),yn.default.isSupported()&&(e.closest(".copy")||te("content.code.copy")&&!e.closest(".no-copy"))){let s=e.closest("pre");s.id=`__code_${xa++}`,s.insertBefore(mn(s.id),e)}let i=e.closest(".highlight");if(i instanceof HTMLElement){let s=En(i);if(typeof s!="undefined"&&(i.classList.contains("annotate")||te("content.code.annotate"))){let a=sr(s,e,t);return xn(e).pipe(w(c=>n.next(c)),A(()=>n.complete()),m(c=>R({ref:e},c)),qe(ye(i).pipe(m(({width:c,height:p})=>c&&p),X(),E(c=>c?a:L))))}}return xn(e).pipe(w(s=>n.next(s)),A(()=>n.complete()),m(s=>R({ref:e},s)))});return te("content.lazy")?rr(e).pipe(M(n=>n),xe(1),E(()=>o)):o}function ya(e,{target$:t,print$:r}){let o=!0;return _(t.pipe(m(n=>n.closest("details:not([open])")),M(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(M(n=>n||!o),w(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Sn(e,t){return H(()=>{let r=new x;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),ya(e,t).pipe(w(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}var Tn=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var zr,wa=0;function Sa(){return typeof mermaid=="undefined"||mermaid instanceof Element?ht("https://unpkg.com/mermaid@9.4.3/dist/mermaid.min.js"):j(void 0)}function On(e){return e.classList.remove("mermaid"),zr||(zr=Sa().pipe(w(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Tn,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),J(1))),zr.subscribe(()=>{e.classList.add("mermaid");let t=`__mermaid_${wa++}`,r=T("div",{class:"mermaid"}),o=e.textContent;mermaid.mermaidAPI.render(t,o,(n,i)=>{let s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})}),zr.pipe(m(()=>({ref:e})))}var Mn=T("table");function Ln(e){return e.replaceWith(Mn),Mn.replaceWith(dn(e)),j({ref:e})}function Ta(e){let t=q(":scope > input",e),r=t.find(o=>o.checked)||t[0];return _(...t.map(o=>h(o,"change").pipe(m(()=>W(`label[for="${o.id}"]`))))).pipe(V(W(`label[for="${r.id}"]`)),m(o=>({active:o})))}function _n(e,{viewport$:t}){let r=Nr("prev");e.append(r);let o=Nr("next");e.append(o);let n=W(".tabbed-labels",e);return H(()=>{let i=new x,s=i.pipe(Z(),re(!0));return B([i,ye(e)]).pipe(Ce(1,Oe),Y(s)).subscribe({next([{active:a},c]){let p=Je(a),{width:l}=he(a);e.style.setProperty("--md-indicator-x",`${p.x}px`),e.style.setProperty("--md-indicator-width",`${l}px`);let f=er(n);(p.xf.x+c.width)&&n.scrollTo({left:Math.max(0,p.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),B([dt(n),ye(n)]).pipe(Y(s)).subscribe(([a,c])=>{let p=bt(n);r.hidden=a.x<16,o.hidden=a.x>p.width-c.width-16}),_(h(r,"click").pipe(m(()=>-1)),h(o,"click").pipe(m(()=>1))).pipe(Y(s)).subscribe(a=>{let{width:c}=he(n);n.scrollBy({left:c*a,behavior:"smooth"})}),te("content.tabs.link")&&i.pipe(je(1),ne(t)).subscribe(([{active:a},{offset:c}])=>{let p=a.innerText.trim();if(a.hasAttribute("data-md-switching"))a.removeAttribute("data-md-switching");else{let l=e.offsetTop-c.y;for(let u of q("[data-tabs]"))for(let d of q(":scope > input",u)){let v=W(`label[for="${d.id}"]`);if(v!==a&&v.innerText.trim()===p){v.setAttribute("data-md-switching",""),d.click();break}}window.scrollTo({top:e.offsetTop-l});let f=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([p,...f])])}}),i.pipe(Y(s)).subscribe(()=>{for(let a of q("audio, video",e))a.pause()}),Ta(e).pipe(w(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))}).pipe(rt(ae))}function An(e,{viewport$:t,target$:r,print$:o}){return _(...q(".annotate:not(.highlight)",e).map(n=>gn(n,{target$:r,print$:o})),...q("pre:not(.mermaid) > code",e).map(n=>wn(n,{target$:r,print$:o})),...q("pre.mermaid",e).map(n=>On(n)),...q("table:not([class])",e).map(n=>Ln(n)),...q("details",e).map(n=>Sn(n,{target$:r,print$:o})),...q("[data-tabs]",e).map(n=>_n(n,{viewport$:t})))}function Oa(e,{alert$:t}){return t.pipe(E(r=>_(j(!0),j(!1).pipe(ze(2e3))).pipe(m(o=>({message:r,active:o})))))}function Cn(e,t){let r=W(".md-typeset",e);return H(()=>{let o=new x;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Oa(e,t).pipe(w(n=>o.next(n)),A(()=>o.complete()),m(n=>R({ref:e},n)))})}function Ma({viewport$:e}){if(!te("header.autohide"))return j(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Le(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),X()),o=We("search");return B([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),X(),E(n=>n?r:j(!1)),V(!1))}function kn(e,t){return H(()=>B([ye(e),Ma(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),X((r,o)=>r.height===o.height&&r.hidden===o.hidden),J(1))}function Hn(e,{header$:t,main$:r}){return H(()=>{let o=new x,n=o.pipe(Z(),re(!0));return o.pipe(ee("active"),Ge(t)).subscribe(([{active:i},{hidden:s}])=>{e.classList.toggle("md-header--shadow",i&&!s),e.hidden=s}),r.subscribe(o),t.pipe(Y(n),m(i=>R({ref:e},i)))})}function La(e,{viewport$:t,header$:r}){return ar(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=he(e);return{active:o>=n}}),ee("active"))}function $n(e,t){return H(()=>{let r=new x;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=ce(".md-content h1");return typeof o=="undefined"?L:La(o,t).pipe(w(n=>r.next(n)),A(()=>r.complete()),m(n=>R({ref:e},n)))})}function Rn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),X()),n=o.pipe(E(()=>ye(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),ee("bottom"))));return B([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),X((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function _a(e){let t=__md_get("__palette")||{index:e.findIndex(r=>matchMedia(r.getAttribute("data-md-color-media")).matches)};return j(...e).pipe(se(r=>h(r,"change").pipe(m(()=>r))),V(e[Math.max(0,t.index)]),m(r=>({index:e.indexOf(r),color:{scheme:r.getAttribute("data-md-color-scheme"),primary:r.getAttribute("data-md-color-primary"),accent:r.getAttribute("data-md-color-accent")}})),J(1))}function Pn(e){let t=T("meta",{name:"theme-color"});document.head.appendChild(t);let r=T("meta",{name:"color-scheme"});return document.head.appendChild(r),H(()=>{let o=new x;o.subscribe(i=>{document.body.setAttribute("data-md-color-switching","");for(let[s,a]of Object.entries(i.color))document.body.setAttribute(`data-md-color-${s}`,a);for(let s=0;s{let i=Ee("header"),s=window.getComputedStyle(i);return r.content=s.colorScheme,s.backgroundColor.match(/\d+/g).map(a=>(+a).toString(16).padStart(2,"0")).join("")})).subscribe(i=>t.content=`#${i}`),o.pipe(Se(ae)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")});let n=q("input",e);return _a(n).pipe(w(i=>o.next(i)),A(()=>o.complete()),m(i=>R({ref:e},i)))})}function In(e,{progress$:t}){return H(()=>{let r=new x;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(w(o=>r.next({value:o})),A(()=>r.complete()),m(o=>({ref:e,value:o})))})}var qr=Ht(Vr());function Aa(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r}function Fn({alert$:e}){qr.default.isSupported()&&new P(t=>{new qr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||Aa(W(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(w(t=>{t.trigger.focus()}),m(()=>be("clipboard.copied"))).subscribe(e)}function Ca(e){if(e.length<2)return[""];let[t,r]=[...e].sort((n,i)=>n.length-i.length).map(n=>n.replace(/[^/]+$/,"")),o=0;if(t===r)o=t.length;else for(;t.charCodeAt(o)===r.charCodeAt(o);)o++;return e.map(n=>n.replace(t.slice(0,o),""))}function cr(e){let t=__md_get("__sitemap",sessionStorage,e);if(t)return j(t);{let r=me();return Zo(new URL("sitemap.xml",e||r.base)).pipe(m(o=>Ca(q("loc",o).map(n=>n.textContent))),de(()=>L),He([]),w(o=>__md_set("__sitemap",o,sessionStorage,e)))}}function jn(e){let t=W("[rel=canonical]",e);t.href=t.href.replace("//localhost:","//127.0.0.1");let r=new Map;for(let o of q(":scope > *",e)){let n=o.outerHTML;for(let i of["href","src"]){let s=o.getAttribute(i);if(s===null)continue;let a=new URL(s,t.href),c=o.cloneNode();c.setAttribute(i,`${a}`),n=c.outerHTML;break}r.set(n,o)}return r}function Wn({location$:e,viewport$:t,progress$:r}){let o=me();if(location.protocol==="file:")return L;let n=cr().pipe(m(l=>l.map(f=>`${new URL(f,o.base)}`))),i=h(document.body,"click").pipe(ne(n),E(([l,f])=>{if(!(l.target instanceof Element))return L;let u=l.target.closest("a");if(u===null)return L;if(u.target||l.metaKey||l.ctrlKey)return L;let d=new URL(u.href);return d.search=d.hash="",f.includes(`${d}`)?(l.preventDefault(),j(new URL(u.href))):L}),le());i.pipe(xe(1)).subscribe(()=>{let l=ce("link[rel=icon]");typeof l!="undefined"&&(l.href=l.href)}),h(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),i.pipe(ne(t)).subscribe(([l,{offset:f}])=>{history.scrollRestoration="manual",history.replaceState(f,""),history.pushState(null,"",l)}),i.subscribe(e);let s=e.pipe(V(pe()),ee("pathname"),je(1),E(l=>ir(l,{progress$:r}).pipe(de(()=>(ot(l,!0),L))))),a=new DOMParser,c=s.pipe(E(l=>l.text()),E(l=>{let f=a.parseFromString(l,"text/html");for(let b of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...te("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let z=ce(b),K=ce(b,f);typeof z!="undefined"&&typeof K!="undefined"&&z.replaceWith(K)}let u=jn(document.head),d=jn(f.head);for(let[b,z]of d)z.getAttribute("rel")==="stylesheet"||z.hasAttribute("src")||(u.has(b)?u.delete(b):document.head.appendChild(z));for(let b of u.values())b.getAttribute("rel")==="stylesheet"||b.hasAttribute("src")||b.remove();let v=Ee("container");return Fe(q("script",v)).pipe(E(b=>{let z=f.createElement("script");if(b.src){for(let K of b.getAttributeNames())z.setAttribute(K,b.getAttribute(K));return b.replaceWith(z),new P(K=>{z.onload=()=>K.complete()})}else return z.textContent=b.textContent,b.replaceWith(z),L}),Z(),re(f))}),le());return h(window,"popstate").pipe(m(pe)).subscribe(e),e.pipe(V(pe()),Le(2,1),M(([l,f])=>l.pathname===f.pathname&&l.hash!==f.hash),m(([,l])=>l)).subscribe(l=>{var f,u;history.state!==null||!l.hash?window.scrollTo(0,(u=(f=history.state)==null?void 0:f.y)!=null?u:0):(history.scrollRestoration="auto",nr(l.hash),history.scrollRestoration="manual")}),e.pipe(Cr(i),V(pe()),Le(2,1),M(([l,f])=>l.pathname===f.pathname&&l.hash===f.hash),m(([,l])=>l)).subscribe(l=>{history.scrollRestoration="auto",nr(l.hash),history.scrollRestoration="manual",history.back()}),c.pipe(ne(e)).subscribe(([,l])=>{var f,u;history.state!==null||!l.hash?window.scrollTo(0,(u=(f=history.state)==null?void 0:f.y)!=null?u:0):nr(l.hash)}),t.pipe(ee("offset"),ke(100)).subscribe(({offset:l})=>{history.replaceState(l,"")}),c}var Dn=Ht(Nn());function Vn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,Dn.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Mt(e){return e.type===1}function pr(e){return e.type===3}function zn(e,t){let r=an(e);return _(j(location.protocol!=="file:"),We("search")).pipe($e(o=>o),E(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:te("search.suggest")}}})),r}function qn({document$:e}){let t=me(),r=Ue(new URL("../versions.json",t.base)).pipe(de(()=>L)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),E(n=>h(document.body,"click").pipe(M(i=>!i.metaKey&&!i.ctrlKey),ne(o),E(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?L:(i.preventDefault(),j(c))}}return L}),E(i=>{let{version:s}=n.get(i);return cr(new URL(i)).pipe(m(a=>{let p=pe().href.replace(t.base,"");return a.includes(p.split("#")[0])?new URL(`../${s}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>ot(n,!0)),B([r,o]).subscribe(([n,i])=>{W(".md-header__topic").appendChild(hn(n,i))}),e.pipe(E(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases)if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of oe("outdated"))a.hidden=!1})}function Pa(e,{worker$:t}){let{searchParams:r}=pe();r.has("q")&&(Ke("search",!0),e.value=r.get("q"),e.focus(),We("search").pipe($e(i=>!i)).subscribe(()=>{let i=pe();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=Zt(e),n=_(t.pipe($e(Mt)),h(e,"keyup"),o).pipe(m(()=>e.value),X());return B([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),J(1))}function Kn(e,{worker$:t}){let r=new x,o=r.pipe(Z(),re(!0));B([t.pipe($e(Mt)),r],(i,s)=>s).pipe(ee("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(ee("focus")).subscribe(({focus:i})=>{i&&Ke("search",i)}),h(e.form,"reset").pipe(Y(o)).subscribe(()=>e.focus());let n=W("header [for=__search]");return h(n,"click").subscribe(()=>e.focus()),Pa(e,{worker$:t}).pipe(w(i=>r.next(i)),A(()=>r.complete()),m(i=>R({ref:e},i)),J(1))}function Qn(e,{worker$:t,query$:r}){let o=new x,n=Ko(e.parentElement).pipe(M(Boolean)),i=e.parentElement,s=W(":scope > :first-child",e),a=W(":scope > :last-child",e);We("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(ne(r),$r(t.pipe($e(Mt)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?be("search.result.none"):be("search.result.placeholder");break;case 1:s.textContent=be("search.result.one");break;default:let u=tr(l.length);s.textContent=be("search.result.other",u)}});let c=o.pipe(w(()=>a.innerHTML=""),E(({items:l})=>_(j(...l.slice(0,10)),j(...l.slice(10)).pipe(Le(4),Ir(n),E(([f])=>f)))),m(fn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(se(l=>{let f=ce("details",l);return typeof f=="undefined"?L:h(f,"toggle").pipe(Y(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(M(pr),m(({data:l})=>l)).pipe(w(l=>o.next(l)),A(()=>o.complete()),m(l=>R({ref:e},l)))}function Ia(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=pe();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Yn(e,t){let r=new x,o=r.pipe(Z(),re(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),h(e,"click").pipe(Y(o)).subscribe(n=>n.preventDefault()),Ia(e,t).pipe(w(n=>r.next(n)),A(()=>r.complete()),m(n=>R({ref:e},n)))}function Bn(e,{worker$:t,keyboard$:r}){let o=new x,n=Ee("search-query"),i=_(h(n,"keydown"),h(n,"focus")).pipe(Se(ae),m(()=>n.value),X());return o.pipe(Ge(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(M(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(M(pr),m(({data:a})=>a)).pipe(w(a=>o.next(a)),A(()=>o.complete()),m(()=>({ref:e})))}function Gn(e,{index$:t,keyboard$:r}){let o=me();try{let n=zn(o.search,t),i=Ee("search-query",e),s=Ee("search-result",e);h(e,"click").pipe(M(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Ke("search",!1)),r.pipe(M(({mode:c})=>c==="search")).subscribe(c=>{let p=Re();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of q(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,d])=>d-u);f.click()}c.claim()}break;case"Escape":case"Tab":Ke("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...q(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(M(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Kn(i,{worker$:n});return _(a,Qn(s,{worker$:n,query$:a})).pipe(qe(...oe("search-share",e).map(c=>Yn(c,{query$:a})),...oe("search-suggest",e).map(c=>Bn(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,Ve}}function Jn(e,{index$:t,location$:r}){return B([t,r.pipe(V(pe()),M(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Vn(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=T("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Fa(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return B([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),X((i,s)=>i.height===s.height&&i.locked===s.locked))}function Kr(e,o){var n=o,{header$:t}=n,r=eo(n,["header$"]);let i=W(".md-sidebar__scrollwrap",e),{y:s}=Je(i);return H(()=>{let a=new x,c=a.pipe(Z(),re(!0)),p=a.pipe(Ce(0,Oe));return p.pipe(ne(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe($e()).subscribe(()=>{for(let l of q(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=he(f);f.scrollTo({top:u-d/2})}}}),ge(q("label[tabindex]",e)).pipe(se(l=>h(l,"click").pipe(Se(ae),m(()=>l),Y(c)))).subscribe(l=>{let f=W(`[id="${l.htmlFor}"]`);W(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Fa(e,r).pipe(w(l=>a.next(l)),A(()=>a.complete()),m(l=>R({ref:e},l)))})}function Xn(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return St(Ue(`${r}/releases/latest`).pipe(de(()=>L),m(o=>({version:o.tag_name})),He({})),Ue(r).pipe(de(()=>L),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),He({}))).pipe(m(([o,n])=>R(R({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return Ue(r).pipe(m(o=>({repositories:o.public_repos})),He({}))}}function Zn(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return Ue(r).pipe(de(()=>L),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),He({}))}function ei(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return Xn(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return Zn(r,o)}return L}var ja;function Wa(e){return ja||(ja=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return j(t);if(oe("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return L}return ei(e.href).pipe(w(o=>__md_set("__source",o,sessionStorage)))}).pipe(de(()=>L),M(t=>Object.keys(t).length>0),m(t=>({facts:t})),J(1)))}function ti(e){let t=W(":scope > :last-child",e);return H(()=>{let r=new x;return r.subscribe(({facts:o})=>{t.appendChild(un(o)),t.classList.add("md-source__repository--active")}),Wa(e).pipe(w(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}function Ua(e,{viewport$:t,header$:r}){return ye(document.body).pipe(E(()=>ar(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),ee("hidden"))}function ri(e,t){return H(()=>{let r=new x;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(te("navigation.tabs.sticky")?j({hidden:!1}):Ua(e,t)).pipe(w(o=>r.next(o)),A(()=>r.complete()),m(o=>R({ref:e},o)))})}function Na(e,{viewport$:t,header$:r}){let o=new Map,n=q("[href^=\\#]",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=ce(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(ee("height"),m(({height:a})=>{let c=Ee("main"),p=W(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return ye(document.body).pipe(ee("height"),E(a=>H(()=>{let c=[];return j([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let d=f.offsetParent;for(;d;d=d.offsetParent)u+=d.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),Ge(i),E(([c,p])=>t.pipe(kr(([l,f],{offset:{y:u},size:d})=>{let v=u+d.height>=Math.floor(a.height);for(;f.length;){let[,b]=f[0];if(b-p=u&&!v)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),X((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),V({prev:[],next:[]}),Le(2,1),m(([a,c])=>a.prev.length{let i=new x,s=i.pipe(Z(),re(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),te("toc.follow")){let a=_(t.pipe(ke(1),m(()=>{})),t.pipe(ke(250),m(()=>"smooth")));i.pipe(M(({prev:c})=>c.length>0),Ge(o.pipe(Se(ae))),ne(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=zo(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:d}=he(f);f.scrollTo({top:u-d/2,behavior:p})}}})}return te("navigation.tracking")&&t.pipe(Y(s),ee("offset"),ke(250),je(1),Y(n.pipe(je(1))),Tt({delay:250}),ne(i)).subscribe(([,{prev:a}])=>{let c=pe(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Na(e,{viewport$:t,header$:r}).pipe(w(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))})}function Da(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),Le(2,1),m(([s,a])=>s>a&&a>0),X()),i=r.pipe(m(({active:s})=>s));return B([i,n]).pipe(m(([s,a])=>!(s&&a)),X(),Y(o.pipe(je(1))),re(!0),Tt({delay:250}),m(s=>({hidden:s})))}function ni(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new x,s=i.pipe(Z(),re(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(Y(s),ee("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),h(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),Da(e,{viewport$:t,main$:o,target$:n}).pipe(w(a=>i.next(a)),A(()=>i.complete()),m(a=>R({ref:e},a)))}function ii({document$:e,tablet$:t}){e.pipe(E(()=>q(".md-toggle--indeterminate")),w(r=>{r.indeterminate=!0,r.checked=!1}),se(r=>h(r,"change").pipe(Rr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ne(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function Va(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function ai({document$:e}){e.pipe(E(()=>q("[data-md-scrollfix]")),w(t=>t.removeAttribute("data-md-scrollfix")),M(Va),se(t=>h(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function si({viewport$:e,tablet$:t}){B([We("search"),t]).pipe(m(([r,o])=>r&&!o),E(r=>j(r).pipe(ze(r?400:100))),ne(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function za(){return location.protocol==="file:"?ht(`${new URL("search/search_index.js",Qr.base)}`).pipe(m(()=>__index),J(1)):Ue(new URL("search/search_index.json",Qr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var nt=Uo(),_t=Bo(),gt=Jo(_t),Yr=Yo(),Te=nn(),lr=Fr("(min-width: 960px)"),pi=Fr("(min-width: 1220px)"),li=Xo(),Qr=me(),mi=document.forms.namedItem("search")?za():Ve,Br=new x;Fn({alert$:Br});var Gr=new x;te("navigation.instant")&&Wn({location$:_t,viewport$:Te,progress$:Gr}).subscribe(nt);var ci;((ci=Qr.version)==null?void 0:ci.provider)==="mike"&&qn({document$:nt});_(_t,gt).pipe(ze(125)).subscribe(()=>{Ke("drawer",!1),Ke("search",!1)});Yr.pipe(M(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=ce("link[rel=prev]");typeof t!="undefined"&&ot(t);break;case"n":case".":let r=ce("link[rel=next]");typeof r!="undefined"&&ot(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});ii({document$:nt,tablet$:lr});ai({document$:nt});si({viewport$:Te,tablet$:lr});var Xe=kn(Ee("header"),{viewport$:Te}),Lt=nt.pipe(m(()=>Ee("main")),E(e=>Rn(e,{viewport$:Te,header$:Xe})),J(1)),qa=_(...oe("consent").map(e=>cn(e,{target$:gt})),...oe("dialog").map(e=>Cn(e,{alert$:Br})),...oe("header").map(e=>Hn(e,{viewport$:Te,header$:Xe,main$:Lt})),...oe("palette").map(e=>Pn(e)),...oe("progress").map(e=>In(e,{progress$:Gr})),...oe("search").map(e=>Gn(e,{index$:mi,keyboard$:Yr})),...oe("source").map(e=>ti(e))),Ka=H(()=>_(...oe("announce").map(e=>sn(e)),...oe("content").map(e=>An(e,{viewport$:Te,target$:gt,print$:li})),...oe("content").map(e=>te("search.highlight")?Jn(e,{index$:mi,location$:_t}):L),...oe("header-title").map(e=>$n(e,{viewport$:Te,header$:Xe})),...oe("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?jr(pi,()=>Kr(e,{viewport$:Te,header$:Xe,main$:Lt})):jr(lr,()=>Kr(e,{viewport$:Te,header$:Xe,main$:Lt}))),...oe("tabs").map(e=>ri(e,{viewport$:Te,header$:Xe})),...oe("toc").map(e=>oi(e,{viewport$:Te,header$:Xe,main$:Lt,target$:gt})),...oe("top").map(e=>ni(e,{viewport$:Te,header$:Xe,main$:Lt,target$:gt})))),fi=nt.pipe(E(()=>Ka),qe(qa),J(1));fi.subscribe();window.document$=nt;window.location$=_t;window.target$=gt;window.keyboard$=Yr;window.viewport$=Te;window.tablet$=lr;window.screen$=pi;window.print$=li;window.alert$=Br;window.progress$=Gr;window.component$=fi;})(); +//# sourceMappingURL=bundle.aecac24b.min.js.map + diff --git a/assets/javascripts/bundle.aecac24b.min.js.map b/assets/javascripts/bundle.aecac24b.min.js.map new file mode 100644 index 0000000..b1534de --- /dev/null +++ b/assets/javascripts/bundle.aecac24b.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/sample.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2023 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an --> +
+
+ + + Last update: + October 12, 2023 + +
+ + + + +
+ +
+
+
+ + + + + + + \ No newline at end of file diff --git a/physics/index.html b/physics/index.html new file mode 100644 index 0000000..64f60eb --- /dev/null +++ b/physics/index.html @@ -0,0 +1,573 @@ + + + + + + + + + + + +普物辅学 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

普物辅学

+

欢迎来到竺院普物辅学版块🤗。你可以在左侧导航栏中详细浏览本模块的内容。

+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming/exam/fundamentals_of_programming/fp13answer.pdf b/programming/exam/fundamentals_of_programming/fp13answer.pdf new file mode 100644 index 0000000..c199182 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp13answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp13test.pdf b/programming/exam/fundamentals_of_programming/fp13test.pdf new file mode 100644 index 0000000..499d736 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp13test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp14answer.pdf b/programming/exam/fundamentals_of_programming/fp14answer.pdf new file mode 100644 index 0000000..202e0a4 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp14answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp14test.pdf b/programming/exam/fundamentals_of_programming/fp14test.pdf new file mode 100644 index 0000000..f692feb Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp14test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp15answer.pdf b/programming/exam/fundamentals_of_programming/fp15answer.pdf new file mode 100644 index 0000000..0d5955a Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp15answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp15test.pdf b/programming/exam/fundamentals_of_programming/fp15test.pdf new file mode 100644 index 0000000..85dc7c2 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp15test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp16answer.pdf b/programming/exam/fundamentals_of_programming/fp16answer.pdf new file mode 100644 index 0000000..c1156ad Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp16answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp16test.pdf b/programming/exam/fundamentals_of_programming/fp16test.pdf new file mode 100644 index 0000000..06c58ce Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp16test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp17answer.pdf b/programming/exam/fundamentals_of_programming/fp17answer.pdf new file mode 100644 index 0000000..388ba6c Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp17answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp17test.pdf b/programming/exam/fundamentals_of_programming/fp17test.pdf new file mode 100644 index 0000000..b7799ea Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp17test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp18answer.pdf b/programming/exam/fundamentals_of_programming/fp18answer.pdf new file mode 100644 index 0000000..3901947 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp18answer.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp18test.pdf b/programming/exam/fundamentals_of_programming/fp18test.pdf new file mode 100644 index 0000000..4450169 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp18test.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp20simulation1.pdf b/programming/exam/fundamentals_of_programming/fp20simulation1.pdf new file mode 100644 index 0000000..2c5b6e7 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp20simulation1.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp20simulation2.pdf b/programming/exam/fundamentals_of_programming/fp20simulation2.pdf new file mode 100644 index 0000000..7f4cac6 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp20simulation2.pdf differ diff --git a/programming/exam/fundamentals_of_programming/fp20simulation3.pdf b/programming/exam/fundamentals_of_programming/fp20simulation3.pdf new file mode 100644 index 0000000..fdbafc9 Binary files /dev/null and b/programming/exam/fundamentals_of_programming/fp20simulation3.pdf differ diff --git a/programming/exam/index.html b/programming/exam/index.html new file mode 100644 index 0000000..43373c6 --- /dev/null +++ b/programming/exam/index.html @@ -0,0 +1,709 @@ + + + + + + + + + + + + +历年卷整理 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

历年卷整理

+

程序设计与算法基础

+

暂无

+

程序设计基础与实验

+

暂无

+

【已停开】程序设计基础(2013-2018+2020)

+

该课程已于 2022-2023 学年停开,经典题目解析见 C 大经典题目解析

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
年份试卷答案
2013试卷答案
2014试卷答案
2015试卷答案
2016试卷答案
2017试卷答案
2018试卷答案
2020模拟卷 1 及答案 模拟卷 2 及答案 模拟卷 3 及答案
+

【已停开】C 程序设计专题(2013-2019)

+

该课程已于 2022-2023 学年停开,经典题目解析见 C 小经典题目解析

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
年份试卷答案
2013试卷答案
2014试卷答案
2015试卷答案
2016试卷答案
2017试卷答案
2018试卷答案
2019试卷答案
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming/exam/lectures_on_c_programming/index.html b/programming/exam/lectures_on_c_programming/index.html new file mode 100644 index 0000000..782abc3 --- /dev/null +++ b/programming/exam/lectures_on_c_programming/index.html @@ -0,0 +1,1214 @@ + + + + + + + + + + +C 程序设计专题 历年卷经典题目解析 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

C 程序设计专题 历年卷经典题目解析

+ +
+

页面正在施工中

+
+ +

2020-2021 年卷

+
    +
  • 选择题 1 typedef
  • +
+
+

注意这里的 typedef struct{char * name;} *T;T 定义为 struct{char * name;}*; 的别名。下一个语句即声明变量 t 为该类型。

+
    +
  • A:char *
  • +
  • B:该表达式实际为 &(t->name[0]),即 char * 类型。
  • +
  • C:char *
  • +
  • D:*(t.name) 是一个错误的用法,不能直接对结构的指针使用 . 运算符访问其成员。
  • +
+
+
    +
  • 选择题 3 指针类型
  • +
+
+

函数名、数组名都不是指针哦,虽然它们常常退化成指针。

+
    +
  • A:p 是函数名
  • +
  • B:p 是函数名
  • +
  • C:p 是指向 int[5] 的指针
  • +
  • D:p 是一个数组
  • +
+
+
    +
  • 选择题 4 存储类别限定符
  • +
+
+

C 语言中一共有 5 个存储类别限定符,请回忆它们的作用:

+
    +
  • auto:默认的存储类别限定符,用于局部变量,表示变量的生命周期与函数调用相同。
  • +
  • register:用于局部变量,表示变量可能存储在 CPU 寄存器中,以加快访问速度。
  • +
  • extern:用于全局变量,表示变量在其他文件中定义。
  • +
  • +

    static

    +
      +
    • 用于局部变量,表示变量的生命周期与程序运行相同。
    • +
    • 用于全局变量,表示变量的作用域仅限于当前文件。
    • +
    +
  • +
  • +

    _Thread_local:不作要求。

    +
  • +
+

其实 typedef 按语法功能也被分在这一类,我们不管它。

+

在任何声明中,只能同时存在最多一个存储类别限定符。这与 constvolatilerestrict类型限定符不同,它们可以同时存在。

+
+
    +
  • 选择题 5 函数指针
  • +
+
+

2019 年选择题 6

+
+
    +
  • 选择题 8 数据结构的使用
  • +
+
+

这种题通用的方法就是每个选项尝试一遍。只要对栈、队列操作熟悉的话,一个个试很快就出来了。

+
+
    +
  • 简答题 1.1 后缀表达式
  • +
+
+

如果你的答案和参考答案不一样,也是有对的可能的,就像中缀表达式那样,二元运算符的操作数是可以换序的(

+

注意这道题中的 ^ 运算符的右结合问题,加上括号后变成 d^(e^f) 而不是 (d^e)^f,转换成后缀表达式只能是 def^^,而 fed^^ 之类的全是错的。

+
+
    +
  • 简答题 5 排序算法最优情况
  • +
+
+

见常见问题 - 算法复杂度

+

引用一下 ztgg 的解释:

+
    +
  • 平均情况下,插入元素导致的移动依旧是 \(O(n)\) 的,并没有优化,所以总复杂度还是 \(O(n^2)\)(批注:交换的复杂度为 \(O(n^2)\),比较的复杂度为 \(O(n\log n)\),前者较大,占据主导地位
  • +
  • 最佳情况应该是插入元素时,不需要移动原来的元素,也就是数组已经排好序了。这个情况下,每次插入只有二分查找的代价,即为 \(O(n\log n)\)
  • +
+
+
    +
  • 简答题 6 队列操作
  • +
+
+

如果第一个 while 循环读不懂一定要找同学 / 老师问清楚捏,队列的使用是很基本的。请思考这个 while 循环为什么需要逐个 malloc() 呢?

+

中间那个 while 循环有点迷惑。它其实只是在将 eQueue 中的每个元素放到 dQueue 时同时把后面一个元素换到队尾去。理解到这里就能做对啦。

+
+
    +
  • 程序填空 3
  • +
+
+

这几个空都需要花一会儿时间来推断的:

+
    +
  • InitGraphics() 一定要记得
  • +
  • 记住几种回调函数的使用方法,void registerTimerEvent(TimerEventCallback callback)void startTimer(int id,int timeinterval) 配对使用,它们各自的参数意义。
  • +
  • 计时器回调函数怎么写?参数 timerID 是用来做什么的?
  • +
  • 14 空可能不容易想到,反正记住在每次画点什么东西之前,都要检查画笔位置是否正确,这在绘制分形图形时也很重要。
  • +
+
+
    +
  • 算法设计 1 链表循环检测
  • +
+
+

想象一个解谜场景:如果你和你的朋友走在一条路上,你们要怎么做才能判断有没有遇到鬼打墙(即在原路绕圈) ?

+

答案很简单:一个人走快点,一个人走慢点。如果这条路有尽头,先走的人一定会先到达尽头;如果没有到达尽头,那么他一定会重新看见你。

+

LoopDetect() 函数的思路也类似:使用两个指针 fastlatefast 每次步进两个节点,late 每次步进一个节点。最后终止时只有两种条件:fast 无法继续步进或 fast 在前进的路上看见 late。前者表明没有循环,后者表明有循环。

+
+
    +
  • 算法设计 2 有序数组原地去重
  • +
+
+

看到这道题你有没有想起字符串去空格的一个例程?

+
char *a;
+for(int i = 0, j = 0; i < length; i++){
+    if(a[i] != ' ')
+        a[j++] = a[i];
+}
+
+

有序数组去重与这个算法也有些类似,只是比较条件换成 a[i]!=a[j] 了而已。

+
+

2019-2020 年卷

+
    +
  • 选择题 1 递归函数
  • +
+
+
    +
  • D 项 调用栈位于堆栈段(Stack Segment),在运行时创建,也有自己的大小,不能越界访问。越界造成段错误(Segmentation Fault)。每次递归调用添加栈帧,造成的越界称为栈溢出(Stack Overflow)。堆栈段中保存着函数调用关系和局部变量。局部变量过大也可能造成栈溢出。
  • +
+
+
    +
  • 选择题 2 时间复杂度分析
  • +
  • 选择题 6 函数指针
  • +
+
+

一句话总结:作为函数作为形参,会自动退化成函数指针,就像数组名作为形参自动退化成指针那样。这句话在下面的英文部分提到了。

+
+

The type of a function is determined using the following rules. [...] After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. [...]

+
+
    +
  • 函数指针:指向函数的指针中储存着函数代码的起始处地址,要指明函数的类型,要指明函数的返回类型和形参类型。把函数名替换成 (*pf) 的形式是最简单的方法,如 void ToUpper(char *) 改为函数指针 void (*pf)(char *)
  • +
  • +

    声明函数指针后,可以将函数的地址赋给它,这种语境下函数名可以表示函数的地址。因此我们可以写:pf = ToUpper,注意不是 pf = ToUpper()

    +
  • +
  • +

    使用函数指针调用函数有两种方法:(*pf)(mis)pf(mis),它们看起来矛盾。事实上,K&R C 不允许第二种形式,我也推荐大家始终将函数调用理解为第一种形式。

    +
      +
    • 第一种形式,先解引用函数指针再调用该函数,这个思路很直接。
    • +
    • 第二种形式,来源是上面的赋值语句,在上面的赋值语境下,指针和函数名可以互换使用。
    • +
    +
  • +
  • +

    取函数的地址也有两种方法:f&f

    +
  • +
  • +

    C 项 或许通过上面的讲解,你能理解 (*cmd)cmd 的等价之处。下面是 StackOverflow 中的讨论:c++ - What does void f(void()) mean? - Stack Overflow

    +
  • +
+
+

As mentioned in dcl.fct of the working draft (emphasis mine):

+
+

The type of a function is determined using the following rules. [...] After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. [...]

+
+

Because of that, the following function:

+
void f(void());
+
+

Has the same type of:

+
void f(void(*)());
+
+

Thus the definitions below are identical:

+
void f(void(g)());
+void f(void(*g)());
+
+

Correct me if I'm wrong, AFAIK function names are pointers just like array names so in the first example you are passing function object and compiler does implicit conversion, in the second example you are directly passing function pointer which is explicit conversion.

+
+
+
    +
  • 选择题 7 函数指针
  • +
+
+

同样依据上面的讲解能够选出正确答案

+
+
    +
  • 选择题 8 函数参数
  • +
+
+

我觉得 D 项的表述本来就很混乱。函数参数如果为 void 就表示函数不接收参数,这就是 void 关键字的作用,而不是选项中说的什么“函数有一个 void 类型的参数”。

+
+
    +
  • 选择题 9 图形库
  • +
+
+

WK 班同学一定要去看辅学群里其他老师的图形库课件

+
+
    +
  • 选择题 10 还是函数指针
  • +
+
+
    +
  • 第一行:F 定义为 int (int) 类型的函数。
  • +
  • 第二行:声明两个类型为 F 的函数 gh。其实就是 int g(int a)int h(int a)
  • +
  • 第三行:声明一个数组 p,其中每个元素都是 int (*)(int) 类型(与 F 等价。并用 gh 来初始化这个数组。
      +
    • 让我们从内往外读这个声明:p 是标识符的名称,向右 [] 表明这是一个数组,向左 * 表示其元素是指针,再向右 (int) 表示其所指类型是函数,这种函数接受 int 类型参数,再向左 int 说明这种函数返回 int 类型。
    • +
    • gh 初始化这个数组时,gh 被转换为函数指针(回顾上面的讨论
    • +
    +
  • +
  • +

    第四行:声明一个函数 q 这个函数返回 int,接受一种数组,这种数组的每个元素都是 F* 类型,即 int (*)(int)。故函数 q 的参数类型为 int (**)(int)

    +
  • +
  • +

    A 项:数组名就是首元素指针,为 int (**)(int),匹配。

    +
  • +
  • C 项:显然类型匹配。
  • +
  • D 项:对函数取地址,得到 int (*)(int),与 int (**)(int) 类型不匹配。
  • +
+
+
    +
  • 简答题 1
  • +
+
+

如果程序代码有错,就勇敢地写“该段程序可能运行失败”。

+
+
    +
  • 简答题 3
  • +
+
+

注意,合并数组的时候部分去重了。如果离开了第一个 while 循环,则不会去重。

+
+
    +
  • 简答题 4
  • +
+
+

让我们看 main() 函数的第一行的表达式:

+
    +
  • 外层:((H)内层表达式 )(100);,它会将内层表达式强制类型转换为 H 类型的函数,然后对该函数执行函数调用。
  • +
  • 内层:h(0)。调用后返回了 h,即函数自己,也就是函数自己的指针。作为 void * 类型返回,表明它是一个指针,但不知道所指向的类型。
  • +
  • 内层调用后,外层就相当于 h(100)了,因为 h 本来就是 H 类型的函数。
  • +
+
+
    +
  • 程序填空 3 geblib.h
  • +
+
+

WK 班同学应当补充阅读 libgraphics 库中的一些内容,我们直接读源码吧:

+
    +
  • +

    New() 宏函数:

    +
      +
    • +

      Usage: p = New(pointer-type);

      +
    • +
    • +

      The New pseudofunction allocates enough space to hold an object of the type to which pointer-type points and returns a pointer to the newly allocated pointer. Note that "New" is different from the "new" operator used in C++; the former takes a pointer type and the latter takes the target type.

      +
    • +
    • +

      源码:

      +
      void *GetBlock(size_t nbytes);
      +#define New(type) ((type) GetBlock(sizeof *((type) NULL)))
      +
      +
    • +
    • +

      举个例子:调用 New(char*)

      +
        +
      • 宏展开为 ((char*) GetBlock(sizeof *((char*) NULL)))
      • +
      • GetBlock() 函数接收需要分配的字节数,返回分配成功的指针。对于上面的宏展开后的调用参数,NULL 被转换为 char* 随后解引用仍为 char 类型的大小。
      • +
      • 这个调用就返回了一个 char* 的指针。
      • +
      +
    • +
    +
  • +
  • +

    FreeBlock() 函数:

    +
      +
    • 原型:void FreeBlock(void *ptr)
    • +
    • free() 功能类似,不加解释。
    • +
    +
  • +
+

15 空有意思,FreeBlock(PopStack(stack)) 的嵌套写法。

+
+
    +
  • 算法设计 1 分形
  • +
+
+

这类算法设计题目,怎么简洁怎么来,以 OI 码风去写是最合适的。不要试图弄完善的交互,那是浪费时间。

+

以下是我自己做的时候写的,作为一个不好的参考(

+

理解错题意了,原来 order 不是方向而是分形次序。

+
    +
  • 基准情形:长度缩小到某值。
  • +
  • +

    递归情形:画一根,随后两次递归调用,绘制下一支的 lengthorder。每次递归调用后,都应当返回原位

    +
    #include <stdio.h>
    +#include <math.h>
    +#include <stdlib.h>
    +#include "graphics.h"
    +#define MIN_LEN .1
    +
    +double toRadius(double deg)
    +{
    +    return deg * 3.1415926 / 180;
    +}
    +
    +void DrawBranch(double len, double deg)
    +{
    +    DrawLine(len * cos(toRadius(deg)), len * sin(toRadius(deg)));
    +    if (len * 0.75 < MIN_LEN)
    +        return;
    +    DrawBranch(len * 0.75, deg - 15);
    +    MovePen(GetCurrentX() - len * 0.75 * cos(toRadius(deg - 15)),
    +            GetCurrentY() - len * 0.75 * sin(toRadius(deg - 15)));
    +    //也可以用 DrawLine 实现
    +    DrawBranch(len * 0.75, deg + 15);
    +    MovePen(GetCurrentX() - len * 0.75 * cos(toRadius(deg + 15)),
    +            GetCurrentY() - len * 0.75 * sin(toRadius(deg + 15)));
    +}
    +
    +int main(void)
    +{
    +  double length;
    +    char order;
    +    printf("Please enter initial length: ");
    +    scanf("%lf", &length);
    +    getchar();
    +    printf("Please enter order (u)pper, (d)own, (r)ight, (l)eft: ");
    +    scanf("%c", &order);
    +    double deg;
    +    switch(order)
    +    {
    +        case 'u': deg = 90; break;
    +        case 'd': deg = -90; break;
    +        case 'r': deg = 0; break;
    +        case 'l': deg = 180; break;
    +        default: printf("error.\n"); return 1;
    +    }
    +    InitGraphics();
    +    MovePen(GetWindowWidth()/2, GetWindowHeight()/2);
    +  DrawBranch(length, deg);
    +    return 0;
    +}
    +
    +
  • +
+
+
    +
  • 算法设计 2 列表变序
  • +
+
+

就用标答的方法,将偶数节点移动到另一个链表,再合并两个链表。

+
+

2018-2019 年卷

+
    +
  • 选择题 4 递归计算
  • +
+
+

像这种递归计算,就老老实实把函数递归展开吧。展开过程中记得依次记下已经计算完的 f(0)f(1) 等值,方便后续计算。

+
+
    +
  • 选择题 6 算法复杂度分析
  • +
+
+

这道题我的想法挺奇葩的,我是想只要全部排序一遍 \(O(N\log N)\),然后用 \(O(1)\) 的时间检查一下头、中间、尾部的元素不就好了吗(doge

+
+
    +
  • 选择题 9 递增运算符
  • +
+
+

前缀递增运算符先递增再使用。

+
+
    +
  • 简答题 1.2
  • +
+
+

本题英文有点烫嘴,我翻译一下:

+
+

为了用类似 T p 的方式声明一个指针 p,请写出复合类型 T 的定义。p 是一个函数的指针,该函数接收 (char *, double) 参数,并返回一个 int *

+
+

读懂题目剩下的就不用说啦。

+
+
    +
  • 简答题 2 数据与字节
  • +
+
+

注意:xx-bit system(n 位系统)指的是这个系统的指针长度有 \(n\) 比特,\(8\) 比特为一个字节。故本题的所有指针都是 \(4\) 字节。

+

以下是各类型的大小:

+
    +
  • StudentInfo:两个 char 数组 + 一个指针 = \(12 + 20 + 4 = 36\)
  • +
  • PtrStudentInfo\(4\)
  • +
  • pStudent->name:一个 char 数组 \(=20\)
  • +
  • pStudent->photo:一个 void* 指针 \(=4\)
  • +
+

从上面再次看到,数组名并不能简单被看作指针,它还包含数组的类型信息。

+
+
    +
  • 简答题 3 链表操作
  • +
+
+

这道题答案感觉有点问题啊。反正只要知道返回的时候 p 指向 \(2\) 这个节点就算对了,题目说 node 那应该不用吧后面的节点都写出来吧。

+
+
    +
  • 简答题 4 链表操作
  • +
+
+

这个函数合并了两个链表,按升序合并。

+

HEAD 是一个临时使用的哑节点。

+

调用后,原来的两个指针指的位置不变,l1 仍然指向 \(1\) 这个节点。但节点之间的连接变了,这时 l1 后面链上了从 l2 合并进来的其他节点。所以可以看作“链表” l1 发生了改变。

+
+
    +
  • 简答题 5 双向栈
  • +
+
+

这是一个双向的栈。每次入 / 出栈时,需要用 Tag 参数指定是哪一头。从数组的角度来看,Top1 是左边(头部)那头,Top2 是右边(尾部)那头。

+

读这种题时,我推荐先读 main() 中的内容,即观察题目给的数据结构是怎么被使用的。然后不明白的地方再去看具体实现的代码,其他部分就一点都不用看。比如这道题:

+
    +
  • 先看 main() 中的 Push() ,这怎么比平常的 Push() 多一个参数呢?
  • +
  • 再看类型定义,怎么有两个 Top?回想 main() 中一个令为 -1 一个令为 MaxSize 便知道这是一个双向栈了。
  • +
  • Push()Pop() 的代码就不用看了,想象得到是怎么操作的。最多再多看一眼 if(Tag == 1) 知道哪个值对应哪一头,就可以完成这道题了。
  • +
+
+
    +
  • 简答题 6 不知道是什么
  • +
+
+

这个东西,保险起见推荐手工模拟,而且手工模拟几次后你就知道这个函数在干嘛了。

+

其实这个函数的作用是:调用后保证数组 a[k] 左侧的元素都比 a[k] 小,右侧都比 a[k] 大。最后返回 a[k] 上的元素。但不会保证其他元素之间的相对顺序

+

具体的操作就是:每轮循环把第 a[k] 位置上的元素提出来作为 x,然后用 ij 分别从左右遍历并交换两侧不符合要求的数。交换完成后,数组中比 x 小的数都在相对左边的位置,比 x 大的数都在相对右边的位置。

+

如果你对快排比较熟悉,那么这就是“如果目标位置不在的一边直接舍弃”的快排。相当于本来快排区间形成一颗树,但是现在就只走一条路,只排 a[k] 所在的那些区间套。

+
+
    +
  • 程序填空 1 分型
  • +
+
+

画个坐标轴,一切都清晰起来了。然后 Main() 里最开始对大三角形三个顶点的求值可能会引起困惑,其实可以不用管它,它不影响你分析递归调用过程。它只是在用三角函数计算位置使这个大三角形的中心在屏幕中央罢了。给个很草的草稿示意图:

+

画这个分形的步骤就是:先画大三角,然后各边取中点。大三角的每个顶点和相邻两边中点构成两个小三角。

+

+
+
    +
  • 程序填空 2 循环队列实现
  • +
+
+

本质上还是用数组实现循环队列,只不过本题进行了比较完善的封装。

+

如果还不知道循环队列是什么东西,去网上搜一搜。循环队列的要点就是:所有加法操作全部要套上一次取模操作。本题注意一下间接成员运算符 -> 的使用。

+

此外循环队列的 rear 也有不同实现方法,在本题中,它标志队列尾部的后一个元素,也就是下一个元素应该插入的地方;在另一些实现中,它直接标志队列尾部的元素。比如如果本题在创建数组的时候 Q->rear = maxsize - 1,这些空应该作怎样的改变呢?

+
+
    +
  • 程序填空 3 图形库
  • +
+
+

参见常见问题 - 图形库 - 计时器

+
+
    +
  • 算法设计 1 寻找第一个公共节点
  • +
+
+

想象这样一个情境:还是想象你和你的朋友站在题目所示的两个链表的起始处。这两个链表有可能相交,你们想要尽快找到会合点,怎么办呢?而且一个有用的信息是,你们都知道自己离终点还有多远。

+

如果相交,你们肯定有公共子链表。剩下不同的部分就是你们各自子链表的长度。因此,你们应当先相对终点对齐彼此的位置,使自己剩余的子链表的的长度相等。接下来以相同的速度前进,如果你们在某处会合了,那么这一定是公共子链表的起始处。

+

参答中,lPtr 指向较长的链表,sPtr 指向较短的链表,numLeftNodes 就是两链表节点数的差值,lPtr=lPtr->nextfor 循环就是在对齐两人的位置。

+

循环终止的条件是:其中某人走到了尽头 NULL,或两人相遇 lPtr==sPtr。返回最终位置即可。

+
+
    +
  • 算法设计 2 二分插入排序
  • +
+
+

这题简单,不作解析。参答中漏了检查 minPos == rh 的情况,想想这样会造成什么后果?

+
+

2017-2018 年卷

+
    +
  • 选择题 1 数据类型与指针操作
  • +
+
+
    +
  • C 项:strcpy() 只能用于字符串。进一步说,它依据字符串末尾的 \0 来决定是否停止复制,因此不宜用于此情境。
  • +
  • D 项:每次 *pc2++ = *pc1++,都会将 pc1 的一个字节拷贝到 pc2 指向的位置,并让这两个指针向后移动一个 char 的位置。由于 p1p2 两个结构变量大小都是 \(8+8=16\) 字节,因此该选项正确地执行了拷贝。
  • +
+
+
    +
  • 选择题 7 冒泡排序
  • +
+
+

这道题时,我选的是 D 项。因为我记忆中的冒泡排序是这样的:

+
void bubble_sort(int *arr, int len) {
+ int i, j, tmp;
+ for (i = 0; i < len - 1; i++) {
+     for (j = len - 1; j > i; j--) {//Bubble
+         if (arr[j] < arr[j - 1]) {
+             tmp = arr[j];
+             arr[j] = arr[j - 1];
+             arr[j - 1] = tmp;
+         }
+     }
+ }
+}
+
+

上面这样的写法对于任何情况的复杂度都是 \(O(n^2)\)。但是冒泡排序普遍会作这样的优化:

+
    +
  • 如果在上一轮的 Bubble 中,没有发生任何交换,则说明这个序列也是有序的,不再需要后续操作了。
  • +
+

因此可以在外循环开头添加 bool flag = 0;,结尾添加 if(!flag)break;,交换操作中添加 flag=true 即可将最优情况优化至 \(O(n)\)

+
+
    +
  • 选择题 9 存储类别限定符
  • +
+
+
    +
  • D 项:static 此处修饰的是指针 p。事实上,也不存在指针指向 static int 这种说法。static 作为存储类别限定符,在变量的声明中表示该变量具有静态存储期。一个指针,只需要管它指向的是什么类型,不需要知道这个对象的存储期。
  • +
+
+
    +
  • 简答题 1.(2) 写函数声明
  • +
+
+

先想想自己会怎么调用这个 fun 函数才能得到 void 类型:

+
    +
  • 第一步,调用函数获取返回值:fun(int)
  • +
  • 第二步,解引用返回值,获得函数,调用该函数:(*fun(int))(int)。注意,函数指针应当使用 (*fp)() 形式调用。
  • +
+

得到了答案:void (*fun(int))(int)

+
+
    +
  • 简答题 5 最大子列和
  • +
+
+

其实这是一个经典的算法:所有连续子列元素的和中最大者。在网上可以搜到很多该算法的原理介绍,请去看一看,看完就能立刻明白这段代码了。

+

thisp 被放置在最大子列的开头,maxp 被放置在最大子列的末尾。

+
+
    +
  • 简答题 6 侏儒排序
  • +
+
+

基于比较的排序算法,大概都能优化到最优情况复杂度为 \(O(n)\) 吧?

+
+
    +
  • 程序填空 2 多项式计算
  • +
+
+

这题蛮坑的,我看了好一会儿才明白第 (7)(8) 空在干嘛。它其实就是先把前面的高次项提公因式,然后在逐步向后求和的过程给它整体乘上 \(x\)。比如 \(3x^4+2x^2+1\) 可以这样计算:

+
    +
  • \((((3x)x^2)+2x)x + 1\)
  • +
+

这样做一定程度上减少了计算乘积的次数。

+

同样注意 -> 运算符的使用。

+
+

2016-2017 年卷

+
    +
  • 选择题 1 倒序栈
  • +
+
+

注意题目中说明了栈顶指针位于 N,这个栈是从数组的尾部开始累积的。

+
+
    +
  • 简答题 1.(2) 写函数指针
  • +
+
+

简单函数指针,直接这样记:typedef 返回类型 (*新名字)(参数列表)

+
+
    +
  • 简答题 3 奇偶排序
  • +
+
+

和前一年的侏儒排序有点像,有序情况也是一遍过,最优时间复杂度也是 \(O(n)\)

+
+
    +
  • 简答题 4 链表操作
  • +
+
+

过程中,该链表顺序被重新排列。比 x 小的节点依次移动到 root 为首的带哨兵链表中,大的依次移动到 pivot 为首的哨兵链表中,最后将两个链表合并,返回合并后的链表。

+
+
    +
  • 简答题 5 因数分解
  • +
+
+

本题其实就是在从小到达求因数、约去这个因数、求下一个更大的因数 ...。模拟一遍即可。

+
+
    +
  • 程序填空 1 计数排序
  • +
+
+

排序原理题目已经讲清楚了,这里讲一下循环中几个变量的作用:

+
    +
  • count 数组:先用于统计出现次数,后用来标记开始位置。
  • +
  • output_array[count[input_array[i]]] = input_array[i] 我们来拆解一下:
      +
    • intput_array[i] 就是第 i 个元素
    • +
    • 把它放到 count[] 就能查到这个数应该放置的起始位置。
    • +
    • 所以第 4 空当然要递增啦。
    • +
    +
  • +
+
+
    +
  • 程序填空 3 差集
  • +
+
+

值得一提的是,这两个链表都是集合,这意味着其中的元素都是唯一的,所以不需要考虑重复元素的情况,不需要完整遍历 \(A\)

+
+

2015-2016 年卷

+
    +
  • 选择题 5 宏的展开
  • +
+
+

宏展开只是简单的文本替换。

+
    +
  • 先展开 DD 得到 SQ(2*3) - SQ(2+3),得到 2 * 3 * 2 * 3 - 2 + 3 * 2 + 3
  • +
  • 先展开 SQ 得到 DD(x, y) = x * x - y * y,得到 2 * 3 * 2 * 3 - 2 + 3 * 2 + 3
  • +
+

从上面的展开中我们看到,宏函数的展开顺序并不重要。最终结果应当一致。

+
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming/exam/lectures_on_c_programming/lcp13answer.pdf b/programming/exam/lectures_on_c_programming/lcp13answer.pdf new file mode 100644 index 0000000..8caee1d Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp13answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp13test.pdf b/programming/exam/lectures_on_c_programming/lcp13test.pdf new file mode 100644 index 0000000..58067a3 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp13test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp14answer.pdf b/programming/exam/lectures_on_c_programming/lcp14answer.pdf new file mode 100644 index 0000000..9909bb7 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp14answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp14test.pdf b/programming/exam/lectures_on_c_programming/lcp14test.pdf new file mode 100644 index 0000000..60f627b Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp14test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp15answer.pdf b/programming/exam/lectures_on_c_programming/lcp15answer.pdf new file mode 100644 index 0000000..1a898c5 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp15answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp15test.pdf b/programming/exam/lectures_on_c_programming/lcp15test.pdf new file mode 100644 index 0000000..d76cfe1 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp15test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp16answer.pdf b/programming/exam/lectures_on_c_programming/lcp16answer.pdf new file mode 100644 index 0000000..b3209f6 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp16answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp16test.pdf b/programming/exam/lectures_on_c_programming/lcp16test.pdf new file mode 100644 index 0000000..6fde34e Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp16test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp17answer.pdf b/programming/exam/lectures_on_c_programming/lcp17answer.pdf new file mode 100644 index 0000000..8b0df3d Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp17answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp17test.pdf b/programming/exam/lectures_on_c_programming/lcp17test.pdf new file mode 100644 index 0000000..0072851 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp17test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp18answer.pdf b/programming/exam/lectures_on_c_programming/lcp18answer.pdf new file mode 100644 index 0000000..337418f Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp18answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp18test.pdf b/programming/exam/lectures_on_c_programming/lcp18test.pdf new file mode 100644 index 0000000..9421eee Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp18test.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp19answer.pdf b/programming/exam/lectures_on_c_programming/lcp19answer.pdf new file mode 100644 index 0000000..467235d Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp19answer.pdf differ diff --git a/programming/exam/lectures_on_c_programming/lcp19test.pdf b/programming/exam/lectures_on_c_programming/lcp19test.pdf new file mode 100644 index 0000000..6133f71 Binary files /dev/null and b/programming/exam/lectures_on_c_programming/lcp19test.pdf differ diff --git a/programming/faq/index.html b/programming/faq/index.html new file mode 100644 index 0000000..b3aa966 --- /dev/null +++ b/programming/faq/index.html @@ -0,0 +1,1037 @@ + + + + + + + + + + + + +FAQ - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

常见问题

+

指针、声明

+

怎么读声明?

+ +

函数与函数指针

+
+

Author:45gfg9、Anston Sun

+
+

首先,让我介绍一下两个惹人喜爱的小家伙。

+
int function(int arg)
+{
+    return 2 * arg;
+}
+
+

一般通过函数,类型是 int (int)

+
int (*func_ptr)(int);
+
+

芝士什么?芝士函数指针,类型是 int (*)(int)

+

那么,这两个小家伙能干什么呢?

+
func_ptr = &function;
+func_ptr = function;
+
+

前者是什么?指针。没错,平平无奇的取地址操作,洒洒水啦。 +后者是什么?我们知道指针的值实际上是某块内存地址,不考虑奇技淫巧的话,将所指对象的值赋值给指针是没有意义的。但是,将函数指代器 function 赋值给函数指针 func_ptr,却没有产生任何问题。

+

坏了,自动播放妈妈生的,大脑要打高端局了。不过你先别急,这个看起来不知所云的赋值语句,其实与前者完全等效。C 标准是仁慈的,它不忍心看到被函数绕晕的初学者面对错误的解引用不知所措,于是规定了函数到指针的隐式转换

+
+

函数到指针转换

+

任何函数指代器表达式,在用于异于下列语境

+
    +
  • 作为取址运算符的操作数
  • +
  • 作为 sizeof 的操作数
  • +
+

会经历到指向表达式所指代函数的指针的转换。

+
+

这里 function 经过一次隐式转换变成 &function。这一步转换并不改变值,而类型从 int (int) 变成 int (*)(int) 了。也就是实际上在编译器看来,第二行就是第一行。

+

现在你已经对函数和函数指针有了一定了解,就让我们看一看下面这个简单的例子,把我们已经学到的知识运用到实践中吧。

+

请解释以下代码的作用:

+
// 试试看!
+(*(void(*)())0)();
+
+

好吧,这样的表达式或许对你来说为时尚早。我们换一个简单点的例子。

+
function(20);
+(function)(20);
+(*&function)(20);
+(&function)(20);
+(*function)(20);
+(***********function)(20); // 不用数了,11 个
+
+

先不管第六个是什么东西。我们看看前五个。

+

第一个不能再熟悉了,一个人畜无害的函数调用。

+

第二个看着和第一个差不多……没错,相信自己,它们完全一样。

+

第三个呢?没错,取地址再解引用,除了出题没有用。连编译器都会毫不犹豫地优化掉。

+

第四个开始奇怪了起来。缺失的解引用并非粗心大意,它象征着我们玩转指针的自信与惬意,以及捍卫指针地位的决心。鉴于 C 标准允许通过函数指针调用函数,编译器对此也没什么意见。

+

第五个换了种折磨方式。聪明如你早已料到最后的结果。但是为什么?引言定真,鉴定为隐式转换惯的。回忆一下函数到指针的隐式转换*function 等效于 *&function,这下看懂了。

+

现在第六个你应该也能理解了。每次尝试对 function 解引用,都会迫使编译器将它转换为函数指针,以满足你对代码风格的奇怪癖好。

+

还是看看远处的 func_ptr 吧家人们。

+
(*func_ptr)(20);
+func_ptr(20);
+(****func_ptr)(20);
+(&func_ptr)(20);
+
+

第一个,简单易懂的指针解引用,相当于上面的第二个。

+

第二个,人畜无害的函数指针调用函数,相当于上面的第四个。

+

第三个,函数到指针的隐式转换发生了整整三回啊三回,类似上面的第六个。

+

第四个,编译器跟你爆了。怎么会是呢?我们不妨拆开看看:

+
int (*func_ptr)(int) = &function;    // 这是之前的
+int (**second_ptr)(int) = &func_ptr; // 这是我们正在做的
+second_ptr(20);                      // 我们想这样
+
+

在这里,second_ptr 已经是个二级指针了。函数到函数指针(它是个一级指针)的变化,地址值是不会改变的,就是这个函数的可执行代码所在的位置。问题在于,二级指针的值不是 function 的地址,而是 func_ptr 这个变量的地址。这还得了,骗自己可以,骗兄弟也就算了,编译器可不吃你这套。

+

接下来,我们再看点不太一样的:

+
int func_two(int a, int f(int arg))
+{
+    return 3 * f(a);
+}
+
+

这是什么?函数,调用一下:

+
// function 如上文定义
+int function(int arg);
+
+int a = 1;
+int b = func_two(a, function);
+
+

相信聪明的你已经猜到了,b 的值就是 6。桥豆麻袋,好像有哪里不太对劲。func_two 的两个参数类型分别是 intint (int),但是调用时却传入了一个函数指针(还记得隐式转换吗,这却没有产生任何问题。这又是什么操作?

+

又是隐式转换?Bingo!不过需要注意发生隐式转换的位置。func_two 的第二个形参实际上是 int (*)(int) ,而非字面上的 int (int)。这就和 void f(int a[]) 实际上就是 void f(int *a) 一样,同样是出于节约资源的考虑。也就是说,编译器眼中的 func_twoint func_two(int a, int (*f)(int)。搞清楚这一点,其余部分也就顺理成章了。

+

经过练习,你应该已经可以看出,从函数到指针的隐式转换规定出发,理解上述情景并非难事。对函数指针的畏惧,往往是因为不熟悉转换规则,或受复杂的声明语法干扰。因此,提高识别类型的熟练度,足以让你自信运用函数指针。

+

图形库

+

简要整理一下 libgraphics 用法:

+

必备函数

+

图形与文字

+
+

值得注意的一点是:libgraphics 的坐标系统与 ACLLib 不同。前者以左下角为原点,符合我们常用的数学表达;后者以左上角为顶点,使用窗口坐标系统。

+

+
+
    +
  • void InitGraphics(void):使用图形库中的函数前调用
  • +
  • void MovePen(double x, double y):将笔移动到某点(注意不是相对移动)
  • +
  • void DrawLine(double dx, double dy):从当前点 \((x,y)\) 画到 \((x+dx, y+dy)\) 的线,画笔随之移动
  • +
  • void DrawArc(double r, double start, double sweep):以当前点为圆心,从 \(\phi=start\) 角开始,画半径为 \(r\),圆心角为 \(\Delta\phi=sweep\) 的圆弧。
  • +
  • double GetWindowWidth(void):获取窗口宽度
  • +
  • double GetWindowHeight(void)
  • +
  • double GetCurrentX(void):获取当前画笔的位置
  • +
  • double GetCurrentY(void)
  • +
  • void DrawTextString(string text):在当前位置打印字符串
  • +
  • double TextStringWidth(string text):获取该字符串打印时的宽度
  • +
+

关于 SetEraseMode()GetEraseMode() 我直接把注释贴在这了,直接读吧:

+
/*
+ * Function: SetEraseMode
+ * Usage: SetEraseMode(TRUE);
+ *        SetEraseMode(FALSE);
+ * ---------------------------
+ * The SetEraseMode function sets the value of the internal
+ * erasing flag.  Setting this flag is similar to setting the
+ * color to "White" in its effect but does not affect the
+ * current color setting.  When erase mode is set to FALSE,
+ * normal drawing is restored, using the current color.
+ */
+
+void SetEraseMode(bool mode);
+
+/*
+ * Function: GetEraseMode
+ * Usage: mode = GetEraseMode();
+ * -----------------------------
+ * This function returns the current state of the erase mode flag.
+ */
+
+bool GetEraseMode(void);
+
+
+

还是附个翻译吧:SetEraseMode 函数设置内部擦除标志的值。设置这个值的效果就像把颜色设置为“白色”,但不会影响当前的颜色设置。当擦除模式设置为 FALSE 时,恢复到正常的绘画状态,使用当前的颜色。

+
+

控制台交互:这些源代码在 simpio.h

+
    +
  • +

    void InitConsole(void):打开一个新的控制台,要使用 stdio.h 中的标准输入输出函数前记得写上这个。

    +
  • +
  • +

    int GetInteger(void):从标准输入中读入一行,并尝试读取一个整数。如果遇到意外情况,会要求用户重新输入。源码如下:

    +
    int GetInteger(void)
    +{
    +    string line;
    +    int value;
    +    char termch;
    +
    +    while (TRUE) {
    +        line = GetLine();
    +        if (line == NULL) Error("GetInteger: unexpected end of file");
    +        switch (sscanf(line, " %d %c", &value, &termch)) {
    +          case 1:
    +            FreeBlock(line);
    +            return (value);
    +          case 2:
    +            printf("Unexpected character: '%c'\n", termch);
    +            break;
    +          default:
    +            printf("Please enter an integer\n");
    +            break;
    +        }
    +        FreeBlock(line);
    +        printf("Retry: ");
    +    }
    +}
    +
    +
  • +
  • +

    double GetReal(void):读取一个实数,具体同上。

    +
  • +
  • +

    string GetLine(void)

    +
  • +
  • +

    string ReadLine(FILE *infile):从指定的文件中读入一行。

    +
  • +
+

定时启动——计时器回调

+

计时器用于延时或重复执行同类任务。相比钟表等纯粹的计时工具,计时器更接近于日程安排。计时器的核心功能如下:每经过预先设定的时长,计时器便会通过某种机制,执行特定的指令

+

libgraphics 库通过事件回调机制实现定时触发的功能。回调机制此处不再赘述。

+

计时器

+

与计时器相关的函数如下:

+
    +
  • void startTimer(int timerID, int interval)
  • +
  • void cancelTimer(int timerID)
  • +
+

顾名思义,两个函数分别用于启动与终止定时器。interval预先设定的时长,即每两次触发的时间间隔。timerID 为计时器的标识符,可理解为计时器的专用名称。

+

为了完成多项定时任务,往往需要分别启动多个间隔不同的定时器。由于所有计时器均会触发 TimerEvent,在回调函数内需要使用 timerID 区分不同的定时器。

+

回调注册函数

+
    +
  • void registerTimerEvent(TimerEventCallback):注册计时器事件。 TimerEventCallback 类型见下。
  • +
+

回调函数

+
    +
  • typedef void (*TimerEventCallback)(int timerID)
  • +
+

TimerEventCallback 是一个函数指针类型,该类型变量指向函数(假设名称为 func)的类型为 void func(int timerID)。通过回调机制,每当任一计时器到达设定时间时,均会通过该类型函数指针调用 func 函数。通过传入的 timerID,回调函数内可以区分不同计时器的触发事件,并执行特定操作。

+

补充思考

+

以上介绍均集中于重复执行,但是前面提到计时器也可用于延时执行,即在预先设定的时长后执行特定次数特定操作。结合 cancelTimer 函数,想想怎样实现这一目标。

+

回调函数

+
typedef void (*KeyboardEventCallback) (int key,int event);
+typedef void (*CharEventCallback) (char c);
+typedef void (*MouseEventCallback) (int x, int y, int button, int event);
+typedef void (*TimerEventCallback) (int timerID);
+
+void registerKeyboardEvent(KeyboardEventCallback callback);
+void registerCharEvent(CharEventCallback callback);
+void registerMouseEvent(MouseEventCallback callback);
+void registerTimerEvent(TimerEventCallback callback);
+void startTimer(int id,int timeinterval);
+
+

因为这些回调函数在 graphics 库中都没有注释,我就不作解释了,课上都讲过回调函数怎么用。

+
    +
  • +

    计时器:以 20 年程序填空第 3 题为例:

    +
    void Main()
    +{
    +    InitGraphics();
    +    registerTimerEvent(TimerEventProcess);
    +    //...
    +    startTimer(TIMER_CURSOR, 500);/*start 500ms cursor blinking timer*/
    +}
    +void TimerEventProcess(int timerID)
    +{
    +    bool erasemode;
    +    if(TIMER_CURSOR == timerID)
    +    {
    +        //...
    +    }
    +}
    +
    +

    从这段例程中可以了解到几个重要的点:

    +
      +
    • 使用 void registerTimerEvent(TimerEventCallback callback) 注册回调函数 callback 后,还需要用 void startTimer(int id,int timeinterval) 设定并启动一个计时器,设定这个计时器的 idtimeinterval
    • +
    • 每当计时器到达指定时间后,计时器就会调用所有的回调函数,回调函数会接收这个计时器的 id 并检查是不是自己需要进行动作的那个计时器。这就是 TimerEventProcess 函数中 if 语句的作用。
    • +
    +
  • +
+

使用方法

+
    +
  • 主函数是 void Main() 别写错了
  • +
  • 下面是一个最简单的例程:
  • +
+
#include <stdio.h>
+#include "graphics.h"
+
+void Main(void)
+{
+    InitGraphics();
+    MovePen(1.5, 1.0);
+    DrawArc(0.5, 0, 360);
+}
+
+

New() 函数

+

向下翻,找到 2019 年程序填空第 3 题,使用方法在那里。

+

算法复杂度分析

+
    +
  • +

    记住:排序算法的时间复杂度与两项操作的次数有关:比较交换

    +
      +
    • +

      你可以这样想:创建一个全局变量作为计数器,在所有涉及比较和交换的地方让它 ++,运行完的结果就是其时间复杂度。比如:

      +
      int count = 0;
      +for (int i = 0; i < n; ++i) {
      +  for (int j = 0; j < n; ++j) {
      +    for (int k = 0; k < m; ++k) {
      +        count++;
      +    }
      +  }
      +}
      +
      +

      运行完这段代码,count = n*n*m,则其时间复杂度为 \(O(n^2m)\)

      +
    • +
    +
  • +
  • +

    记住并理解一些常见的算法的平均时间复杂度、最优、最差情况复杂度:image-20230623223659304

    +

    来源:常用排序算法总结对比 | 数据结构与算法 系列教程(笔记) (zq99299.github.io)

    +
  • +
+

后缀表达式

+

这东西前两三年都考了,需要了解一下。关于表达式树的相关内容请参见:

+ +

在前缀、中缀、后缀表达式之间进行转换的最好方法是将其想象成一个树状结构。

+

+
    +
  • 中缀表达式:对这棵树进行中序遍历,即左、根、右
      +
    • a+b*(c-d)-(e/f)
    • +
    +
  • +
  • 前缀表达式:对这棵树进行先序遍历,即根、左、右
      +
    • -+a*b-cd/ef
    • +
    +
  • +
  • 后缀表达式:对这棵树进行后序遍历,即左、右、根。注意到左右子节点都比根先遍历,所以可以一路往下找到最深的子节点,然后向上解析。
      +
    • abcd-*+ef/-
    • +
    +
  • +
+

值得一提的是后缀表达式具有几个方便的性质:

+
    +
  • 计算后缀表达式,只需要维护一个数字栈,每次遇到一个运算符,就取出两个栈顶元素,将运算结果重新压入栈中。
  • +
  • 后缀表达式与表达式树一一对应。后缀表达式不需要括号表示,它的运算顺序是唯一确定的。
  • +
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming/index.html b/programming/index.html new file mode 100644 index 0000000..e4ff9f7 --- /dev/null +++ b/programming/index.html @@ -0,0 +1,641 @@ + + + + + + + + + + + + +程序设计辅学 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

程序设计辅学

+

欢迎来到竺院辅学程设版块🤗。你可以在左侧导航栏中详细浏览本模块的内容。

+

FAQ

+

我们为各个模块同学们经常遇到的问题整理了一些 FAQ

+ + + + + + + + + + + + + +
知识模块FAQ
暂无暂无
+

历年卷

+

请跳转到 历年卷 页面。历年卷均已上传完成,经典题目解析还在整理中。

+

其他资源

+

常用网站

+
    +
  • CPPReferenceC/C++ 参考手册,可以查找 C/C++ 语法和标准库的用法等。
  • +
+

学长学姐的笔记本

+

很多学长学姐都在自己的博客 / 笔记本中写了一些关于程序设计的内容,这里列出一些链接,供大家参考。

+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/current.png b/programming_lecture/current.png new file mode 100644 index 0000000..1abffe4 Binary files /dev/null and b/programming_lecture/current.png differ diff --git a/programming_lecture/index.html b/programming_lecture/index.html new file mode 100644 index 0000000..f9afb81 --- /dev/null +++ b/programming_lecture/index.html @@ -0,0 +1,678 @@ + + + + + + + + + + + + +程设辅学课程 系统知识拾遗 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

程设辅学课程 系统知识拾遗

+

欢迎来到竺院程设辅学系统知识拾遗版块 🤗。你可以在左侧导航栏中详细浏览本模块的内容。

+ +
+

本期课程

+

+
+ +

课程简介

+

程序设计与算法基础课程讲述的内容局限于语言本身,较为表象。然而,C 语言实质上是一门很难的编程语言,不懂编译原理、操作系统和计算机体系结构无法获得深入的理解,而这些也是学习计算机专业的同学应当尽早了解的知识。

+

本辅学课程将结合计算机系统方面的知识,为同学们提供深入理解 C 语言的视角。我们的目的是解答程序设计中较为底层的问题:

+
    +
  • 编译时我的代码经历了什么?操作系统如何运行我的程序?如何使用调试器快速定位错误?
  • +
  • 指针究竟是什么?内存中的数据是如何组织的?
  • +
  • C 标准库中的 I/O 函数如何与操作系统交互?
  • +
  • C 标准库是如何编写的?怎样写出具有工业强度的健壮代码?
  • +
  • 如何使用数据结构与算法解决实际问题?
  • +
+

希望这些内容能够为你开启从 C 语言到计算机科学与技术的真正的大门。如果对课程内容有任何疑问和建议,欢迎你联系我们。你可以在仓库中发起 issue 或发送邮件到 zhubaolin228@gmail.com

+

课程安排

+

2023-2024 学年,程设辅学系统知识拾遗课题组同学有:

+
    +
  • 朱宝林 混合 2205
  • +
  • 李英琦 图灵 2201
  • +
  • 谢集 混合 2206
  • +
  • 胡育玮 混合 2206
  • +
  • 苏煜程 图灵 2201
  • +
  • 孙兆江 混合 2204
  • +
+

课程安排如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
节次内容主讲时间地点课前资料PPT 与讲义
1程序编译过程与调试技术朱宝林10.14 下午 2:30-4:30准备开发与调试环境讲义
2类型系统与内存模型李英琦【暂定】10.21
3I/O 与文件胡育玮【暂定】11.18
4C 标准库李英琦【暂定】11.25
5数据结构与算法谢集
苏煜程
【暂定】12.15
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture1/code/debug.c b/programming_lecture/lecture1/code/debug.c new file mode 100644 index 0000000..aa9e3a8 --- /dev/null +++ b/programming_lecture/lecture1/code/debug.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + printf("printf "); + fprintf(stderr, "fprintf "); + abort(); +} \ No newline at end of file diff --git a/programming_lecture/lecture1/code/error.c b/programming_lecture/lecture1/code/error.c new file mode 100644 index 0000000..0eee7f8 --- /dev/null +++ b/programming_lecture/lecture1/code/error.c @@ -0,0 +1,11 @@ +// This program will produce error and cannot be compiled. +#include + +void my_print(void){ + printf("Hello World\n"); +} + +int main(void){ + my_print(1); + return 0; +} \ No newline at end of file diff --git a/programming_lecture/lecture1/code/gets.c b/programming_lecture/lecture1/code/gets.c new file mode 100644 index 0000000..e3037ec --- /dev/null +++ b/programming_lecture/lecture1/code/gets.c @@ -0,0 +1,26 @@ +#include + +char *gets(char *s) +{ + int c; + char *dest = s; + while((c = getchar()) != '\n' && c != EOF) + *dest++ = c; + if(c == EOF && dest == s) + return NULL; + *dest++ = '\0'; + return s; +} + +void echo() +{ + char buf[8]; + gets(buf); + puts(buf); +} + +int main() +{ + echo(); + return 0; +} diff --git a/programming_lecture/lecture1/code/hello.c b/programming_lecture/lecture1/code/hello.c new file mode 100644 index 0000000..23f7fd3 --- /dev/null +++ b/programming_lecture/lecture1/code/hello.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + printf("Hello World.\n"); + return 0; +} diff --git a/programming_lecture/lecture1/code/hello.i b/programming_lecture/lecture1/code/hello.i new file mode 100644 index 0000000..e2b8ccb --- /dev/null +++ b/programming_lecture/lecture1/code/hello.i @@ -0,0 +1,745 @@ +# 0 "hello.c" +# 0 "" +# 0 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 0 "" 2 +# 1 "hello.c" +# 1 "/usr/include/stdio.h" 1 3 4 +# 27 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4 +# 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4 +# 1 "/usr/include/features.h" 1 3 4 +# 393 "/usr/include/features.h" 3 4 +# 1 "/usr/include/features-time64.h" 1 3 4 +# 20 "/usr/include/features-time64.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 21 "/usr/include/features-time64.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 1 3 4 +# 19 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 20 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 2 3 4 +# 22 "/usr/include/features-time64.h" 2 3 4 +# 394 "/usr/include/features.h" 2 3 4 +# 487 "/usr/include/features.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4 +# 561 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 562 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4 +# 563 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4 +# 488 "/usr/include/features.h" 2 3 4 +# 511 "/usr/include/features.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4 +# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4 +# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4 +# 512 "/usr/include/features.h" 2 3 4 +# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4 +# 28 "/usr/include/stdio.h" 2 3 4 + + + + + +# 1 "/usr/lib/gcc/x86_64-linux-gnu/12/include/stddef.h" 1 3 4 +# 214 "/usr/lib/gcc/x86_64-linux-gnu/12/include/stddef.h" 3 4 + +# 214 "/usr/lib/gcc/x86_64-linux-gnu/12/include/stddef.h" 3 4 +typedef long unsigned int size_t; +# 34 "/usr/include/stdio.h" 2 3 4 + + +# 1 "/usr/lib/gcc/x86_64-linux-gnu/12/include/stdarg.h" 1 3 4 +# 40 "/usr/lib/gcc/x86_64-linux-gnu/12/include/stdarg.h" 3 4 +typedef __builtin_va_list __gnuc_va_list; +# 37 "/usr/include/stdio.h" 2 3 4 + +# 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4 +# 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 1 3 4 +# 19 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4 +# 20 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 2 3 4 +# 29 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 + + +typedef unsigned char __u_char; +typedef unsigned short int __u_short; +typedef unsigned int __u_int; +typedef unsigned long int __u_long; + + +typedef signed char __int8_t; +typedef unsigned char __uint8_t; +typedef signed short int __int16_t; +typedef unsigned short int __uint16_t; +typedef signed int __int32_t; +typedef unsigned int __uint32_t; + +typedef signed long int __int64_t; +typedef unsigned long int __uint64_t; + + + + + + +typedef __int8_t __int_least8_t; +typedef __uint8_t __uint_least8_t; +typedef __int16_t __int_least16_t; +typedef __uint16_t __uint_least16_t; +typedef __int32_t __int_least32_t; +typedef __uint32_t __uint_least32_t; +typedef __int64_t __int_least64_t; +typedef __uint64_t __uint_least64_t; + + + +typedef long int __quad_t; +typedef unsigned long int __u_quad_t; + + + + + + + +typedef long int __intmax_t; +typedef unsigned long int __uintmax_t; +# 141 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4 +# 142 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/time64.h" 1 3 4 +# 143 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4 + + +typedef unsigned long int __dev_t; +typedef unsigned int __uid_t; +typedef unsigned int __gid_t; +typedef unsigned long int __ino_t; +typedef unsigned long int __ino64_t; +typedef unsigned int __mode_t; +typedef unsigned long int __nlink_t; +typedef long int __off_t; +typedef long int __off64_t; +typedef int __pid_t; +typedef struct { int __val[2]; } __fsid_t; +typedef long int __clock_t; +typedef unsigned long int __rlim_t; +typedef unsigned long int __rlim64_t; +typedef unsigned int __id_t; +typedef long int __time_t; +typedef unsigned int __useconds_t; +typedef long int __suseconds_t; +typedef long int __suseconds64_t; + +typedef int __daddr_t; +typedef int __key_t; + + +typedef int __clockid_t; + + +typedef void * __timer_t; + + +typedef long int __blksize_t; + + + + +typedef long int __blkcnt_t; +typedef long int __blkcnt64_t; + + +typedef unsigned long int __fsblkcnt_t; +typedef unsigned long int __fsblkcnt64_t; + + +typedef unsigned long int __fsfilcnt_t; +typedef unsigned long int __fsfilcnt64_t; + + +typedef long int __fsword_t; + +typedef long int __ssize_t; + + +typedef long int __syscall_slong_t; + +typedef unsigned long int __syscall_ulong_t; + + + +typedef __off64_t __loff_t; +typedef char *__caddr_t; + + +typedef long int __intptr_t; + + +typedef unsigned int __socklen_t; + + + + +typedef int __sig_atomic_t; +# 39 "/usr/include/stdio.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 1 3 4 + + + + +# 1 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 1 3 4 +# 13 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 3 4 +typedef struct +{ + int __count; + union + { + unsigned int __wch; + char __wchb[4]; + } __value; +} __mbstate_t; +# 6 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 2 3 4 + + + + +typedef struct _G_fpos_t +{ + __off_t __pos; + __mbstate_t __state; +} __fpos_t; +# 40 "/usr/include/stdio.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 1 3 4 +# 10 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 3 4 +typedef struct _G_fpos64_t +{ + __off64_t __pos; + __mbstate_t __state; +} __fpos64_t; +# 41 "/usr/include/stdio.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/types/__FILE.h" 1 3 4 + + + +struct _IO_FILE; +typedef struct _IO_FILE __FILE; +# 42 "/usr/include/stdio.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/types/FILE.h" 1 3 4 + + + +struct _IO_FILE; + + +typedef struct _IO_FILE FILE; +# 43 "/usr/include/stdio.h" 2 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 1 3 4 +# 35 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 3 4 +struct _IO_FILE; +struct _IO_marker; +struct _IO_codecvt; +struct _IO_wide_data; + + + + +typedef void _IO_lock_t; + + + + + +struct _IO_FILE +{ + int _flags; + + + char *_IO_read_ptr; + char *_IO_read_end; + char *_IO_read_base; + char *_IO_write_base; + char *_IO_write_ptr; + char *_IO_write_end; + char *_IO_buf_base; + char *_IO_buf_end; + + + char *_IO_save_base; + char *_IO_backup_base; + char *_IO_save_end; + + struct _IO_marker *_markers; + + struct _IO_FILE *_chain; + + int _fileno; + int _flags2; + __off_t _old_offset; + + + unsigned short _cur_column; + signed char _vtable_offset; + char _shortbuf[1]; + + _IO_lock_t *_lock; + + + + + + + + __off64_t _offset; + + struct _IO_codecvt *_codecvt; + struct _IO_wide_data *_wide_data; + struct _IO_FILE *_freeres_list; + void *_freeres_buf; + size_t __pad5; + int _mode; + + char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)]; +}; +# 44 "/usr/include/stdio.h" 2 3 4 +# 52 "/usr/include/stdio.h" 3 4 +typedef __gnuc_va_list va_list; +# 63 "/usr/include/stdio.h" 3 4 +typedef __off_t off_t; +# 77 "/usr/include/stdio.h" 3 4 +typedef __ssize_t ssize_t; + + + + + + +typedef __fpos_t fpos_t; +# 133 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4 +# 134 "/usr/include/stdio.h" 2 3 4 +# 143 "/usr/include/stdio.h" 3 4 +extern FILE *stdin; +extern FILE *stdout; +extern FILE *stderr; + + + + + + +extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__)); + +extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__)); + + + +extern int renameat (int __oldfd, const char *__old, int __newfd, + const char *__new) __attribute__ ((__nothrow__ , __leaf__)); +# 178 "/usr/include/stdio.h" 3 4 +extern int fclose (FILE *__stream); +# 188 "/usr/include/stdio.h" 3 4 +extern FILE *tmpfile (void) + __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; +# 205 "/usr/include/stdio.h" 3 4 +extern char *tmpnam (char[20]) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + +extern char *tmpnam_r (char __s[20]) __attribute__ ((__nothrow__ , __leaf__)) ; +# 222 "/usr/include/stdio.h" 3 4 +extern char *tempnam (const char *__dir, const char *__pfx) + __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (__builtin_free, 1))); + + + + + + +extern int fflush (FILE *__stream); +# 239 "/usr/include/stdio.h" 3 4 +extern int fflush_unlocked (FILE *__stream); +# 258 "/usr/include/stdio.h" 3 4 +extern FILE *fopen (const char *__restrict __filename, + const char *__restrict __modes) + __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; + + + + +extern FILE *freopen (const char *__restrict __filename, + const char *__restrict __modes, + FILE *__restrict __stream) ; +# 293 "/usr/include/stdio.h" 3 4 +extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; +# 308 "/usr/include/stdio.h" 3 4 +extern FILE *fmemopen (void *__s, size_t __len, const char *__modes) + __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; + + + + +extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ; +# 328 "/usr/include/stdio.h" 3 4 +extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)); + + + +extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf, + int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__)); + + + + +extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf, + size_t __size) __attribute__ ((__nothrow__ , __leaf__)); + + +extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + + + + + + + +extern int fprintf (FILE *__restrict __stream, + const char *__restrict __format, ...); + + + + +extern int printf (const char *__restrict __format, ...); + +extern int sprintf (char *__restrict __s, + const char *__restrict __format, ...) __attribute__ ((__nothrow__)); + + + + + +extern int vfprintf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg); + + + + +extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg); + +extern int vsprintf (char *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) __attribute__ ((__nothrow__)); + + + +extern int snprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, ...) + __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int vsnprintf (char *__restrict __s, size_t __maxlen, + const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0))); +# 403 "/usr/include/stdio.h" 3 4 +extern int vdprintf (int __fd, const char *__restrict __fmt, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__printf__, 2, 0))); +extern int dprintf (int __fd, const char *__restrict __fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + + + + + + + +extern int fscanf (FILE *__restrict __stream, + const char *__restrict __format, ...) ; + + + + +extern int scanf (const char *__restrict __format, ...) ; + +extern int sscanf (const char *__restrict __s, + const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__)); + + + + + +# 1 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 1 3 4 +# 119 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 1 3 4 +# 24 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 3 4 +# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4 +# 25 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 2 3 4 +# 120 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 2 3 4 +# 431 "/usr/include/stdio.h" 2 3 4 + + + +extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf") + + ; +extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf") + ; +extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__)) + + ; +# 459 "/usr/include/stdio.h" 3 4 +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, + __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 2, 0))) ; + + + + + +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__format__ (__scanf__, 1, 0))) ; + + +extern int vsscanf (const char *__restrict __s, + const char *__restrict __format, __gnuc_va_list __arg) + __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0))); + + + + + +extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf") + + + + __attribute__ ((__format__ (__scanf__, 2, 0))) ; +extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf") + + __attribute__ ((__format__ (__scanf__, 1, 0))) ; +extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__)) + + + + __attribute__ ((__format__ (__scanf__, 2, 0))); +# 513 "/usr/include/stdio.h" 3 4 +extern int fgetc (FILE *__stream); +extern int getc (FILE *__stream); + + + + + +extern int getchar (void); + + + + + + +extern int getc_unlocked (FILE *__stream); +extern int getchar_unlocked (void); +# 538 "/usr/include/stdio.h" 3 4 +extern int fgetc_unlocked (FILE *__stream); +# 549 "/usr/include/stdio.h" 3 4 +extern int fputc (int __c, FILE *__stream); +extern int putc (int __c, FILE *__stream); + + + + + +extern int putchar (int __c); +# 565 "/usr/include/stdio.h" 3 4 +extern int fputc_unlocked (int __c, FILE *__stream); + + + + + + + +extern int putc_unlocked (int __c, FILE *__stream); +extern int putchar_unlocked (int __c); + + + + + + +extern int getw (FILE *__stream); + + +extern int putw (int __w, FILE *__stream); + + + + + + + +extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + __attribute__ ((__access__ (__write_only__, 1, 2))); +# 632 "/usr/include/stdio.h" 3 4 +extern __ssize_t __getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; +extern __ssize_t getdelim (char **__restrict __lineptr, + size_t *__restrict __n, int __delimiter, + FILE *__restrict __stream) ; + + + + + + + +extern __ssize_t getline (char **__restrict __lineptr, + size_t *__restrict __n, + FILE *__restrict __stream) ; + + + + + + + +extern int fputs (const char *__restrict __s, FILE *__restrict __stream); + + + + + +extern int puts (const char *__s); + + + + + + +extern int ungetc (int __c, FILE *__stream); + + + + + + +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; + + + + +extern size_t fwrite (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s); +# 702 "/usr/include/stdio.h" 3 4 +extern size_t fread_unlocked (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream) ; +extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream); + + + + + + + +extern int fseek (FILE *__stream, long int __off, int __whence); + + + + +extern long int ftell (FILE *__stream) ; + + + + +extern void rewind (FILE *__stream); +# 736 "/usr/include/stdio.h" 3 4 +extern int fseeko (FILE *__stream, __off_t __off, int __whence); + + + + +extern __off_t ftello (FILE *__stream) ; +# 760 "/usr/include/stdio.h" 3 4 +extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos); + + + + +extern int fsetpos (FILE *__stream, const fpos_t *__pos); +# 786 "/usr/include/stdio.h" 3 4 +extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + +extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + +extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + +extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); +extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; +extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + + + + +extern void perror (const char *__s); + + + + +extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + + + +extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; +# 823 "/usr/include/stdio.h" 3 4 +extern int pclose (FILE *__stream); + + + + + +extern FILE *popen (const char *__command, const char *__modes) + __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (pclose, 1))) ; + + + + + + +extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__access__ (__write_only__, 1))); +# 867 "/usr/include/stdio.h" 3 4 +extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); + + + +extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ; + + +extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)); +# 885 "/usr/include/stdio.h" 3 4 +extern int __uflow (FILE *); +extern int __overflow (FILE *, int); +# 909 "/usr/include/stdio.h" 3 4 + +# 2 "hello.c" 2 + + +# 3 "hello.c" +int main(void) +{ + printf("Hello World.\n"); + return 0; +} diff --git a/programming_lecture/lecture1/code/hello.s b/programming_lecture/lecture1/code/hello.s new file mode 100644 index 0000000..ae723b1 --- /dev/null +++ b/programming_lecture/lecture1/code/hello.s @@ -0,0 +1,45 @@ + .file "hello.c" + .text + .section .rodata +.LC0: + .string "Hello World." + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + endbr64 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq .LC0(%rip), %rax + movq %rax, %rdi + call puts@PLT + movl $0, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (Ubuntu 12.3.0-1ubuntu1~23.04) 12.3.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/programming_lecture/lecture1/code/include/header.h b/programming_lecture/lecture1/code/include/header.h new file mode 100644 index 0000000..e69de29 diff --git a/programming_lecture/lecture1/code/log.txt b/programming_lecture/lecture1/code/log.txt new file mode 100644 index 0000000..6ca5364 --- /dev/null +++ b/programming_lecture/lecture1/code/log.txt @@ -0,0 +1,63 @@ +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 12.3.0-1ubuntu1~23.04' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +Supported LTO compression algorithms: zlib zstd +gcc version 12.3.0 (Ubuntu 12.3.0-1ubuntu1~23.04) +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-' + /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpdir prog- -dumpbase main.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s +GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu) + compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include" +#include "..." search starts here: +#include <...> search starts here: + /usr/lib/gcc/x86_64-linux-gnu/12/include + /usr/local/include + /usr/include/x86_64-linux-gnu + /usr/include +End of search list. +GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu) + compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +Compiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024 +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-' + as -v --64 -o /tmp/ccEgqpgY.o /tmp/ccClT5M4.s +GNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40 +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-' + /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu sum.c -quiet -dumpdir prog- -dumpbase sum.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s +GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu) + compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed" +ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include" +#include "..." search starts here: +#include <...> search starts here: + /usr/lib/gcc/x86_64-linux-gnu/12/include + /usr/local/include + /usr/include/x86_64-linux-gnu + /usr/include +End of search list. +GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu) + compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP + +GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +Compiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024 +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-' + as -v --64 -o /tmp/ccxMA26W.o /tmp/ccClT5M4.s +GNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40 +COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/ +LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../:/lib/:/usr/lib/ +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.' + /usr/lib/gcc/x86_64-linux-gnu/12/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper -plugin-opt=-fresolution=/tmp/ccyzC2ZB.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o prog /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/12/../../.. /tmp/ccEgqpgY.o /tmp/ccxMA26W.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o +COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.' diff --git a/programming_lecture/lecture1/code/main.c b/programming_lecture/lecture1/code/main.c new file mode 100644 index 0000000..c66f0e6 --- /dev/null +++ b/programming_lecture/lecture1/code/main.c @@ -0,0 +1,9 @@ +int sum(int *a, int n); + +int array[2] = {1, 2}; + +int main() +{ + int val = sum(array, 2); + return val; +} \ No newline at end of file diff --git a/programming_lecture/lecture1/code/sum.c b/programming_lecture/lecture1/code/sum.c new file mode 100644 index 0000000..9a06af6 --- /dev/null +++ b/programming_lecture/lecture1/code/sum.c @@ -0,0 +1,7 @@ +int sum(int *a, int n) +{ + int i, s = 0; + for (i = 0; i < n; i++) + s += a[i]; + return s; +} \ No newline at end of file diff --git a/programming_lecture/lecture1/code/warning.c b/programming_lecture/lecture1/code/warning.c new file mode 100644 index 0000000..840d316 --- /dev/null +++ b/programming_lecture/lecture1/code/warning.c @@ -0,0 +1,10 @@ +//This program will produce warning but will compile + +#include + +int main(void) +{ + double a = 1; + printf("a = %d\n", a); + return 0; +} \ No newline at end of file diff --git a/programming_lecture/lecture1/graph/Conline_index.png b/programming_lecture/lecture1/graph/Conline_index.png new file mode 100644 index 0000000..e96d885 Binary files /dev/null and b/programming_lecture/lecture1/graph/Conline_index.png differ diff --git a/programming_lecture/lecture1/graph/Conline_run.png b/programming_lecture/lecture1/graph/Conline_run.png new file mode 100644 index 0000000..ae9f1b5 Binary files /dev/null and b/programming_lecture/lecture1/graph/Conline_run.png differ diff --git a/programming_lecture/lecture1/graph/WinR.png b/programming_lecture/lecture1/graph/WinR.png new file mode 100644 index 0000000..37989bc Binary files /dev/null and b/programming_lecture/lecture1/graph/WinR.png differ diff --git a/programming_lecture/lecture1/graph/assembly.png b/programming_lecture/lecture1/graph/assembly.png new file mode 100644 index 0000000..9ceafc0 Binary files /dev/null and b/programming_lecture/lecture1/graph/assembly.png differ diff --git a/programming_lecture/lecture1/graph/chinese_english.png b/programming_lecture/lecture1/graph/chinese_english.png new file mode 100644 index 0000000..c8371be Binary files /dev/null and b/programming_lecture/lecture1/graph/chinese_english.png differ diff --git a/programming_lecture/lecture1/graph/cmd.png b/programming_lecture/lecture1/graph/cmd.png new file mode 100644 index 0000000..be1e11b Binary files /dev/null and b/programming_lecture/lecture1/graph/cmd.png differ diff --git a/programming_lecture/lecture1/graph/compile.png b/programming_lecture/lecture1/graph/compile.png new file mode 100644 index 0000000..8b0888e Binary files /dev/null and b/programming_lecture/lecture1/graph/compile.png differ diff --git a/programming_lecture/lecture1/graph/compiler.png b/programming_lecture/lecture1/graph/compiler.png new file mode 100644 index 0000000..b72d1dc Binary files /dev/null and b/programming_lecture/lecture1/graph/compiler.png differ diff --git a/programming_lecture/lecture1/graph/config_language.png b/programming_lecture/lecture1/graph/config_language.png new file mode 100644 index 0000000..3bbfdee Binary files /dev/null and b/programming_lecture/lecture1/graph/config_language.png differ diff --git a/programming_lecture/lecture1/graph/cpu.png b/programming_lecture/lecture1/graph/cpu.png new file mode 100644 index 0000000..b4800f7 Binary files /dev/null and b/programming_lecture/lecture1/graph/cpu.png differ diff --git a/programming_lecture/lecture1/graph/env_var.png b/programming_lecture/lecture1/graph/env_var.png new file mode 100644 index 0000000..5c93674 Binary files /dev/null and b/programming_lecture/lecture1/graph/env_var.png differ diff --git a/programming_lecture/lecture1/graph/gcc_process.png b/programming_lecture/lecture1/graph/gcc_process.png new file mode 100644 index 0000000..bf93340 Binary files /dev/null and b/programming_lecture/lecture1/graph/gcc_process.png differ diff --git a/programming_lecture/lecture1/graph/high_level_language.png b/programming_lecture/lecture1/graph/high_level_language.png new file mode 100644 index 0000000..4426002 Binary files /dev/null and b/programming_lecture/lecture1/graph/high_level_language.png differ diff --git a/programming_lecture/lecture1/graph/lose_dll.png b/programming_lecture/lecture1/graph/lose_dll.png new file mode 100644 index 0000000..dd6a345 Binary files /dev/null and b/programming_lecture/lecture1/graph/lose_dll.png differ diff --git a/programming_lecture/lecture1/graph/machine_code.png b/programming_lecture/lecture1/graph/machine_code.png new file mode 100644 index 0000000..5f021bc Binary files /dev/null and b/programming_lecture/lecture1/graph/machine_code.png differ diff --git a/programming_lecture/lecture1/graph/missing_library.webp b/programming_lecture/lecture1/graph/missing_library.webp new file mode 100644 index 0000000..d6f6d56 Binary files /dev/null and b/programming_lecture/lecture1/graph/missing_library.webp differ diff --git a/programming_lecture/lecture1/graph/newfile.png b/programming_lecture/lecture1/graph/newfile.png new file mode 100644 index 0000000..0200b4c Binary files /dev/null and b/programming_lecture/lecture1/graph/newfile.png differ diff --git a/programming_lecture/lecture1/graph/object_file.png b/programming_lecture/lecture1/graph/object_file.png new file mode 100644 index 0000000..c2cf3c4 Binary files /dev/null and b/programming_lecture/lecture1/graph/object_file.png differ diff --git a/programming_lecture/lecture1/graph/pc_right_attr.png b/programming_lecture/lecture1/graph/pc_right_attr.png new file mode 100644 index 0000000..7c3ae30 Binary files /dev/null and b/programming_lecture/lecture1/graph/pc_right_attr.png differ diff --git a/programming_lecture/lecture1/graph/plugin.png b/programming_lecture/lecture1/graph/plugin.png new file mode 100644 index 0000000..8b2ac44 Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin.png differ diff --git a/programming_lecture/lecture1/graph/plugin_WSL.png b/programming_lecture/lecture1/graph/plugin_WSL.png new file mode 100644 index 0000000..82ce069 Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin_WSL.png differ diff --git a/programming_lecture/lecture1/graph/plugin_ccpp.png b/programming_lecture/lecture1/graph/plugin_ccpp.png new file mode 100644 index 0000000..5290c84 Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin_ccpp.png differ diff --git a/programming_lecture/lecture1/graph/plugin_chinese.png b/programming_lecture/lecture1/graph/plugin_chinese.png new file mode 100644 index 0000000..25370ee Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin_chinese.png differ diff --git a/programming_lecture/lecture1/graph/plugin_remote.png b/programming_lecture/lecture1/graph/plugin_remote.png new file mode 100644 index 0000000..cdfcf8c Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin_remote.png differ diff --git a/programming_lecture/lecture1/graph/plugin_remote_detail.png b/programming_lecture/lecture1/graph/plugin_remote_detail.png new file mode 100644 index 0000000..9c9c9ea Binary files /dev/null and b/programming_lecture/lecture1/graph/plugin_remote_detail.png differ diff --git a/programming_lecture/lecture1/graph/pwsh.jpeg b/programming_lecture/lecture1/graph/pwsh.jpeg new file mode 100644 index 0000000..302a3f1 Binary files /dev/null and b/programming_lecture/lecture1/graph/pwsh.jpeg differ diff --git a/programming_lecture/lecture1/graph/risc_cpu.png b/programming_lecture/lecture1/graph/risc_cpu.png new file mode 100644 index 0000000..4ba3d91 Binary files /dev/null and b/programming_lecture/lecture1/graph/risc_cpu.png differ diff --git a/programming_lecture/lecture1/graph/tdm32_or_64.png b/programming_lecture/lecture1/graph/tdm32_or_64.png new file mode 100644 index 0000000..518bc5b Binary files /dev/null and b/programming_lecture/lecture1/graph/tdm32_or_64.png differ diff --git a/programming_lecture/lecture1/graph/tdmgcc_create.png b/programming_lecture/lecture1/graph/tdmgcc_create.png new file mode 100644 index 0000000..1c9afd4 Binary files /dev/null and b/programming_lecture/lecture1/graph/tdmgcc_create.png differ diff --git a/programming_lecture/lecture1/graph/tdmgcc_install_items.png b/programming_lecture/lecture1/graph/tdmgcc_install_items.png new file mode 100644 index 0000000..fdce677 Binary files /dev/null and b/programming_lecture/lecture1/graph/tdmgcc_install_items.png differ diff --git a/programming_lecture/lecture1/graph/tdmgcc_path.png b/programming_lecture/lecture1/graph/tdmgcc_path.png new file mode 100644 index 0000000..d994f8e Binary files /dev/null and b/programming_lecture/lecture1/graph/tdmgcc_path.png differ diff --git a/programming_lecture/lecture1/graph/terminal.jpg b/programming_lecture/lecture1/graph/terminal.jpg new file mode 100644 index 0000000..b6ecd55 Binary files /dev/null and b/programming_lecture/lecture1/graph/terminal.jpg differ diff --git a/programming_lecture/lecture1/graph/undefined_reference.png b/programming_lecture/lecture1/graph/undefined_reference.png new file mode 100644 index 0000000..a058ec0 Binary files /dev/null and b/programming_lecture/lecture1/graph/undefined_reference.png differ diff --git a/programming_lecture/lecture1/graph/vscode_autosave.png b/programming_lecture/lecture1/graph/vscode_autosave.png new file mode 100644 index 0000000..f9c9db5 Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_autosave.png differ diff --git a/programming_lecture/lecture1/graph/vscode_gccout_mac.png b/programming_lecture/lecture1/graph/vscode_gccout_mac.png new file mode 100644 index 0000000..958065a Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_gccout_mac.png differ diff --git a/programming_lecture/lecture1/graph/vscode_initUI.png b/programming_lecture/lecture1/graph/vscode_initUI.png new file mode 100644 index 0000000..454daf6 Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_initUI.png differ diff --git a/programming_lecture/lecture1/graph/vscode_newterminal.png b/programming_lecture/lecture1/graph/vscode_newterminal.png new file mode 100644 index 0000000..7091143 Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_newterminal.png differ diff --git a/programming_lecture/lecture1/graph/vscode_workdir_terminal.png b/programming_lecture/lecture1/graph/vscode_workdir_terminal.png new file mode 100644 index 0000000..ec2e542 Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_workdir_terminal.png differ diff --git a/programming_lecture/lecture1/graph/vscode_wsl_connected.png b/programming_lecture/lecture1/graph/vscode_wsl_connected.png new file mode 100644 index 0000000..fcde5fd Binary files /dev/null and b/programming_lecture/lecture1/graph/vscode_wsl_connected.png differ diff --git a/programming_lecture/lecture1/graph/win10_x64.png b/programming_lecture/lecture1/graph/win10_x64.png new file mode 100644 index 0000000..24d42c3 Binary files /dev/null and b/programming_lecture/lecture1/graph/win10_x64.png differ diff --git a/programming_lecture/lecture1/graph/win11_about.png b/programming_lecture/lecture1/graph/win11_about.png new file mode 100644 index 0000000..4b4e365 Binary files /dev/null and b/programming_lecture/lecture1/graph/win11_about.png differ diff --git a/programming_lecture/lecture1/graph/win_and_pwsh.png b/programming_lecture/lecture1/graph/win_and_pwsh.png new file mode 100644 index 0000000..1983e83 Binary files /dev/null and b/programming_lecture/lecture1/graph/win_and_pwsh.png differ diff --git a/programming_lecture/lecture1/graph/windows_terminal.png b/programming_lecture/lecture1/graph/windows_terminal.png new file mode 100644 index 0000000..70dcc6c Binary files /dev/null and b/programming_lecture/lecture1/graph/windows_terminal.png differ diff --git a/programming_lecture/lecture1/graph/wsl_terminal.png b/programming_lecture/lecture1/graph/wsl_terminal.png new file mode 100644 index 0000000..c8def46 Binary files /dev/null and b/programming_lecture/lecture1/graph/wsl_terminal.png differ diff --git a/programming_lecture/lecture1/graph/wsl_ubuntu_set.png b/programming_lecture/lecture1/graph/wsl_ubuntu_set.png new file mode 100644 index 0000000..abeed28 Binary files /dev/null and b/programming_lecture/lecture1/graph/wsl_ubuntu_set.png differ diff --git a/programming_lecture/lecture1/graph/you_and_shell.png b/programming_lecture/lecture1/graph/you_and_shell.png new file mode 100644 index 0000000..710e8c5 Binary files /dev/null and b/programming_lecture/lecture1/graph/you_and_shell.png differ diff --git a/programming_lecture/lecture1/lecture1/index.html b/programming_lecture/lecture1/lecture1/index.html new file mode 100644 index 0000000..a166f21 --- /dev/null +++ b/programming_lecture/lecture1/lecture1/index.html @@ -0,0 +1,1915 @@ + + + + + + + + + + + + +讲义:程序编译过程与调试技术 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

讲义:程序编译过程与调试技术

+ + +
+本页面正在施工中 +
+
+内容提要 +
    +
  • C 语言程序基本结构
  • +
  • 编译过程:从源代码到可执行文件
  • +
  • 编译器和开发套件:gccclangllvm 究竟是什么?
  • +
  • 调试器:如何使用 gdblldb 设置断点、找到段错误的根源?
  • +
+
+
+如何食用本讲义 +

作为在线讲义,我会尽量写得详细一些,为同学们提供复习和进一步扩展的指引。因为时间有限,在课上我无法覆盖讲义中所有的内容。同学们可以根据自己的习惯选择在课前课后浏览本讲义~

+

本次课的核心内容从「程序的编译过程」开始。前面的内容作为预备知识,在课上将会快速带过。

+
+ +

课程导言

+

Hi,欢迎各位同学来到竺院程设辅学「系统知识拾遗」的第一节课。

+

在前几周的程序设计课程中,老师们应该已经为同学们讲解了 C 语言的基础语法等知识。但是同学们或许会有下面这些疑问:

+
    +
  • 计算机是如何读懂我写的代码的?
  • +
  • 我的程序总是出问题,我该如何快速找到错误的根源?
  • +
+

辅学课程的目的就是帮助同学们解决这些进一步的问题。实质上 C 语言是一门很难的编程语言,不懂编译原理、操作系统和计算机体系结构无法获得深入的理解。我们希望通过线下授课,为同学们提供语言之外的进一步的知识扩展和技能训练。让同学们在计算机(而非算法题)的语境下理解 C 语言,理解程序设计。

+

那么在本节课,我们将为大家系统讲解程序编译过程与调试技术,为后续的课程做铺垫。接下来,让我们一起进入计算机的世界吧!

+

基础知识

+

首先,我们来了解一下我们学习的对象——计算机的基本知识。它是如何工作的?我们如何与它交流?

+

计算机能做什么?

+

现代计算机由多种部件构成,比如中央处理单元(Central Processing Unit,CPU、随机存取内存(Random Access Memory,RAM、硬盘(Hard Disk)等。其中 CPU 负责处理程序。

+ +
+
+
+
+
+
+

RISC CPU

+

这是一个非常简单的 CPU 的电路,它能够执行你用 0 1 编写的机器指令。

+
+
+
+
+
+
+
+
+
+

CPU 基本结构

+

CPU 主要由控制单元、算术逻辑单元和寄存器组成。控制单元中有程序计数器和指令寄存器。

+
+
+
+
+
+ +
    +
  • CPU 能读懂什么?
  • +
+

CPU 无法直接读懂你写的 C 语言代码,它是由数字电路构成的。数字电路只能处理 0 1,因此计算机中的任何数据都必须使用二进制表示,程序也是如此。

+

在计算机刚刚诞生的阶段,工程师们不得不使用 0 1 构成的指令序列和计算机打交道,这就是机器语言。因为具体电路设计不同,每种 CPU 所能理解的指令有限,这些指令的集合叫做指令集

+
    +
  • CPU 都做些什么?
  • +
+

CPU 的工作非常简单:从内存中读取并执行一条指令,再从内存中读取并执行下一条指令……1 GHz CPU 每秒能重复这一操作约十亿次。

+

这些指令都相当具体,比如把一个数字从一个位置移动到另一个位置,把两个数字相加并把结果存储再某个地方。是的,你的 CPU 也在疯狂做着这些事情。但是通过精巧的设计,这些简单的指令就能构建起程序的控制逻辑,实现复杂的功能

+

CPU 还有自己的小工作区——由若干寄存器(Register)组成的寄存器组。每个寄存器能存储一个数字。

+

从机器语言、汇编语言到高级语言

+

现代计算机的结构与 70 年前并没有本质上的不同,但是程序设计语言取得了很大的发展,产生了汇编语言和高级语言。我们仍然不能直接对 CPU 说:为我计算 \(1 + 1\),但我们可以用高级语言简洁的表达它,让编译器(compiler)和汇编器(assembler)将其翻译成 0101 的机器语言。下图展示了程序设计语言的发展历史,编译过程其实就是这一历史的反向。

+ +
+
+
+
+
+
+

机器语言
Machine Code

+

这是第一代编程语言,也是计算机唯一能识别的语言。上图展示了世界上第一个计算机程序,它用来找出一个数最大的因数。

+
+
+
+
+
+
+
+
+
+

汇编语言
Assembly Language

+

这是第二代编程语言,其实就是机器语言的助记符。它使得程序员不用再直接与 0 1 打交道,程序的可读性也更强了。上图显示了将两个整数相加的汇编代码。

+
+
+
+
+
+
+
+
+
+

高级语言
High-level Language

+

这是第三代编程语言,它让程序员们不用再关注计算机结构上的细节,而是将注意力转移到要解决的问题上来。

+
+
+
+
+
+ +

下面三行代码分别是用 C 语言、汇编语言和机器语言(十六进制)描述的同一件事:

+ +
+
+
+
c = a + b;
+
+
add $t0, $t1, $t2
+
+
01 2a 40 20
+
+
+
+
void multstore(long x, long y, long *dest) {
+    long t = mult2(x, y);
+    *dest = t;
+}
+
+
multstore:
+    pushq   %rbx
+    movq    %rdx, %rbx
+    call    mult2
+    movq    %rax, (%rbx)
+    popq    %rbx
+    ret
+
+
53 48 89 d3 48 83 ec 08 e8 00 00 00 00 48 89 03 5b c3
+
+
+
+
+ + +
+为什么需要高级语言? +
    +
  1. 机器语言和汇编语言都是非常底层的语言,程序员需要关注计算机的细节,这使得程序的可读性很差。使用高级语言,程序员能将注意力转移到要解决的问题上来
  2. +
  3. 机器语言和汇编语言都是与具体 CPU 相关的,程序员需要为不同的 CPU 编写不同的程序,可移植性差。使用高级语言,程序员只需要写一次程序,再使用编译器就能将其翻译成能在特定 CPU 的机器语言。
  4. +
+
+ + +
+前瞻:第四代和第五代编程语言 +

编程语言仍在发展演化。目前已经有了第四代和第五代编程语言的概念。第三代的编程语言虽然是用语句编程而不直接用指令编程,但语句也分为输入、输出、基本运算、测试分支和循环等几种,和指令有直接的对应关系。而第四代以后的编程语言更多是描述要做什么(Declarative)而不描述具体一步一步怎么做(Imperative,具体一步一步怎么做完全由编译器或解释器决定,例如 SQL 语言(SQL,Structured Query Language,结构化查询语言)就是这样的例子。

+
+ + +
+对机器语言有兴趣? +

这里提供了一些将汇编语言转换为 MIPS 指令集机器语言的基础例子,有兴趣可以了解一下。

+
+ +

程序的基本语法结构

+

经过了 2-3 周课程的学习,相信同学们多少都写过了一些代码,对语言有了一些基本认识。本节将系统地梳理程序的语法和结构知识,帮助大家理清思路,为后续理解程序编译过程和调试技术作铺垫。

+

写程序的目标是什么?

+

从根本上说,计算机是由数字电路组成的运算机器,只能对数字做运算,程序之所以能做符号运算,是因为符号在计算机内部也是用数字表示的。此外,程序还可以处理声音和图像,声音和图像在计算机内部必然也是用数字表示的,这些数字经过专门的硬件设备转换成人可以听到、看到的声音和图像。

+

程序由一系列指令(Instruction)组成,指令是指示计算机做某种运算的命令,通常包括以下几类:

+
    +
  • 输入(Input:从键盘、文件或者其它设备获取数据。
  • +
  • 输出(Output:把数据显示到屏幕,或者存入一个文件,或者发送到其它设备。
  • +
  • 基本运算:执行最基本的数学运算(加减乘除)和数据存取。
  • +
  • 测试和分支:测试某个条件,然后根据不同的测试结果执行不同的后续指令。
  • +
  • 循环:重复执行一系列操作。
  • +
+

对于程序来说,有上面这几类指令就足够了。你曾用过的任何一个程序,不管它有多么复杂,都是由这几类指令组成的。程序是那么的复杂,而编写程序可以用的指令却只有这么简单的几种,这中间巨大的落差就要由程序员去填了,所以编写程序理应是一件相当复杂的工作。编写程序可以说就是这样一个过程:把复杂的任务分解成子任务,把子任务再分解成更简单的任务,层层分解,直到最后简单得可以用以上指令来完成。

+

词法和语法规则

+

词法(Lexical)和语法(Syntax)是编程语言的两个基本概念。词法规则定义了编程语言中的基本符号,语法规则定义了这些符号如何组成合法的表达式、语句和程序。

+ +
+C 的词法规则:贪心法 +

术语 token (符号)是语言的基本表意单元。字符组成符号。例子 : ->file 都是符号。同一组字符序列在不同上下文中可能属于不同符号。

+

如果该字符可能组成符号,那么再读入下一个字符,直到读入的字符串已经不可能再组成一个有意义的符号。

+
+
+词法练习:请思考下面这些表达式的行为 +

点击「+」号展开答案。

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
a---b /*(1)!*/
+a -- - b /*(2)!*/
+a - -- b /*(3)!*/
+
+//下面的 p 指向除数。
+y = x/*p     
+/*(4)!*/
+y = x / *p /*(5)!*/
+
+n-->0 /*(6)!*/
+n-- >0 /*(7)!*/
+n- -> 0 /*(8)!*/
+
+a+++++b /*(9)!*/
+
+
    +
  1. 等价于 (a--) - b。按照贪心法,编译器读入两个连续的 - 号后,已经不可能再组成一个有意义的符号,因此这个符号被确定为后缀递减运算符。接着读取下一个符号。
  2. +
  3. 等价于 (a--) - b
  4. +
  5. 等价于 a - (--b)
  6. +
  7. 等价于 y = x/* 被贪心法解释为注释的开头。
  8. +
  9. 等价于 y = x / (*p)
  10. +
  11. 等价于 (n--) > 0
  12. +
  13. 等价于 (n--) > 0
  14. +
  15. 等价于 (n-) -> 0。这是一个无效的语句,n- 本身不是一个合法的表达式,也无法用作 -> 的操作数。
  16. +
  17. 等价于 ((a++)++) + b。请思考一下,这个语句有效吗?
  18. +
+
+ + +
+语法:标识符、表达式和语句 +

为了便于初学者理解,我们采用一套简化的语法规则:

+
    +
  • 标识符(Identifier:就是「名字,用于指代各种实体,比如:对象、类型、函数、标签、宏等等。
  • +
+
+对象的不同含义 +

在这里,对象(Object)的含义与 C++ 中不同。这里的对象指数据存储的一个区域,其内容可以表示。比如下面的语句创建了一个对象:

+
int a;
+
+

创建一个对象的意思就是分配了一块存储空间。标识符 a 用于指代这个对象。每个对象都有大小、生存期、存储器、值等属性,我们将在下节课详细展开。

+
+
    +
  • 表达式(Expression:由运算符(+-*/% 等等)和操作数(常量、变量、函数返回值 ......)组成的式子,可以计算出一个值。
  • +
  • +

    语句(StatementC 标准确定了五种语句类型。除了复合语句,其它语句都以分号 ; 结尾。下面是语句的定义,你可以发现语句是递归定义的

    +
      +
    • +

      复合语句:由花括号包围的一组语句。

      +
      { 语句或声明 }
      +
      +
    • +
    • +

      表达式语句:表达式加上分号就是表达式语句。C 程序中大部分语句都是表达式语句。空语句也算作表达式语句。

      +
      表达式;
      +
      +

      例子:

      +
      puts("hello"); // 表达式语句
      +char *s;
      +while (*s++ != '\0')
      +  ; // 空语句
      +
      +
    • +
    • +

      选择语句:

      +
      if(表达式) 语句
      +if(表达式) 语句 else 语句
      +switch(表达式) 语句
      +
      +
    • +
    • +

      循环语句:

      +
      while(表达式) 语句
      +do 语句 while(表达式);
      +for(初始化子句;表达式;表达式) 语句
      +
      +
    • +
    • +

      跳转语句:

      +
      goto 标识符;
      +continue;
      +break;
      +return 表达式;
      +
      +
    • +
    +
  • +
+

完整的 C 语法规则请参考:

+ +
+ +

语法将在后续课程中作深入讲解(第 2 讲涉及类型相关的语法,第 4 讲涉及函数指针

+

函数:C 程序的基本模块

+

「指令」是第一、二代编程语言的基本结构。C 语言是面向过程的高级语言,它的基本模块是函数(Function)

+ +
+关键概念:函数 +

从外面看,函数就像一个黑盒子,只能看到函数的三大要素:

+
    +
  • 函数名:函数的名字,用来调用函数。
      +
    • 函数名与变量名的命名规则相同。
    • +
    +
  • +
  • 参数:函数的输入,可以有多个
  • +
  • 返回值:函数的输出,只能有一个
  • +
+

下面这行语句被称为函数签名(Function Signature)或函数原型(Function Prototype。它给出了函数对外的一切信息:

+
int MyFunc(int a, int b);
+
+

从里面看,函数是一组指令的集合,它们按照一定的顺序执行,完成某个特定的功能。

+
+ +

当我们调用一个函数时,我们应当按照函数签名中的要求传入参数,并可以获得它的返回值。在函数签名的语境下,void 表示空,即不存在。下面的这个函数没有参数,也没有返回值。

+
void MyFunc(void);
+
+

因为我们比较关心函数返回值的类型,有时会把函数的返回值类型称为这个函数的“类型”,比如会说 MyFunc 这个函数是一个 void 函数。

+ +
+关于 void +

Q:void 到底有哪些含义?

+

A: 下面是 void 的一般用法

+
    +
  • void 作为函数参数,表示函数不接受参数。
  • +
  • void 作为函数返回值,表示函数不返回值。
  • +
  • void* 是一种指针类型,表示不知道指向的类型是什么。
  • +
+

从这些用法来看,似乎 void 是一种类型,但这会引起下面问题中的矛盾。另一种看待方式是:上面的用法都是特殊的语法,不过是恰好用了同一个关键字 void 罢了。

+

Q:所以 void 是一种类型吗?

+

A:C 标准从概念上将 void 作为一种类型。但是 void 类型的变量是不存在的,因为它没有大小,编译器也不允许你写下 void a;。这会引起一些困惑。

+
+ +

函数有两个功能:

+
    +
  • 返回值:函数调用本身就是一个表达式,它的值就是函数的返回值。
  • +
  • 副作用:除了返回值以外的功能统称为副作用。
  • +
+

一些例子:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数签名返回值的含义副作用
int printf(const char *format, ...);打印的字符数打印字符串到标准输出
int scanf(const char *format, ...);读取的字符数从标准输入读取字符串
int rand(void);生成的随机数
void exit(int status);退出程序
+

每个 C 语言程序都必须包含一个 main 函数,它是程序的入口。main 的函数签名一般是这样的:

+
int main(void);
+int main(int argc, char *argv[]); //以后学命令行参数就会用到这种形式
+
+

main 的调用者是操作系统。操作系统看到 main 的签名中说返回值为 int,因此系统会等待 main 返回一个整数。这个整数一般被用于告知操作系统程序的执行状态,0 表示正常结束,其他值可以传递其他信息。这就是为什么 main 的末尾应当写 return 0。如果 main 函数中没有 return 语句,有些编译器会为你补全(其他函数不会但请记得写上,这是你的责任。

+

没有返回值的函数也可以使用 return 语句,此时它没有返回值的作用,而是结束当前函数的执行并返回。例子:

+
void print_logarithm(double x)
+{
+    if (x <= 0.0) {
+        printf("Positive numbers only, please.\n");
+        return;
+    }
+    printf("The log of x is %f", log(x));
+}
+
+ +
+其他建议 +

每个函数都应该设计得尽可能简单,简单的函数才容易维护。应遵循以下原则:

+
    +
  1. +

    实现一个函数只是为了做好一件事情,不要把函数设计成用途广泛、面面俱到的,这样的函数肯定会超长,而且往往不可重用,维护困难。

    +
  2. +
  3. +

    函数内部的缩进层次不宜过多,一般以少于 4 层为宜。如果缩进层次太多就说明设计得太复杂了,应考虑分割成更小的函数(Helper Function)来调用。

    +
  4. +
  5. +

    函数不要写得太长,建议在 24 行的标准终端上不超过两屏,太长会造成阅读困难,如果一个函数超过两屏就应该考虑分割函数了。[CodingStyle] 中特别说明,如果一个函数在概念上是简单的,只是长度很长,这倒没关系。例如函数由一个大的 switch 组成,其中有非常多的 case,这是可以的,因为各 case 分支互不影响,整个函数的复杂度只等于其中一个 case 的复杂度,这种情况很常见,例如 TCP 协议的状态机实现。

    +
  6. +
  7. +

    执行函数就是执行一个动作,函数名通常应包含动词,例如 get_currentradix_tree_insert

    +
  8. +
  9. +

    比较重要的函数定义上侧必须加注释,说明此函数的功能、参数、返回值、错误码等。

    +
  10. +
  11. +

    另一种度量函数复杂度的办法是看有多少个局部变量,5 10 个局部变量已经很多了,再多就很难维护了,应该考虑分割成多个函数。

    +
  12. +
+
+
+扩展:编译和解释 +

简单了解一下就好。

+

将高级语言编写的源代码转化成机器语言的目标程序的过程统称为翻译(Translation。翻译的方式有两种:编译(Compile)和解释(Interpret。编译将整个程序翻译成机器语言,解释则是边翻译边执行。

+

C 语言是典型的编译型语言,源代码需要经过编译后才能运行,而编译阶段并不会执行程序。Python 则是典型的解释型语言,逐句执行源代码,不需要产生可执行文件。

+

这些描述的都是一种语言的典型用法。事实上 C 语言也开发出了相应的解释器,Python 也开发出了相应的编译器。两种翻译方式各有优劣。

+
+ +

现在你是编译器

+

接下来我们将化身 C 语言编译器,解读一些代码。相信经过下面的训练,你对代码和程序执行的理解会更加深入。

+ +
+例子:语法树 +
printf("%d:%d is %d minutes after 00:00\n", hour, minute, hour * 60 + minute);
+
+

编译器在翻译这条语句时,首先根据上述语法规则把这个语句解析成下图所示的语法树,然后再根据语法树生成相应的指令。语法树的末端的是一个个 Token,每一步展开利用一条语法规则。

+

+

理解组合(Composition)规则是理解语法规则的关键所在,正因为可以根据语法规则任意组合,我们才可以用简单的常量、变量、表达式、语句搭建出任意复杂的程序,以后我们学习新的语法规则时会进一步体会到这一点。从上面的例子可以看出,表达式不宜过度组合,否则会给阅读和调试带来困难。

+
+
+表达式不宜过度组合 +

这涉及代码可读性问题。看看下面这段代码:

+
double distance(double x1, double y1, double x2, double y2)
+{
+     return sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
+}
+
+

这样写很简洁,但如果写错了呢?只知道是这一长串表达式有错,根本不知道错在哪,而且整个函数就一个语句,插 printf 都没地方插。所以用临时变量有它的好处,使程序更清晰,调试更方便,而且有时候可以避免不必要的计算,例如上面这一行表达式要把 (x2-x1) 计算两遍,如果算完 (x2-x1) 把结果存在一个临时变量 dx 里,就不需要再算第二遍了(虽然这些优化现代编译器都会替你自动完成。下面这个版本是可读性高的代码:

+
double distance(double x1, double y1, double x2, double y2)
+{
+    double dx = x2 - x1;
+    double dy = y2 - y1;
+    double dsquared = dx * dx + dy * dy;
+    double result = sqrt(dsquared);
+
+    return result;
+}
+
+

码风不是死的,请同学们视情况切换码风。

+
+ +

Lap:关于做题目

+

如果想做题的话,有基础的同学可以早点开始做历年卷,了解一下程设考试都考些啥。

+

简单提一些 Tips

+
    +
  • 考试是全英文。如果平常不太看英文文档 / 没怎么学 / 英语很差的同学,至少你考前做历年卷的时候要把生词全部抄下来记一遍。
  • +
  • 一定一定一定要做历年卷。不要以为自己会写点代码就能应付考试了,其实考试和你写代码水平并不呈正相关。考试的题目都是很细节的,很多都是你平常不会注意到的,所以一定要做历年卷,做完了还要看看答案,看看自己哪里做错了,哪里没注意到。这里展示一个去年 C 小考试干碎一片人的选择题:
  • +
+ +
+干碎一片人的选择题 +

Suppose T is a type name and t is a variable of type T. Which of the following is NOT a valid expression?

+

+
A. sizeof(T)
+
B. sizeof(t)
+
C. sizeof T
+
D. sizeof t
+
+
+答案 +

答案是 C,不知道你猜对了吗?

+

大家一般写代码 sizeof 后面都会加括号的对吧,但你知道为什么吗?想要知道为什么,需要回顾前面学习的语法知识。

+

sizeof 是一个运算符,它有两种使用方式:

+
sizeof(类型)
+sizeof 表达式
+
+

我们知道,t 是表达式,(t) 也是表达式。sizeof(T) 的使用符合规范。因此 A、B、D 都是正确的。为什么不规定 sizeof 类型 的用法呢?因为这可能引起歧义,有些类型名就携带空格,比如:short intstruct node 等等。了解了这些知识,你能说说下面的语句是否合法吗?如果合法,你能解释它的含义吗?如果不规定类型必须带括号,可能会产生哪些二义性?

+
sizeof int***p
+sizeof(int)*p
+sizeof int * + 1
+
+
+
+ +

如果你想的话,可以再来两道:

+ +
+C 16 年选择题 +

In the following notations, _____ can express a character constant( 字符常量 ) correctly.

+

+
A. '\x100'
+
B. 125
+
C. '\08'
+
D. '\'
+
+
+答案 +

B

+
+
+ +

程序的编译过程

+

接下来,我们将了解编译器和汇编器是如何一步步把你的程序编译成机器码的。我们以最经典的 C 语言编译系统 GCC 为例。

+ +
+什么是 GCC +

简单地说,GNU 项目旨在开发一个完全自由的操作系统以及配套的软件。GCC 最早是 GNU C Compiler 的简称,现在代表 GNU Compiler Collection。这表明它不是单个程序,而是一系列编译工具的集合,包括了 C、C++、Objective-C、Fortran、Ada、Go、D 等语言的前端,以及汇编器、链接器等后端,和这些语言的库文件。

+
+ +

当我们使用命令 gcc -o test test.c 编译一个 C 语言程序时,GCC 会调用一系列的程序将源代码翻译成汇编语言、再翻译成机器语言,最后经过链接产生可执行文件。下图展示了这个过程。

+

+
    +
  1. 预处理:由 C 预处理器(C Preprocessor)完成,它将源代码中的宏定义展开,将头文件中的内容插入到源代码中,删除注释等。预处理后的代码文件以 .i 为后缀。
  2. +
  3. 编译:由 C 编译器(C Compiler)完成,它将预处理后的文件翻译成汇编语言。编译后得到的汇编代码文件以 .s 为后缀。
  4. +
  5. 汇编:由汇编器(Assembler)完成,它将汇编代码翻译成机器语言。汇编后得到的机器代码文件以 .o 为后缀。
  6. +
  7. 链接:由链接器(Linker)完成,它将多个目标文件链接成一个可执行文件。链接后得到的可执行文件以 .exe 为后缀。
  8. +
+

解读 gcc 显示的详细信息

+

下面这些文本是 gcc -v -o prog main.c sum.c 命令的输出结果。

+ +
+gcc 的输出信息 +

点击文本中带圆圈的 + 号可以展开详细信息,高亮的行是运行某个编译工具的具体命令。

+
<!--(1)!-->Using built-in specs.
+COLLECT_GCC=gcc
+COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
+OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
+OFFLOAD_TARGET_DEFAULT=1
+Target: x86_64-linux-gnu
+Configured with: ../src/configure -v --with-pkgversion='Ubuntu 12.3.0-1ubuntu1~23.04' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
+Thread model: posix
+Supported LTO compression algorithms: zlib zstd
+gcc version 12.3.0 (Ubuntu 12.3.0-1ubuntu1~23.04) 
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'
+<!--(2)!--> /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpdir prog- -dumpbase main.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s
+GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)
+    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP
+
+GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
+ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
+ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed"
+ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
+<!--(3)!-->#include "..." search starts here:
+#include <...> search starts here:
+ /usr/lib/gcc/x86_64-linux-gnu/12/include
+ /usr/local/include
+ /usr/include/x86_64-linux-gnu
+ /usr/include
+End of search list.
+GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)
+    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP
+
+GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
+Compiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'
+<!--(4)!--> as -v --64 -o /tmp/ccEgqpgY.o /tmp/ccClT5M4.s
+GNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'
+<!--(5)!--> /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu sum.c -quiet -dumpdir prog- -dumpbase sum.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s
+GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)
+    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP
+
+GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
+ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
+ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed"
+ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
+#include "..." search starts here:
+#include <...> search starts here:
+ /usr/lib/gcc/x86_64-linux-gnu/12/include
+ /usr/local/include
+ /usr/include/x86_64-linux-gnu
+ /usr/include
+End of search list.
+GNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)
+    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP
+
+GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
+Compiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'
+ as -v --64 -o /tmp/ccxMA26W.o /tmp/ccClT5M4.s
+GNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40
+COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/
+LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../:/lib/:/usr/lib/
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.'
+<!--(6)!--> /usr/lib/gcc/x86_64-linux-gnu/12/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper -plugin-opt=-fresolution=/tmp/ccyzC2ZB.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o prog /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/12/../../.. /tmp/ccEgqpgY.o /tmp/ccxMA26W.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o
+COLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.'
+
+
    +
  1. 最开头是 gcc 的相关信息,包括它运行的平台、配置的选项等。
  2. +
  3. 这里调用了 cc1 完成预处理和编译阶段,将源代码文件 main.c 编译成了 ASCII 编码的汇编文件 /tmp/ccCWi0p2.s
  4. +
  5. 这里显示了头文件搜索路径,如果你编译时报错缺少头文件,可以检查一下这里有没有包含对应的路径。
  6. +
  7. 这里调用了 as 完成汇编阶段,将汇编文件 /tmp/ccCWi0p2.s 翻译成了机器语言文件 /tmp/ccAnKDEo.o
  8. +
  9. 接下来又对 sum.c 重复预处理、编译和汇编的过程,得到了 /tmp/ccgMFTqK.o
  10. +
  11. 最后调用 collect2 (这是 ld 的包装程序)完成链接阶段,将两个源代码生成的目标文件 /tmp/ccAnKDEo.o/tmp/ccgMFTqK.o 与其他很多目标文件链接成了可执行文件 prog。这就是你能在操作系统上运行的程序。
  12. +
+
+ + +
+为什么没有看见预处理器 cpp 的执行呢? +

某些版本的 gcc 会将预处理器 cpp 和编译器 gcc 合并成一个指令,比如上面的 cc1,这样就不用单独调用 cpp 了。

+
+ +

接下来,我们详解其中的每一个阶段以及可能会发生的问题。

+

预处理

+

执行以下命令,查看预处理后的文件 hello.i

+
cpp hello.c > hello.i
+
+

你会发现,原来 hello.c#include 预处理指令的地方被替换为完整的 stdio.h 文件内容,这些内容包括 printf 等函数的原型。其他预处理指令(在后续课程会学习到)比如 #define 也会在这一阶段生效。至于为什么只插入了函数原型而没有定义,接下来的链接阶段会解答。

+

预处理阶段最经常产生的问题是找不到头文件C 语言头文件搜索规则如下:

+
    +
  • 用双引号 #include "..." 包含的头文件,编译器会先在当前目录下查找,再在系统目录下查找。
  • +
  • 用尖括号 #include <...> 包含的头文件,编译器只会在系统目录下查找。
  • +
+

如果你的头文件不在当前目录下,那么你需要使用 -I 选项告诉编译器头文件的位置。比如你的头文件在 include 目录下:

+
.
+├── hello.c
+└── include
+    └── header.h
+
+

你可以使用以下命令编译:

+
gcc -Iinclude -o hello hello.c
+
+

路径可以是相对路径或绝对路径,比如:

+
gcc -I../include -o hello hello.c
+gcc -I/home/user/include -o hello hello.c
+
+

另一种方式是设置环境变量 CPATH 指定搜索路径。

+
export CPATH="$HOME/.local:$CPATH"
+
+

设置后,你应当能在编译器的输出信息中看到新增的路径。

+
#include <...> search starts here:
+ /home/bowling/.local
+
+

编译

+

执行以下命令,查看编译后的文件 hello.s

+
gcc -S hello.i
+
+

所有高级语言层面的类型、控制结构等,都被与特定 CPU 指令集相关的汇编指令代替。在汇编语言中,所有数据都是字节块,没有类型的概念。

+

在这个阶段,编译器会检查一些问题,并抛出不同等级的信息:

+
    +
  • 错误(Error:编译器无法继续进行编译。比如:提供的参数列表不匹配、使用了未定义的变量、函数等。
  • +
+
error.c: In function ‘main’:
+error.c:9:5: error: too many arguments to function ‘my_print’
+    9 |     my_print(1);
+      |     ^~~~~~~~
+error.c:4:6: note: declared here
+    4 | void my_print(void)
+      |      ^~~~~~~~
+
+
    +
  • 警告(Warning:违反了语法,但能够继续编译,编译出来的程序运行结果很可能与你想象的不一样。比如:转义字符与数据类型不匹配、发生了隐式转换等。
  • +
+
warning.c: In function ‘main’:
+warning.c:8:18: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
+    8 |     printf("a = %d\n", a);
+      |                 ~^     ~
+      |                  |     |
+      |                  int   double
+      |                 %f
+
+

大部分警告信息默认不会输出,使用 -Wall-Wextra 选项可以打开更多的警告信息。你也可以使用 -Werror 选项将警告信息视为错误,这样编译器就会停止编译。在编译时带上这些参数是一个好习惯。

+
gcc -Wall -Wextra -Werror -o hello hello.c
+
+

汇编

+

执行以下命令,汇编器将汇编指令翻译为机器码,产生可重定位目标文件 hello.o

+
as -o hello.o hello.s
+
+ +
+目标文件 +

目标文件中包含计算机能读懂的机器代码和数据,有三种形式:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
形式由谁产生有什么用
可重定位目标文件编译器或汇编器只包含编译器为你编写的代码翻译的机器语言代码,需要与其他目标文件链接合并为可执行目标文件
可执行目标文件链接器包含你编写的程序中使用的库函数和启动代码的机器代码,能够被操作系统正确运行
共享目标文件编译器或汇编器给其他程序用的代码,可以在程序加载或运行时链接
+
+ +

hello.o 中包含了 hello.c 中的 C 语言代码翻译成的二进制代码以及一些数据,比如字符串 Hello, world.\n。如果使用文本编辑器打开 hello.o,你会看见一堆乱码,其中夹杂着一些字符。因为字符在源文件和内存中都是用 ASCII 编码的,所以 ASCII 字符仍能被文本编辑器识别,但其他的机器指令和数据只会被解读为乱码。

+

+

如果运行 ./hello.o,终端会告诉你这个文件不能被操作系统执行

+
exec: Failed to execute process: './hello.o' the file could not be run by the operating system.
+
+

它还缺少一些东西,如:

+
    +
  • 启动代码:启动程序时,操作系统会将控制权交给程序的入口点,但这个入口点不是 main 函数,而是一些启动代码。启动代码在执行 main 前进行一些初始化工作,并在退出 main 后做一些扫尾工作。
  • +
+ +
+一个不带启动代码的例子 +

Linux 程序的入口点一般是 _start,它完成一些内存初始化的工作,然后跳转到 main 函数。我们在链接阶段不带上含有启动代码的目标文件,看看在缺少 _start 的情况下会发生什么。

+
$ ld hello.o -o hello -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2
+ld: warning: cannot find entry symbol _start; defaulting to 0000000000401030
+$ ./hello
+Hello World.
+fish: Job 1, './hello' terminated by signal SIGSEGV (Address boundary error)
+
+

这个程序源代码正常,为什么会出现段错误呢?

+

在链接阶段,ld 的输出表明找不到入口点 _start,因此把入口点默认放在了 0000000000401030 处的函数。这个函数是 main 函数。因此,当程序执行到 main 函数的最后一条指令时,会继续往下执行,但此时栈已经被清空,因此会发生段错误。

+

使用 gdb 查看错误位置:

+
Program received signal SIGSEGV, Segmentation fault.
+0x0000000000000001 in ?? ()
+
+

证实了上面的分析。

+

crt C Runtime 的缩写。C 语言相关启动代码在这些目标文件中:

+
    +
  • crt1.o:负责启动,包含 _start 和未定义的 __libc_start_mainmain
  • +
  • crti.o:初始化
  • +
  • crtbegin.o:构造(C++ 依赖)
  • +
  • crtend.o:析构(C++ 依赖)
  • +
  • crtn.o:结束
  • +
+

Linux 平台下,它们的链接顺序为:

+
ld crt1.o crti.o [user_objects] [system_libraries] crtn.o
+
+
+ +
    +
  • 库函数:几乎所有 C 程序都会用到标准库中的函数,比如 printf。标准库中的代码已经被预编译成目标文件,附在编译器的安装目录下。
  • +
+

在接下来的链接步骤,我们将这些目标文件链接到我们的程序中,生成可以执行的程序。

+

链接

+

链接有两种类型:静态链接和动态链接。

+ +
+静态链接 +

如果你的程序与静态库链接,那么链接器会将静态库中的代码复制到你的程序中。这样,你的程序就不再依赖静态库了,可以在任何地方运行。但是,如果静态库中的代码发生了变化,你的程序并不会自动更新,你需要重新编译你的程序。

+

Linux 系统上,静态库的文件名以 .a 结尾,比如 libm.a。在 Window 上,静态库的文件名以 .lib 结尾,比如 libm.lib。静态库可以使用 ar (archive program)工具创建。

+
+
+动态链接 +

当你的程序与动态库链接时,程序中创建了一个表。在程序运行前,操作系统将需要的外部函数的机器码加载到内存中,这就是动态链接过程

+

与静态链接相比,动态链接使程序文件更小,因为一个动态库可以被多个程序共享,节省磁盘空间。部分操作系统还允许动态库代码在内存中的共享,还能够节省内存。动态库升级时,也不需要重写编译你的程序。

+

Linux 系统上,动态库的文件名以 .so 结尾,比如 libm.so。在 Window 上,动态库的文件名以 .dll 结尾,比如 libm.dll

+
+ +

动态链接具有上面描述的优点,因此 GCC 尽可能地执行动态链接。

+

链接相关的问题可能出现在链接时(静态链接、程序运行前和运行中(动态链接。下面时一些常见的问题。

+ +
+
+
+
+
+
+

未定义的引用

+

当同学们开始使用其他库构建大型项目时,这或许会成为最头疼的问题。首先应当阅读库的使用说明,接下来搜索缺失的符号可能位于哪些库文件中。

+
+
+
+
+
+
+
+
+
+

缺失 .dll

+

常用 Windows 的同学多多少少见过这个报错,可以去网上搜索相应 .dll 文件放置到正确的目录。

+
+
+
+
+
+
+
+
+
+

缺失 .so

+

Linux 上的动态库一般通过 apt 管理,搜索相应的包并安装即可。

+
+
+
+
+
+ +

下面这行命令在我的系统上完成了 hello 程序的正确链接,不一定能在你的系统上运行。你可以尝试查找库文件的路径,让它成功运行。

+
ld --output hello --dynamic-linker /lib64/ld-linux-x86-64.so.2  /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o -lc hello.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o
+
+

动态链接过程

+

如果一个可执行文件依赖于动态库,那么程序运行前,动态链接器(interpreter)会被先加载运行。它将寻找需要的动态库,加载到内存中,然后将控制权交给程序的入口点。

+

ld 的选项 --dynamic-linker 就指定了动态链接器的路径。目前 Linux 系统使用的动态链接器一般是 /lib64/ld-linux-x86-64.so.2。它也是一个可以直接运行的程序,你可以试试运行它:

+
$ /lib64/ld-linux-x86-64.so.2 --help
+You have invoked 'ld.so', the program interpreter for dynamically-linked ELF programs.  Usually, the program interpreter is invoked automatically when a dynamically-linked executable is started.
+
+You may invoke the program interpreter program directly from the command line to load and run an ELF executable file; this is like executing that file itself, but always uses the program interpreter you invoked, instead of the program interpreter specified in the executable file you run.  Invoking the program interpreter directly provides access to additional diagnostics, and changing the dynamic linker behavior without setting environment variables (which would be inherited by subprocesses).
+
+

该选项将会在可执行目标文件前面加上对动态链接器的请求。使用 readelf 可以查看 ELF 格式可执行目标文件的头部信息。

+
$ readelf -l /usr/bin/ls | head -20
+
+Elf file type is DYN (Shared object file)
+Entry point 0x6b10
+There are 13 program headers, starting at offset 64
+
+Program Headers:
+  Type           Offset             VirtAddr           PhysAddr
+                 FileSiz            MemSiz              Flags  Align
+  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
+                 0x00000000000002d8 0x00000000000002d8  R      0x8
+  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
+                 0x000000000000001c 0x000000000000001c  R      0x1
+      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
+                 0x0000000000003510 0x0000000000003510  R      0x1000
+  LOAD           0x0000000000004000 0x0000000000004000 0x0000000000004000
+                 0x0000000000013111 0x0000000000013111  R E    0x1000
+  LOAD           0x0000000000018000 0x0000000000018000 0x0000000000018000
+                 0x0000000000007530 0x0000000000007530  R      0x1000
+  LOAD           0x000000000001ff70 0x0000000000020f70 0x0000000000020f70
+
+

静态链接过程

+

进行静态链接时需要注意命令行中文件的顺序。

+
    +
  • 如果是目标文件,链接器将记录其中的符号定义和引用。
  • +
  • 如果是库文件,链接器将尝试匹配前面记录的未解析的符号定义和引用。解析完成后,该库中没有被使用的符号将被丢弃。
  • +
+

看看下面的命令行发生了什么?

+
$ gcc -static ./libvector.a main2.c
+/tmp/cc9XH6Rp.o: In function `main':
+main2.c:(.text+0x1a): undefined reference to `vector_add'
+
+

链接器检查 libvector.a 库文件时,还没有记录任何符号定义和引用,因此它被整个丢弃了。当链接器开始检查 main2.c 时,不会再回去找 libvector.a 了。

+

总而言之,静态链接时,库文件一般放在末尾。如果库文件之间有相互依赖,也需要对它们进行排序。

+

程序调试技术

+ +
+杂谈:Bug 的典故 +

编程是一件复杂的工作,因为是人做的事情,所以难免经常出错。据说有这样一个典故:早期的计算机体积都很大,有一次一台计算机不能正常工作,工程师们找了半天原因最后发现是一只臭虫钻进计算机中造成的。从此以后,程序中的错误被叫做臭虫(Bug,而找到这些 Bug 并加以纠正的过程就叫做调试(Debug。有时候调试是一件非常复杂的工作,要求程序员概念明确、逻辑清晰、性格沉稳,还需要一点运气。

+
+ +

Bug 的类型

+

调试的技能我们在后续的学习中慢慢培养,但首先我们要区分清楚程序中的 Bug 分为哪几类。

+

编译时错误

+

编译器只能翻译语法正确的程序,否则将导致编译失败,无法生成可执行文件。对于自然语言来说,一点语法错误不是很严重的问题,因为我们仍然可以读懂句子。而编译器就没那么宽容了,只要有哪怕一个很小的语法错误,编译器就会输出一条错误提示信息然后罢工,你就得不到你想要的结果。虽然大部分情况下编译器给出的错误提示信息就是你出错的代码行,但也有个别时候编译器给出的错误提示信息帮助不大,甚至会误导你。在开始学习编程的前几个星期,你可能会花大量的时间来纠正语法错误。等到有了一些经验之后,还是会犯这样的错误,不过会少得多,而且你能更快地发现错误原因。等到经验更丰富之后你就会觉得,语法错误是最简单最低级的错误,编译器的错误提示也就那么几种,即使错误提示是有误导的也能够立刻找出真正的错误原因是什么。相比下面两种错误,语法错误解决起来要容易得多。

+

运行时错误

+

编译器检查不出这类错误,仍然可以生成可执行文件,但在运行时会出错而导致程序崩溃。对于我们接下来的几章将编写的简单程序来说,运行时错误很少见,到了后面的章节你会遇到越来越多的运行时错误。读者在以后的学习中要时刻注意区分编译时和运行时(Run-time)这两个概念,不仅在调试时需要区分这两个概念,在学习 C 语言的很多语法时都需要区分这两个概念,有些事情在编译时做,有些事情则在运行时做。

+

逻辑错误和语义错误

+

第三类错误是逻辑错误和语义错误。如果程序里有逻辑错误,编译和运行都会很顺利,看上去也不产生任何错误信息,但是程序没有干它该干的事情,而是干了别的事情。当然不管怎么样,计算机只会按你写的程序去做,问题在于你写的程序不是你真正想要的,这意味着程序的意思(即语义)是错的。找到逻辑错误在哪需要十分清醒的头脑,要通过观察程序的输出回过头来判断它到底在做什么。

+

通过本节你将掌握的最重要的技巧就是调试。调试的过程可能会让你感到一些沮丧,但调试也是编程中最需要动脑的、最有挑战和乐趣的部分。从某种角度看调试就像侦探工作,根据掌握的线索来推断是什么原因和过程导致了你所看到的结果。调试也像是一门实验科学,每次想到哪里可能有错,就修改程序然后再试一次。如果假设是对的,就能得到预期的正确结果,就可以接着调试下一个 Bug,一步一步逼近正确的程序;如果假设错误,只好另外再找思路再做假设“当你把不可能的全部剔除,剩下的——即使看起来再怎么不可能——就一定是事实”(即使你没看过福尔摩斯也该看过柯南吧

+

也有一种观点认为,编程和调试是一回事,编程的过程就是逐步调试直到获得期望的结果为止。你应该总是从一个能正确运行的小规模程序开始,每做一步小的改动就立刻进行调试,这样的好处是总有一个正确的程序做参考:如果正确就继续编程,如果不正确,那么一定是刚才的小改动出了问题。例如,Linux 操作系统包含了成千上万行代码,但它也不是一开始就规划好了内存管理、设备管理、文件系统、网络等等大的模块,一开始它仅仅是 Linus Torvalds 用来琢磨 Intel 80386 芯片而写的小程序。据 Larry Greenfield Linus 的早期工程之一是编写一个交替打印 AAAA BBBB 的程序,这玩意儿后来进化成了 Linux”(引自 The Linux User's Guide Beta1 版)在后续的课程中会给出更多关于调试和编程实践的建议。

+ +
+杂谈:为什么很多同学感觉调试的过程十分煎熬? +

或许你也会在后续的学习中亲身体会或看到,同学们被程序的 Bug(最典型的是段错误)折磨得焦头烂额。这可能有以下原因:

+
    +
  • C 语言基础知识不牢:编译都过不了,不开 -Wall-Werror,编译出来的程序中有很多坑,比如隐式类型转换。
  • +
  • 没有事先想好程序的逻辑:建议在动手写代码前,先想好自己程序的逻辑和步骤。边写边想的后果大概率是代码写得一坨(除非你非常熟练
  • +
  • 不了解基本的调试技术,不会使用调试工具:本节课我们将为大家解决这个问题。
  • +
+
+ +

fprintf(stderr) 是你最好的朋友

+

虽然接下来要介绍的 gdb 功能强大,但大多数情况下简单地打印变量就能帮你定位问题所在。

+

在程序中使用 fprintf(stderr, ...) 打印调试信息,可以帮助你定位到程序中的错误。fprintf 向指定的流输出格式化字符串,stderr 是标准错误流,它不会被缓冲,因此你可以在程序崩溃时看到最后的调试信息(这些输入输出的知识会在后面的课程中学到

+

以一个异常终止的程序为例:

+
#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    printf("printf ");
+    fprintf(stderr, "fprintf ");
+    abort();
+}
+
+

运行结果如下:

+
$ ./debug
+fprintf fish: Job 1, './debug' terminated by signal SIGABRT (Abort)
+
+

可以看到只有 fprintf 函数的输出。如果在 printf 语句后面加上换行符,你会发现 printf 的输出也被打印出来了。因为当输出缓冲区遇到 \n 时也会立即输出。

+

此外,将错误信息导向标准错误流还有另一个好处,就是你可以分别收集调试信息和正常输出。比如你可以将调试信息重定向到一个文件,而将正常输出重定向到另一个文件。

+
$ ./debug 2> debug.log 1> output.log
+
+

使用 gdb 调试程序

+

接下来,我们以被 C 标准弃用的库函数 gets 为例,用 gdb 对其进行调试:

+
gets.c
char *gets(char *s)
+{
+    int c;
+    char *dest = s;
+    while((c = getchar()) != '\n' && c != EOF)
+        *dest++ = c;
+    if(c == EOF && dest == s)
+        return NULL;
+    *dest++ = '\0';
+    return s;
+}
+
+void echo()
+{
+    char buf[8];
+    gets(buf);
+    puts(buf);
+}
+
+

编译时开启调试信息

+

在编译时,使用 -g 选项在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证 gdb 能找到源文件。这些信息可以帮助调试器定位到源代码的位置。

+
gcc -g -o gets gets.c
+
+

有时,因为 GCC 的特性,可能导致允许某些不符合 C 标准的事情发生。这时你可以使用 -ansi -pedantic-errors 来关闭 GCC 特性,严格遵守 ANSI C。这构成了常用的编译选项。

+
gcc -Wall -Werror -ansi -pedantic-errors -g prog1.c -o prog1
+
+

gdb 的基本使用

+

启动 gdb 程序:

+
GNU gdb (Ubuntu 10.2-6ubuntu1) 10.2
+...
+Reading symbols from ./hello...
+(gdb)
+
+

命令行的提示符从 $ 变成了 (gdb),这意味着你已经进入了 gdb 的交互界面。gdb 中常用的命令如下:

+
    +
  • file <filename>:加载可执行文件。
  • +
  • rrun [args]:运行程序。[args] 是可选的命令行参数。
  • +
  • bbreak <line>:在指定行设置断点。
  • +
  • bbreak <function>:在指定函数设置断点。
  • +
  • bbreak *<address>:在指定地址设置断点。
  • +
  • info breakpoints:查看断点信息。
  • +
  • delete breakpoints <number>:删除指定编号的断点。
  • +
  • continue:继续执行程序。
  • +
  • next:执行下一行。
  • +
  • step:执行下一行,如果遇到函数调用,进入函数内部。
  • +
  • print <variable>:打印变量的值。
  • +
  • print <expression>:打印表达式的值。
  • +
  • watch <expression>:监视表达式的值,当值发生变化时,程序会停下来。
  • +
  • backtrace:查看函数调用栈。
  • +
  • finish:执行完当前函数后停下来。
  • +
  • qquit:退出 gdb
  • +
  • help:查看帮助信息。
  • +
+

检查程序情况

+

Linux 系统有一个特殊的设备文件 /dev/zero,它能够作为输入,提供无穷无尽的 0 字节。我们将它作为输入,看看程序会发生什么。

+
(gdb) file gets
+Reading symbols from gets...
+(gdb) run < /dev/zero
+Starting program: /mnt/f/Code/_repo/study-assist/docs/programming_lecture/lecture1/code/gets < /dev/zero
+[Thread debugging using libthread_db enabled]
+Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
+
+Program received signal SIGSEGV, Segmentation fault.
+0x00005555555551b2 in gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+
+

因为程序访问了非法的地址空间,系统向程序发送信号 SIGSEGV,程序终止运行。gdb 会自动停在发生错误的位置,这里是 gets.c 的第 8 行。你可以使用 backtrace 命令查看函数调用栈。

+
(gdb) backtrace
+#0  0x00005555555551b2 in gets (s=0x7fffffffd760 "") at gets.c:8
+#1  0x000055555555521b in echo () at gets.c:18
+#2  0x0000000000000000 in ?? ()
+
+

使用 print 命令查看各个变量的值。print/x 能够指定以十六进制的形式打印变量的值。

+
(gdb) print dest
+$1 = 0x7ffffffff001 <error: Cannot access memory at address 0x7ffffffff001>
+(gdb) print s
+$2 = 0x7fffffffd760 ""
+(gdb) print dest - s
+$3 = 6305
+(gdb) print c
+$4 = 0
+
+

gdb 为你做了一些提示,比如 dest 现在所指向的地址 0x7ffffffff001 是程序无法访问的。检查 dest - s 的值我们知道此时 dest 指向的地址已经是 s 6305 个字节,远远超出了数组 s 的空间。我们也可以检查当前输入的字符 c,它显然是 0

+

断点调试

+

使用 break <filename>:<line> 可以在指定文件指定行设置断点。对于单文件程序,可以省略源代码文件名。break 还可以接收函数名和地址作为参数,还可以使用条件表达式,请使用 help break 查看详细用法。

+

我们在程序第 8 *dest++=c 处设置一个断点,然后运行程序。

+
(gdb) b 8
+Breakpoint 1 at 0x11a3: file gets.c, line 8.
+(gdb) r < /dev/zero
+Starting program: /mnt/f/Code/_repo/study-assist/docs/programming_lecture/lecture1/code/gets < /dev/zero
+
+Breakpoint 1, gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+(gdb) print dest - s
+$1 = 0
+
+

next 命令将会单行执行程序,且不会进入函数内部(即把整个函数当作一行step 会进入函数内部一行一行执行。continue 命令将继续执行程序,直到下一个断点。

+
(gdb) next
+7               while((c = getchar()) != '\n' && c != EOF)
+(gdb) next
+Breakpoint 1,gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+(gdb) print dest - s
+$2 =1
+(gdb) continue
+Continuing.
+Breakpoint 1, gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+(gdb) print dest - s
+$3 = 2
+
+

nextstep 命令都可以接受一个参数,表示执行多少行,且会在断点处停下。continue 命令也可以接受一个参数,表示忽略接下来地多少个断点。

+
(gdb) next 20
+
+Breakpoint 1, gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+(gdb) print dest - s
+$4 = 3
+(gdb) continue 20
+Will ignore next 19 crossings of breakpoint 1.  Continuing.
+
+Breakpoint 1, gets (s=0x7fffffffd760 "") at gets.c:8
+8               *dest++ = c;
+(gdb) print dest - s
+$5 = 23
+
+ +
+调试技巧 +

直接按 Enter 键,gdb 会重复上一条命令。这样就不用一直输入 nextstep 了。

+
+ +

在一些更为复杂的程序中,使用 gdb 调试的优越性就逐渐显现出来了。你不用频繁更改源代码插入 printf 语句,只需要在 gdb 中设置断点,然后逐步执行程序,查看变量的值,就能找到错误所在。

+ +
+

进一步学习

+

由于个人水平不足以及时间有限,没能写出一个体验较好的 GDB 调试实验。十分希望同学们在课后去看看这篇文章 Linux C 一站式编程:第 10 gdb,把这边的调试实例都过一遍~

+
+ +

参考资料

+ +
+参考资料 + +
+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture1/pre_class/index.html b/programming_lecture/lecture1/pre_class/index.html new file mode 100644 index 0000000..4483b90 --- /dev/null +++ b/programming_lecture/lecture1/pre_class/index.html @@ -0,0 +1,1293 @@ + + + + + + + + + + + + +课前:准备开发与调试环境 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

课前:准备开发与调试环境

+ +
+

Info

+

本文档更改自周健均学长为图灵程算课程准备的资料,感谢周健均学长的付出。

+
+
+

内容提要

+

在参与线下授课前,同学们最好能够安装好相关的开发环境,以便能够更好的跟随老师的讲解。

+
    +
  • 命令行简介
  • +
  • WSL 安装引导
  • +
  • Windows 上安装 C 语言编译器
  • +
  • VSCode 安装与配置
  • +
+

同学们可以从右侧(电脑端)或左侧(手机端)目录跳转到自己需要的章节。

+
+
+

非计算机专业同学,使用 Dev-C++ IDE 或在线 IDE 即可。

+

本篇文章描述的内容适用于计算机专业的同学。非计算机专业的同学,不需要掌握命令行的使用,使用 IDE 即可。并且更加推荐在线 IDE,因为本地 IDE 有时也会出错。最常见的一个例子是:运行了一次程序,没有以恰当的方式结束进程,再次点击编译时编译器 ld 就会因为 .exe 被占用无法写入而报错,但报错信息并不会表明是上一个程序没关,搞不懂是怎么回事。我还见过有同学,每次编译完运行程序,都要被 360 先扫描一遍,等个半分钟才能显示窗口。在线 IDE 不受你电脑的影响,不会产生这些问题。

+
+

下面的块以 Online GDB 为例,展示在线 IDE 的用法。配好环境的同学也可以看一看,因为你可能偶尔临时用到一个没有配置环境的电脑,这时使用在线 IDE 最为便捷。

+
+

Online GDB 的使用

+
    +
  • 打开这个网址:www.onlinegdb.com
  • +
  • 它已经为你写好 C 语言的 Hello World 程序源码。
  • +
  • 在右上角选择 C 语言,然后点击左上角的 Run
  • +
  • 在下方,你就可以看见程序的输出。
  • +
  • 按下 Enter 键离开终端。下方会显示几个选项:
      +
    • Command Line Arguments:命令行参数,你们应该不会学到?
    • +
    • Standard Input:标准输入。你可以选择 Interactive Console(就是正常地用键盘和程序交互)或者 Text(预先准备一些文本自动输入,通常用于测试 PTA 的样例数据
    • +
    +
  • +
+
+
+

可以跳过本篇文章的同学

+

符合以下描述的同学可以跳过本篇文章:

+
    +
  • Mac Linux 用户
  • +
  • 安装好了 WSL Windows 用户
  • +
  • 安装好了 MinGW、MSVC、Cygwin、tdm-gcc 等编译器的 Windows 用户
  • +
+

使用集成开发环境的同学,也请看一下 Shell 部分。

+
+
+

温馨提示

+
    +
  • 点击页面中的图片可以放大查看。
  • +
  • 如果安装过程遇到困难,可以在辅学群提问,或私戳授课学长~
  • +
+
+ +

Shell 使用拾遗

+

本节我们要认识一个即将成为你的老朋友的东西——Shell。下面是同学们接下来会经常见到的几个名词:

+
    +
  • Terminal 终端:下图中,这个窗口就是 Windows Terminal。它负责接收你的输入,把输入传递给 Shell,然后把 Shell 的输出显示给你。你可以从图中看到,一个 Terminal 可以连接到多个 Shell,就像一台显示器可以连接到多台电脑一样。把 Terminal 理解为键盘和显示器就好。
  • +
  • Shell 命令解释器:接收你给出的命令、执行并给出响应的,就是 Shell。如果把 Terminal 理解为键盘和显示器,那么 Shell 就是主机。
  • +
  • Prompt 提示符:Shell 会给你一个提示符,告诉你它已经准备好接收你的命令了。在 Linux 中,提示符一般是 $。下面的图中,bowling 那一块就是提示符(我做了一些美化
  • +
  • Command Line Interface 命令行交互界面:当我们使用文本命令与计算机交互时,我们就在使用 CLI。这与我们日常生活中使用鼠标的图形交互界面(Graphical User Interface,GUI)不同。
  • +
+ +
+
+
+
+
+
+

真正意义上的 Terminal

+

在计算机发展的早期阶段,还没有像现在的 Windows 这样的图形用户界面。那时人们使用终端与计算机交互。

+
+
+
+
+
+
+
+
+
+

Terminal Shell 的例子

+

这张图展示了 Windows Terminal Powershell

+
+
+
+
+
+
+
+
+
+

Terminal Shell 的关系

+

可以将 Terminal 理解成显示器,将 Shell 理解成电脑主机。

+
+
+
+
+
+ + +
+

杂谈:为什么要使用命令行交互界面呢?

+

很简单,因为我们不仅是在使用计算机,而且是在学习计算机GUI 自然是最适合与人交互的,但它也是由 CLI 搭建起来的。比如,你可能在使用 Dev-C++ Visual Studio IDE 进行编程,只需要点一下按钮就能自动完成程序编译步骤。这固然方便,但是它本质上是帮你写好并执行了一系列编译命令,帮你完成了命令行的操作。当你开始构建大型项目时,这当然是最适合的方法。但作为初学者,我们应当趁此机会了解其背后的原理。

+

总之:如果要学习计算机,那么就需要学习使用命令与计算机交互,这样才能更好地理解计算机是如何工作的。此外,命令行交互界面也有许多有点,比如:

+
    +
  • 速度快:在命令行中,你可以快速地输入命令,而不需要使用鼠标点击菜单。
  • +
  • 可编程:你可以编写脚本,让计算机自动执行一系列命令。
  • +
  • 可远程:你可以通过网络连接到远程计算机,使用命令行与其交互。
  • +
+

最主要的是,你今后会用到的很多工具不一定会提供图形界面,但一定会提供命令行界面。学习 CLI 一开始确实有些难度,但只要学了,就会受益无穷。

+
+ +

运行与终端

+

Windows 上如何打开 Terminal 呢?

+ +
+
+
+
+
+
+

运行窗口

+

使用 Win + R 组合键,将会出现图中的窗口。可以在其中输入命令运行,即使是 Windows XP 都可以使用。

+
+
+
+
+
+
+
+
+
+

命令提示符 CMD

+

在运行窗口中输入 cmd 后回车,就会出现命令提示符。命令提示符是 Windows 最基本的 Shell(与 Linux bash 同等地位,但是功能及其有限,一般不用。

+
+
+
+
+
+
+
+
+
+

Powershell

+

Powershell 简称 pwsh,是 Windows 的新一代命令解释器。它的功能强大,但语法和我们将要学习且最常用的 Linux Shell 大不相同。我们在 Windows 上经常使用 pwsh,但不用花时间去学习它。

+
+
+
+
+
+
+
+
+
+

Windows Terminal

+

这是 Windows 上最好的 Terminal,对各种 Shell 的显示效果都支持的很好。在 Microsoft Store 中搜索 Terminal,出现图中的选项,然后选择安装即可。它对应于 macOS 上的 iTerm。今后学习 ssh 时,你还可能会接触到 Termius

+
+
+
+
+
+ +

在比较新版本的 Windows 中,Win 键打开菜单之后输入字符能够搜索到对应程序,除了常用的应用程序以外,启动 cmd.exe 也可以这样进行,效果和 Win + R 相同。

+

WSL 安装简单引导(可选)

+
+

推荐装一装,如果主力机是 Windows 在以后将对 WSL 有较大需求

+
+

WSL,全称 Windows Subsystem for Linux(适用于 Linux Windows 子系统,是一项允许开发者不依靠单独的虚拟机或双启动 (dual booting) 而在 Windows 上运行 Linux 环境的功能。

+

安装:以 Ubuntu 为例

+

在这里以在 Windows11 上安装 WSL2 Ubuntu 为例介绍最简单的安装流程,详细的信息可以参考官方文档 Install Linux on Windows with WSL 或者它的中文版

+
+

Ubuntu Linux 的一种发行版本,在这里就不对 Linux 的众多发行版本进行介绍和评价了。有能力和想法的同学可以自己对照教程安装其他发行版,比如在终端输入 wsl --list --online 可以看到所有可以选择的 Linux 发行版

+
+

注意安装 WSL 的先决条件:Windows 版本不低于 Windows 10 20H2(Build 19042)或者 Windows 11。如果版本太老,请更新到最新版本,如果无法更新可以考虑重装系统。

+
+

可以使用 winver 命令查询 Windows 版本,Win + R 输入 winver 或者在 Win 键出现的菜单栏中直接输入 winver 都可以启动。新买的电脑可能 Windows 11 居多,如果是 Windows 10 的电脑版本显示可能是 21H2(操作系统内部版本 19044.3086,这样也是符合先决条件的。

+
+

Powershell(管理员)中直接使用如下命令自动安装(注意,每一行命令分别执行,不要多行粘贴执行

+
1
+2
+3
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
+dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
+wsl --install
+
+

中途可能会弹出两个窗口,显示正在修改什么东西,统统选择“是”。安装完成后,将出现如下界面

+

wsl_ubuntu_set

+
    +
  • 设置一个用户名,建议全英文无空格
      +
    • 若有空格,将会只取第一个空格前面的内容作为你的用户名
    • +
    +
  • +
  • 输入密码,注意你输入的字符不会在屏幕上显示,需要盲打
      +
    • 如果打了乱七八糟的字符不要慌,确认密码时故意打错会重新让你设置密码
    • +
    • 确认密码与输入密码一致才会设置成功
    • +
    +
  • +
+

这样就完成了 WSL2 Ubuntu 的安装。

+ +
+

错误:0x80370114

+ +
+ +

使用终端的一大好处是方便打开 WSL。如下图所示,点击 Ubuntu 22.04.2 LTS 或者使用 Ctrl + Shift + 5 组合键就可以方便地打开 Ubuntu 22.04。当然这是因为我安装的是 Ubuntu 22.04 的缘故,在你们的电脑中显示的应该就是 Ubuntu

+
+wsl_terminal +
+

其他 WSL 的使用方法留待你们慢慢探索了,在此不再赘述。

+

安装 C 语言编译器

+
+

如果已经安装好 WSL,那么可以跳过本节,因为基本上不需要在 Windows 上再安装编译环境了。

+
+
+

本篇相对比较复杂,如果在本篇配置遇到难以解决的困难,而作业 / 实验截止日期快要到了,可以跳过本篇安装 Dev-C++ 进行临时开发。

+
+

写完了 C 语言代码,我们需要让它变成能跑的程序,这就需要准备 C 语言的编译器支持。以下主要介绍 Windows 系统的配置。

+

就决定是你了,gcc!

+
+

自由软件 (free software),根据自由软件基金会对其的定义,是一类可以不受限制地自由使用、复制、研究、修改和分发的,尊重用户自由的软件。——维基百科

+
+

gcc,全称 GNU Compiler Collection,著名的自由软件,被许多现代类 Unix 操作系统采用为标准编译器,但是 Windows 上并不直接支持。我们想要在 Windows 系统上使用,一般得依赖 MinGW gcctdm-gcc 也是基于 MinGW gcc 来的。

+
+

有能力的同学推荐在 Windows 上开启 WSL,使用 WSL 进行 C 语言开发。WSL 可以理解为在 Windows 的电脑中模拟一个 Linux 的小系统,从而能方便地控制环境。

+
+

Windows 小白教程之 tdm-gcc

+
+

前面选择了 WSL 的同学可以自行配置,然后再看 3 Mac 用户可以直接看 3

+
+

可以按照老师的视频教程下载 tdm-gcc,目前最新版为 gcc 10.3.0

+

需要判断自己的 Windows 64 位系统还是 32 位系统(现在一般都是 64 位系统

+ +
+
+
+
+

点击 Win 键,输入“关于”,如下图所示。打开“关于你的电脑”后就可以看到电脑是不是 64 位了,新电脑一般都是 64 位。

+

+win11_about +
+
+
+

桌面找到“此电脑”,右键属性

+

+pc_right_attr +
+

可以看到是 64 位系统还是 32 位系统。

+

+win10_x64 +
+
+
+
+
+ +

64 位系统直接下载 tdm64-gcc-10.3.0-2.exe 安装即可,32 位则选择 tdm-gcc-10.3.0.exe

+

准备安装。对于零基础的同学,电脑里应该还没装过 tdm-gcc,选择 create 即可。

+
+tdmgcc_create +
+

接下来就是根据 64/32 位系统选择对应的版本

+
+tdm32_or_64 +
+

选择安装路径,推荐零基础同学选择默认路径(如 64 位的 C:\TDM-GCC-64

+
+tdmgcc_path +
+

接下来是要认真考虑的页面。

+
    +
  • 可选的安装项
      +
    • 可以全选。如果确定不需要一些东西可以不选,比如确定自己不会再需要调试 32 位程序的话可以不选 gdb32
    • +
    +
  • +
  • Start Menu items
      +
    • 看个人意愿,可以不选
    • +
    +
  • +
  • Add to PATH
      +
    • 建议选上。如果不选或者忘选了,将会需要自己配置 tdm-gcc 的环境变量路径。
    • +
    +
  • +
+
+tdmgcc_install_items +
+
+

如果希望用更新版本的 gcc 可以使用 winlibs 编译的 mingw-gcc,或者你可以自己选择。

+
+

测试 gcc 是否正确安装

+ +
+
+
+
+

在命令提示符 / 终端中输入 gcc,应当出现如下信息: +

gcc: fatal error: no input files
+compilation terminated.
+
+

如果没有,可能是你还没有安装 gcc,或者你前一步 Add to PATH 没有正常进行,可能需要参照 Windows 修改环境变量进行环境变量的检查。

+

命令提示符 / 终端中输入 gcc --version,应当出现类似如下的信息。 +

gcc.exe (tdm64-1) 9.2.0
+Copyright (C) 2019 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+

我的版本显示是 9.2.0,是因为装了旧版本的 tdm-gcc,你们的显示将会是 10.3.0

+
+
+

如下命令安装 gcc。如果错误,尝试 sudo apt-get update 后再重新执行下面的命令。 +

sudo apt install gcc
+
+

终端中输入 gcc,应当出现如下信息: +

gcc: fatal error: no input files
+compilation terminated.
+
+

终端中输入 gcc --version,可能会出现类似如下的信息: +

gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0
+Copyright (C) 2021 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+

Mac 用户直接使用 gcc -v (或者 xcode-select --install)会提示你安装开发者工具,然后就会自动安装 XCode 在内的一系列开发支持,最后告诉你你安装的 gcc 其实是 clang,本质上是它将 gcc 作为 clang 的别名 (alias) 了。

+

成功安装后,终端输入 gcc 会出现如下信息: +

clang: error: no input files
+
+

使用 gcc --version 可能出现以下信息: +

Apple clang version 14.0.3 (clang-1403.0.22.14.1)
+Target: x86_64-apple-darwin22.6.0
+Thread model: posix
+InstalledDir: /Library/Developer/CommandLineTools/usr/bin
+
+

gcc clang 都是 C 语言编译器,只是特性上存在差异。在作业和实验中,一个好的遵从标准的 C 代码,由不同的编译器编译后不应当产生不同的运行结果。因此如果你使用 clang 编译 C 代码运行不符合预期,代码出问题的概率比 clang 特性出问题的概率大很多。

+
+
+
+
+ +

Windows 修改环境变量

+
+

Windows 用户环境变量配置出现问题了才需要看这一小节

+
+

检查一下环境变量,Win + R 键输入 sysdm.cpl 后回车,会出现 “系统属性” 界面,选择 “高级”,如下图所示:

+
+env_var +
+

打开环境变量,在 “系统变量” 或者 “用户变量” 中找到 PATH 变量,在其中增加一项 tdm-gcc 的路径。例如你如果默认安装 tdm-gcc,那么路径可能就是 C:\TDM-GCC-64\bin

+

VSCode 安装与配置

+
+

VSCode 的全称是 Visual Studio Code,注意它和 Visual Studio 完全是两个东西

+
+
+

不建议安装 Visual Studio,除非你清楚你安装它是为了什么

+
+

在这里仅介绍 Visual Studio Code 的安装。除了老师的视频之外,大家安装配置时还可以参考 GZTime 的教程,对于初学者来说还不错。

+

安装

+

VSCode 直接从官网选择自己平台对应的安装包下载就行

+ +
+
+
+
+

Windows exe 安装可以全选默认选项一路 Next,比较熟悉的同学可以自定义选项:

+
    +
  • 安装目录
      +
    • 推荐默认 C 盘,可能运行速度更快,也可以避免一些权限问题
    • +
    +
  • +
  • 将 “通过 Code 打开” 操作添加到 Windows 资源管理器文件 / 目录上下文菜单
      +
    • 选中该项后,选中文件或者文件夹,右键菜单中会出现 通过 Code 打开 的选项
    • +
    • 如果希望右键菜单不那么臃肿的话可以不选这一项
    • +
    • 本人没有选择该选项,可以自行思考选择
    • +
    +
  • +
  • Code 注册为受支持的文件类型的编辑器(推荐)
      +
    • 打开受支持的文件类型时,VSCode 将会成为可选项
    • +
    +
  • +
  • 添加到 PATH(推荐)
      +
    • 在命令行窗口 / 终端可以用 code 命令打开 VSCode
    • +
    +
  • +
+
+
+

Mac 的包下载下来之后拖入 Application 文件夹可以直接运行

+
    +
  • 添加到 PATH:如果需要在命令行窗口 / 终端用 code 命令打开 VSCode,那么需要如下操作
      +
    • 打开 VSCode 界面
    • +
    • 使用 Shift + Command + P 打开命令面板
    • +
    • 输入 shell command,选择 Shell Command: Install ‘code’ command in PATH 回车执行
    • +
    +
  • +
+
+
+
+
+ +

插件安装

+

打开 VSCode 后,在左侧竖栏寻找下面这个图标:

+
+plugin +
+

点击这个图标就进入了插件管理。建议可以安装下面两个插件:

+
    +
  • C/C++: 微软自家的插件,可用于语法识别、代码高亮
  • +
+
+plugin_ccpp +
+
    +
  • Chinese(Simplified): 界面汉化插件(可选)
  • +
+
+plugin_chinese +
+

安装汉化插件后可能需要你手动切换显示语言。Ctrl + Shift + P,出现的搜索框中输入 Configure,选择 Configure Display Language

+
+config_language +
+

随后再选择“中文 ( 简体 )”就可以完成界面汉化了。

+
+chinese_english +
+
+

英语基础不太好的同学有困难可以使用,英语基础比较好以及想要在日常实践中学习英语的同学建议跳过这一步。

+
+
+

这里只提供最基本的插件和使用示例,复杂的配置与使用大家可以参考 GZTime 的教程

+
+

VSCode 使用的一个简单示例

+

这里为想要尽快上手的同学提供一个简单的使用示例。打开 VSCode(打开时没有指定工作目录,将会出现如下的窗口:

+

vscode_initUI

+
+

工作目录,指某个专门存放你用于某个目的的文件的文件夹。例如你可能会建立一个文件夹,专门存放所有与第一次作业相关的代码、文档、配置文件等,在你为完成第一次作业而工作时,这个文件夹就是你的工作目录

+
+

点击左侧的 Open Folder,选择一个目录作为你的工作目录,一般会把你这个窗口所要处理的所有文件放置在这里。顶栏 Terminal > New Terminal(或终端 > 新建终端)打开 VSCode 的内部终端,功能大致与命令提示符 / 终端相同。

+

vscode_newterminal

+

下图就是打开了工作目录并新建了终端的界面状态。

+

vscode_workdir_terminal

+

鼠标移动到工作区,按 New File 键可以新建文件,旁边有新建文件夹按键。当然,直接在左侧工作目录右键也可以新建文件 / 文件夹。

+
+newfile +
+

创建 test.c,输入 Hello World 的代码并保存文件。然后在终端输入以下命令并执行: +

gcc test.c
+
+

在不同的系统将会生成不同的编译产物。

+
+
+
+

将会在和 test.c 同目录下生成 a.exe,随后在终端输入以下命令进行执行 +

./a.exe
+
+
+
+

将会在和 test.c 同目录下生成 a.out,随后在终端输入以下命令进行执行 +

./a.out
+
+
+
+
+

以下展示在 macOS 上的执行结果:

+

vscode_gccout_mac

+

这里有几个注意点:

+
    +
  • 记得保存文件后再 gcc 编译,可以考虑开启自动保存
      +
    • 如下图所示,找到左下角的齿轮点击后选择 Setting 或者设置,出现的设置页面中搜索 auto 可以找到如图所示的 Auto Save 设置项,设置为 afterDelay 即可
    • +
    • afterDelay 是对文件做出修改就实时保存,如果嫌保存频率过高可以选择 onFocusChange 或者 onWindowsChange
    • +
    • 我本人使用的是 onFocusChange,这样移动到终端准备编译运行时源代码文件就会自动保存,既自动保存又不会保存太频繁
    • +
    +
  • +
+

vscode_autosave

+
    +
  • 建议工作目录和文件名全英文,给出以下几个反面案例
      +
    • 文件名 作业.c
    • +
    • 工作目录 编程
    • +
    • 工作目录叫 Coding,但是绝对路径是 D:/学习资料/Coding
    • +
    +
  • +
  • 可以指定编译生成的文件名,比如你想要输出文件名为 hello.exe,就可以执行 +
    gcc test.c -o hello.exe
    +
  • +
  • 更多的 gcc 选项和 VSCode 扩展功能留待你们探索
  • +
+

VSCode + WSL(可选)

+
+

前面选择安装了 WSL 的使用 Windows 主力机的同学可以参考一下,非常有用的功能

+
+

以下引导主要按照 Microsoft 的官方文档,也可以参考其中文版

+

VSCode 连接到 WSL

+

安装 WSL 插件,如下图所示:

+
+plugin_WSL +
+

或者你也可以像官方文档那样,直接安装整个 Remote Development 扩展包:

+
+plugin_remote +
+

其中不仅有 WSL,还包括另外三个非常有用的远程开发插件。

+

plugin_remote_detail

+
    +
  • Ctrl + Shift + P,在出现的命令框中输入 WSL,选择 WSL: Connect to WSL in New Window(或 WSL: 在新窗口中连接到 WSL
  • +
  • 将打开一个新的 VSCode 窗口,里面已经连接到默认的 WSL 环境
  • +
+
+

如果需要在本窗口连接到 WSL,或连接到非默认的 WSL 所安装的其他 Linux 发行版,可以选择其他 WSL 的命令

+
+

vscode_wsl_connected

+

注意上图左下角所显示的状态,表明已经连接到 WSL 所安装的 Ubuntu-22.04,接下来的开发操作和上一节就区别不大了。

+

WSL 启动 VSCode

+

确保你已经将 VSCode 添加到 PATH 环境变量中。如果已经添加,那么直接在 WSL 的命令行中你所希望作为工作目录的位置执行 +

code .
+
+

就可以打开 VSCode,连接到 WSL 并且打开该目录作为工作目录。. 在这里表示当前目录即 pwd,如果将它替换成其他目录的路径也是可以将其打开作为工作目录的。

+

如果你还未将 VSCode 添加到 PATH 环境变量中,那该功能将无法使用,需要你手动添加 VSCode PATH 环境变量。例如你的 Windows 用户名是 ZTM,并把 VSCode 安装在默认目录,那么需要将 C:\Users\ZTM\AppData\Local\Programs\Microsoft VS Code\bin 加入到 PATH 环境变量,参考 Windows 修改环境变量章节。

+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture2/lecture2/index.html b/programming_lecture/lecture2/lecture2/index.html new file mode 100644 index 0000000..0c5f65f --- /dev/null +++ b/programming_lecture/lecture2/lecture2/index.html @@ -0,0 +1,1009 @@ + + + + + + + + + + + + +类型系统与内存模型 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

类型系统与内存模型

+ +
+

施工中

+

本页面正在编辑中。

+
+ + +
+

Abstract

+
    +
  • C 类型系统的完整描述
  • +
  • 如何阅读声明
  • +
  • 程序内存空间的布局
  • +
  • 如何管理内存
  • +
+
+ +

类型系统

+ +
+

Abstract

+

该部分在课堂上有较为详细的讲解,你应当已经了解下面这些基本数据类型的使用:

+
    +
  • 整型:intlongshortcharunsignedsigned 等。
  • +
  • 结构
  • +
+
+ +

数据是什么?

+

todo: 数据与类型的基本概念

+

C 语言的类型系统

+ +
+字符类型解惑 +

或许你会和我同样对以下几个问题感到困惑:

+
    +
  • 为什么字符常量的类型是 int 且长度是 4 个字节?
  • +
  • 为什么 getchar() 等函数返回 int 而不是 char
  • +
  • 宽字符、多字节字符和 Unicode 究竟如何使用?
  • +
+

这里将解释前两个问题,第三个问题不做要求,有兴趣可以参看中的相关内容。

+
    +
  • 字符常量的类型为什么是 int
  • +
+

多字符常量(Multicharacter constants)继承于 C 语言的前身 B 语言。它们的主要用途是用于编写汇编语言,因为汇编语言中的指令通常是多字节的。例如,'abcd' 可以用于表示一个 32 位的指令。

+

C 标准中,多字符常量被定义为 int 类型,长度是 4 个字节。在 C 语言的实际使用中,多字符常量通常是出于调试目的而嵌入结构中的魔数(Magic Numbers),就像有些人会使用 0xfeedbeef0xdeadbeef 而不是 NULL 来标记指针的未初始化已删除状态。这样做的好处是,如果程序出现了错误,我们可以通过打印出这些魔数来定位错误的位置。

+

我们使用时应当避免将多字符常量从 int 类型转换为 char 类型,因为这一转换过程是由编译器实现决定的。比如 char a = 'ABCD',在 gcc、clang、msvc 上均为 a = 'D',但是在 armcc 上为 a = 'A'

+
    +
  • getchar() 为什么要返回 int 类型?
  • +
+

因为它会返回 EOF,而 EOF 在标准中定义为 int 类型,通常为 (int)-1

+
+

This macro is an integer value that is returned by a number of narrow stream functions to indicate an end-of-file condition, or some other error situation.

+
+

为什么要这么定义?从逻辑上说,EOF 应当与任何一个字符值都不同(char)-1 也是一个合法的字符(因为它是 char 类型,char 类型的每个值都能表示字符,所以不能用作 EOF,必须使用 (int)-1,它与前者宽度不同,因此是不同的值。

+

还记得的在类型转换中提到的整形提升吗?如果我们让 getchar() 返回 (char)-1,当函数接收到 (char)-1 时,它会执行从无符号数到有符号数的转换(即使实现为有符号的 char,从而返回 (int)255,这与 EOF 的定义不符。

+

此外,charsigned charunsigned char 直接两两不同,尽管 char 具体实现为有符号数还是无符号数由实现决定。

+
+

参考资料:

+ +
+
+ +

结构与其他数据类型

+

阅读和撰写类型声明

+ +
+

Info

+

本节内容主要来自《C 专家编程》第 3 章“分析 C 语言的声明”。

+
+ + +
+

在实际工作中最好使用 typedef 逐步合成声明。

+

One good way to synthesize declarations is in small steps with typedef. K&R C, 5.12.

+
+ +

C 专家编程》和《C 陷阱与缺陷》都提出用下面这种方法理解复杂的类型声明,它们本质是一样的,分别表述为:

+
    +
  • 声明的形式与使用的形式相似
  • +
  • 声明是类型 + 表达式,对该表达式求值将得到该类型
  • +
+ +
+
+
+

看看这个声明:int *p

+
    +
  • p 是一个指针。我们声明它的形式与使用它的形式 *p (解引用 p)类似。
  • +
  • p 是一个指针,对它求值得到一个 int 类型的值。
  • +
+
+
+

再看看这个声明:char (*(*x[3])())[5]

+
    +
  • x 是一个数组。我们声明它的形式与使用它的形式 x[3] 类似。
  • +
  • (*(*x[3])())[5] 看作一个表达式,从内向外按照运算符和结合律对其求值,最终会得到一个 char 类型。求值的过程中,我们依次得到了数组、函数指针、数组指针,最后得到了 char 类型。
  • +
+
+
+
+ + +
+K&R C 语言类型声明的解读 +

Todo

+
+ +

对于声明来说,上面的方法已经足够了,因为总是容易找到变量的名字在哪里。但是对于形式参数typedefsizeof 和强制类型转换符等情况来说,找不到变量的名字,上面的方法就不够了。这时有一个更好的办法:从最内层括号开始读。

+

看看这个表达式:

+
(*(void(*)())0)();
+
+
    +
  • 从最内层括号开始读:void(*)() 显然是一个函数指针,指向的函数的返回类型是 void,参数列表为空。
  • +
  • 一层括号把 void(*)() 包起来,这是强制类型转换的用法,把 0 转换为 void(*)() 类型的指针。
  • +
  • 最后就剩下 (*fp)() 形式的函数调用了。
  • +
+

综上所述,这个表达式的目的是调用首地址为 0 的函数。实际工作中,我们可以这样分解这个函数声明:

+
typedef void (*funcptr)();
+(*(funcptr)0)();
+
+

C 语言考试中还会要求你阅读代码片段,为形参等位置填写类型声明。请参考历年卷总结中的例题。

+
+

分割线下方的内容还未整理

+

内存管理

+

C 的内存管理是一大痛点,因为它本身并不提供检查机制,一切都依赖于程序员自己。因此,好好掌握内存管理对于写出安全、稳定的程序是非常必要的。

+

对象和标识符

+

让我们来了解几个概念:对象、标识符

+
    +
  • 每个被存储的值都占用一定的物理内存,这样的一块内存称为对象。对象可以储存一个或多个值。
  • +
+ +
+

对象的其他含义

+

“面向对象编程”中的对象指的是“类对象”。

+
+ +
    +
  • 声明变量创建了一个标识符,标识符用于指定硬件内存中的对象。
  • +
  • 指针与标识符不同,它是另一种指定对象的途径。
  • +
+ +
+

左值

+

指定对象的表达式被称为左值

+
    +
  • entity 标识符,是左值
  • +
  • *pt 是表达式,也是左值
  • +
  • 2 * entity 不是标识符,也不是左值
  • +
  • *(pt + 2) 是表达式,也是左值
  • +
+

如果可以使用左值改变对象中的值,那么称为可修改的左值

+
const char * pc = "xxxx";
+
+
    +
  • pc 是可修改的左值
  • +
  • *pc 是不可修改的左值
  • +
+
+ +

存储期、作用域和链接

+ +
+

Note

+

存储期描述对象,表明在内存中存储的时间。

+

作用域和链接描述标识符,表明程序的哪些部分可以使用它。

+
+ +

作用域

+

C 中的变量作用域有以下几种类型:

+
    +
  • 块作用域
  • +
+

大多数变量。从定义处到块末尾。

+

函数形参(即使它在花括号外部

+ +
+Note +

C99 之前,块作用域的变量必须在块的开头声明。

+

也是在 C99的概念被放宽:控制语句(条件、循环)也是块(即使没有使用花括号。比如:

+
for(int i = 0;;)
+    function();
+
+

i 具有块作用域,是循环的一部分。

+

更精细的定义:循环体是整个循环的子块。你可以这样想它:

+
{
+    for(int i;;)
+    {
+        int i;
+    }
+}
+
+

上面的两个同名变量 i 不在同一个块中,因此不是重复定义。

+
+
+

Tip

+

同名的变量,内部覆盖外部。

+
+ +
    +
  • 函数作用域
  • +
+

goto 语句的标签。这意味着,即使标签在内层的块中,它的作用域也延伸至整个函数。

+
    +
  • 函数原型作用域
  • +
+

函数原型中的变量名。从定义处到函数原型结束。

+

只在你使用 VLA 时需要注意这一顺序:

+
void use_VLA(int n, int m, ar[n][m]);
+
+
    +
  • 文件作用域
  • +
+

在任何函数外定义的变量。从定义处到文件末尾。

+

这样的变量称为全局变量。

+ +
+

翻译单元

+

你所认为的多个文件对于编译器来说可能是一个文件。比如头文件:预处理时,头文件被插入。对于编译器来说,它看到的是单个文件。

+

这样的单个文件称为一个翻译单元。每个翻译单元对应一个源文件和它 include 的文件。

+

刚才我们说的文件作用域其实是在整个翻译单元可见

+
+ +

链接

+
    +
  • 外部链接
  • +
+

可以在多文件程序中的任何地方使用。

+
    +
  • 内部链接
  • +
+

只能在一个翻译单元中使用。由 static 关键字说明。

+ +
+用语 +

程序员们通常用全局作用域或程序作用域指代外部链接,用文件作用域指代内部链接。

+
+ +
    +
  • 无链接
  • +
+

块作用域、函数作用域、函数原型作用域。

+

存储期

+
    +
  • 静态存储期
  • +
+

整个程序执行期间。文件作用域的变量。

+

块作用域的变量也能具有静态存储期,使用 static 限定符声明即可。

+
    +
  • 线程存储期
  • +
+

从声明处到线程结束。对文件作用域的声明使用 _Thread_local 限定符说明。每个线程有这个变量的私有拷贝。

+
    +
  • 自动存储期
  • +
+

程序进入块时分配,离开块时释放。块作用域的变量。

+
+

VLA 是一个例外,它从定义处到块末尾存在(毕竟到定义处才能知道其大小

+
+
    +
  • 动态分配存储期
  • +
+

总结

+

不考虑并发编程,C 语言有五种存储类型。请描述它们的存储期、作用域、链接和定义方式。

+
    +
  • 自动
  • +
  • 寄存器
  • +
+

寄存器变量存放在可用的最快的内存中。由于它可能存放在寄存器中,因此不能取得它的地址。其他方面与自动变量相同。

+

能够被声明为寄存器类型的变量类型可能受到限制。比如在某些处理器中,比 double 长的类型不能声明为寄存器变量。

+
    +
  • 静态外部链接
  • +
+

extern 声明常常是不必要的,只是能够更好地说明使用了其他地方的变量。

+
+

但是如果在块中,再次声明一个同名的变量,则会覆盖静态外部链接的变量。如果出现这种重名的情况,建议使用 auto 注明。

+
+
    +
  • 静态内部链接
  • +
  • 静态无链接
  • +
+

仅在初始化时编译一次,若未指定值,则为 0。如果你用调试器调试,常常会发现好像“跳过”了这一步。

+ +
+Note +

- 可以使用 auto 显式说明自动存储期。但在 C++ 中它有不同含义,因此不要使用该限定符。

+
+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture3/lecture3/index.html b/programming_lecture/lecture3/lecture3/index.html new file mode 100644 index 0000000..c67e4e0 --- /dev/null +++ b/programming_lecture/lecture3/lecture3/index.html @@ -0,0 +1,1145 @@ + + + + + + + + + + + + +I/O 与文件 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ + + +

I/O 与文件

+ +
+

施工中

+

本页面正在编辑中。

+
+ + +
+

内容提要

+
    +
  • C 的输入输出模型:缓冲与流的概念
  • +
  • C 标准 I/O 函数
  • +
  • 文件编码
  • +
+
+ +

C 的输入输出模型

+

缓冲

+ +
+

缓冲输入

+

用户输入的字符被收集并储存在缓冲区(buffer)中,按下 Enter 键后程序才能使用用户输入的字符。

+
    +
  • 完全缓冲:仅缓冲区填满时才发送内容、刷新缓冲区,通常用于文件输入
  • +
  • 行缓冲:出现换行符时刷新缓冲区,通常用于键盘输入
  • +
+
+ +

与之对应地,无缓冲输入的程序能够立即使用用户输入的内容。

+

C 标准规定:输入是缓冲的

+ +
+我可以更改输入方式吗? +

UNIX 库中有 ioctl() 函数用于指定待输入的类型,但这不属于 C 标准。

+

ANSI C 中,可以使用 setbuf()setvbuf() 控制缓冲,但受限于系统的设置。

+
+ +

+

C 库提供的输入输出方式称为标准 I/O,它们是建立在操作系统提供的底层 I/O 上的。底层 I/O 之间常常会有一些差异:

+ +
+

各个系统的文件差异

+ + + + + + + + + + + + + + + + + + + + + + + +
差异UNIXWindowsMacOS
换行符\n
LF
\r\n
CRLF
\n ( 较早的 MacOS 使用\r )
LF
文件结束符^D^Z^D
+

注:如 ^Z 代表 Ctrl+Z,你可以使用该组合键结束键盘输入。

+

文件结尾也不一定由文件结束符标记。事实上,UNIX 系统储存文件大小信息,依据文件大小信息决定文件末尾。

+
+ +

从概念上看,C 处理的是而不是文件。不同属性和不同种类的输入,由属性更统一的来表示。

+ +
+

+

流就是一系列连续的字节。

+

打开文件的过程就是把流与文件相关联,读写都通过流来完成。

+
+ +

getchar()scanf() 等函数读取到文件结尾时会返回一个特殊的值 EOF,在 stdio.h 中定义了:

+
#define EOF (-1)
+
+

你能解释为什么要把它定为 -1 吗?

+

字符输入输出

+ +
+

函数和它们的功能

+ + + + + + + + + + + + + + + + + + + + + + + + + +
功能函数失败返回值
int getchar(void)
int getc(FILE *stream)
int fgetc(FILE *stream)
单字符输入EOF
char *fgets(char *s, int size, FILE *stream)字符串输入NULL
int ungetc(int c, FILE *stream)放回缓冲输入EOF
+

注意:以上函数都将字符从缓冲区中的 unsigned char 类型转换为 int 类型。

+

那么这是否会造成 EOF 不能被识别,而是被看作字符呢?

+
+ + +
+

关于 getchar() 函数

+

它的返回值是 int 类型而非 char 类型,值得注意。

+
+ +

换行符问题

+

这是一个典型的问题:scanf() 函数,除了 %c 以外的转换说明,都不会读取空白字符(空格、制表符和回车

+ +
+

写一个安全的输入函数

+
char * s_gets(char* st, int n)
+{
+    char * ret_val;
+    int i = 0;
+
+    ret_val = fgets(st, n, stdin);
+    if (ret_val)
+    {
+        while (st[i] != '\n' && st[i] != '\0)
+            i++;
+        if (st[i] == '\n')
+            st[i] = '\0';
+        else //must have words[i] == '\0'
+            while (getchar() != '\n')
+                continue;
+    }
+    return ret_val;
+}
+
+

这个函数来自《C Primer Plus,也是书中 13 章以后一直使用的输入函数。这个函数示范了如何使用安全的 fgets() 函数,并将输入统一,并处理剩余的字符。

+

在涉及行的输入时,一定要注意统一行结尾的形式。这对于换行符,特别是文件结尾处薛定谔的换行符,有很大作用。

+
+ +

检查输入

+

可以用于检查输入的方式有以下几种:

+
    +
  1. scanf() 的返回值。
  2. +
+

文件输入输出

+

标准库

+

C standard library

+

History of I/O model

+
    +
  • +

    Before the UNIX system,

    +
  • +
  • +

    UNIX system designed I/O method isolated about devices. It treats all text stream using standard internal format.

    +

    - ioctl is used to edit text stream for output.

    +
  • +
+

字符串的艺术

+

文件

+

本节结合 <stdio.h> 库和 C 标准内容。

+

基础概念

+

C 把文件看作连续的字节,每个字节都能被单独读取。C 提供两种文件模式,已经在开头介绍。

+

类型和宏

+

<stdio.h> 中有如下与文件相关的类型和宏:

+
    +
  • FILE 对象类型,记录控制所需要的所有信息,包括:文件定位符、指向相关缓冲的指针、错误指示符和文件结束符。
      +
    • 不要试图探索 FILE * 数据对象的内部,即使实现给出了某些可见域。不要修改对象、不要拷贝对象并代替使用,因为实现假定知道流数据对象的所有地址
    • +
    +
  • +
  • fpos_t 对象类型,含有唯一指定文件中每个位置所需的所有信息。
  • +
  • stderr, stdin, stdout都是 FILE* 类型的表达式。
  • +
  • EOF 展开为一个负的整值常量。
  • +
  • NULL
  • +
  • SEEK_CUR 文件当前位置
  • +
  • SEEK_END 文件结束位置
  • +
  • SEEK_SET 文件开始位置
  • +
+

函数

+

文件操作:

+
    +
  • int remove (const char *filename)
  • +
  • int rename (const char *old, const char *new)
  • +
  • FILE *tmpfile(void)
  • +
  • char * tmpnam(char *s)
  • +
+

文件访问:

+
    +
  • int fclose(FILE *stream)
      +
    • 关闭文件,清空流(清空流就是传递缓冲数据,释放缓冲。
    • +
    +
  • +
  • int fflush(FILE *stream)
      +
    • 立即写入(要求上一次操作是输出
    • +
    +
  • +
  • FILE *fopen(const char *filename, const char *mode)
  • +
  • FILE *freopen(const char *filename, const char *mode, FILE *stream)
  • +
  • void setbuf(FILE *stream, char *buf)
  • +
  • int setvbuf(FILE *stream, char *buf, int mode, size_t size)
  • +
+

mode 字符串的含义:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
flagmeaning
rread
wwrite (new or cut)
aappend (new or append)
bbinary
+update
+

注意一下上面词语的含义,update append 能写入的范围应该是不同的。

+
    +
  • append 模式下所有写操作强制加到文件结束处。
  • +
  • update 模式下,若不调用文件定位函数,输入输出不一定相互紧跟。
  • +
+

对于 UNIX 这种只有一种文件类型的系统,带 b 与否的模式是相同的。

+

C11 中新增了 x,带该字母的写模式打开存在文件会失败(相当于加了保护,且允许独占。

+

格式化输入输出:

+
    +
  • fprintf
  • +
  • fscanf
  • +
  • vfprintf
  • +
  • vprintf
  • +
  • vsprintf
  • +
+

字符输入输出:

+
    +
  • fgetc
  • +
  • fgets
  • +
  • fputc
  • +
  • fputs
  • +
  • getc
  • +
  • getchar
  • +
  • [DECPRATED] gets
  • +
  • putc
  • +
  • putchar
  • +
  • puts
  • +
  • ungetc
  • +
+

其中,fgetc()getc() 这类函数的不同是后者可能被实现为宏。

+

直接 I/O

+
    +
  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  • +
  • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  • +
+

文件定位:

+
    +
  • int fseek(FILE *stream, long int offset, int whence)
  • +
  • long int ftell(FILE *stream)
  • +
  • void rewind(FILE *stream)
  • +
+

以下两个函数用于处理更大型的文件(long 无法表示的偏移值)

+
    +
  • int fgetpos(FILE *stream, fpos_t *pos)
  • +
  • int fsetpos(FILE *stream, const fpos_t *pos)
  • +
+

错误处理:略

+

流和文件

+

C 标准是这样描述两种流的:

+
    +
  • 文本流:组成文本行的有序字符序列,每一行由零个或多个字符加上标志结束的换行符组成。
      +
    • 实现定义:最后一行是否需要换行符、换行符正前面的空格是否在读取时出现等。
    • +
    +
  • +
  • 二进制流:字符的有序序列。
  • +
+

关于文件动作:

+
    +
  • 打开文件:流打开一个文件,就是与该文件关联
      +
    • 创建文件会丢弃内容。
    • +
    • 和流相关的文件定位符定位在文件起始位置。
    • +
    • 附加模式下定位位置由实现决定。
    • +
    +
  • +
  • +
+

在文件中移动

+
    +
  • offset 应该由 ftell 来决定。
  • +
+

二进制文件

+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture4/lecture4/index.html b/programming_lecture/lecture4/lecture4/index.html new file mode 100644 index 0000000..279083b --- /dev/null +++ b/programming_lecture/lecture4/lecture4/index.html @@ -0,0 +1,596 @@ + + + + + + + + + + + + +C 标准库 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

C 标准库

+ +
+

施工中

+

本页面正在编辑中。

+
+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/programming_lecture/lecture5/lecture5/index.html b/programming_lecture/lecture5/lecture5/index.html new file mode 100644 index 0000000..05936dd --- /dev/null +++ b/programming_lecture/lecture5/lecture5/index.html @@ -0,0 +1,596 @@ + + + + + + + + + + + + +数据结构与算法 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

数据结构与算法

+ +
+

施工中

+

本页面正在编辑中。

+
+ +
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 0000000..be2501c --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u8ba1\u5212\u7f51\u7ad9","text":"

\ud83d\ude09 \u4f60\u597d~

\u8fd9\u91cc\u662f\u7afa\u53ef\u6862\u5b66\u9662\u5b66\u4e1a\u6307\u5bfc\u4e2d\u5fc3\u8f85\u5b66\u8ba1\u5212\u7684\u7ad9\u70b9\u3002\u8f85\u5b66\u8ba1\u5212\u4e3a\u7afa\u9662\u5927\u4e00\u65b0\u751f\u63d0\u4f9b\u6570\u5b66\u5206\u6790\uff08H\uff09\u3001\u7ebf\u6027\u4ee3\u6570\uff08H\uff09\u3001\u5fae\u79ef\u5206\uff08H\uff09\u3001\u666e\u901a\u7269\u7406\u5b66\uff08H\uff09\u3001\u666e\u901a\u5316\u5b66\uff08H\uff09\u3001\u7a0b\u5e8f\u8bbe\u8ba1\u57fa\u7840\u7b49\u8363\u8a89\u8bfe\u7a0b\u7684\u5b66\u4e60\u6307\u5bfc\u4e0e\u5e2e\u52a9\u3002

\u4f60\u53ef\u4ee5\u901a\u8fc7\u7f51\u7ad9\u4e0a\u65b9\u6216\u5de6\u4fa7\u7684\u5bfc\u822a\u680f\u6d4f\u89c8\u6211\u4eec\u7684\u7f51\u7ad9\u3002\u666e\u901a\u8f85\u5b66\u7248\u5757\u4f7f\u7528 \ud83d\udcda \u6807\u6ce8\uff0c\u7cbe\u54c1\u8bfe\u7a0b\u7248\u5757\u4f7f\u7528 \ud83c\udfeb \u6807\u6ce8\u3002

\u5fae\u79ef\u5206

23-24\u8f85\u5b66\u7fa4\uff1a204755170

\u6570\u5b66\u5206\u6790

23-24\u8f85\u5b66\u7fa4\uff1a618962803 \u7b2c\u4e00\u8bb2\uff1a\u6570\u5217\u6781\u9650

\u7ebf\u6027\u4ee3\u6570

23-24\u8f85\u5b66\u7fa4\uff1a913067714 \u3010\u7cbe\u54c1\u8bfe\u7a0b\u3011\u7ebf\u6027\u4ee3\u6570\uff1a\u672a\u7adf\u4e4b\u7f8e

\u7a0b\u5e8f\u8bbe\u8ba1

23-24\u8f85\u5b66\u7fa4\uff1a728919863 \u3010\u7cbe\u54c1\u8bfe\u7a0b\u3011\u7cfb\u7edf\u77e5\u8bc6\u62fe\u9057 \u3010\u7cbe\u54c1\u8bfe\u7a0b\u3011\u5b9e\u7528\u6280\u80fd\u62fe\u9057

\u666e\u901a\u5316\u5b66

23-24\u8f85\u5b66\u7fa4\uff1a635023447

\u666e\u901a\u7269\u7406\u5b66

22-23\u8f85\u5b66\u7fa4\uff1a727382522

"},{"location":"#_2","title":"\u8f85\u5b66\u7b80\u4ecb","text":"
  • \u6bcf\u4e2a\u957f\u5b66\u671f\u521d\uff0c\u6211\u4eec\u4f1a\u62db\u52df\u4f18\u79c0\u7684\u5b66\u957f\u5b66\u59d0\u4f5c\u4e3a\u8f85\u5b66\u5b66\u957f\u3002\u6240\u6709\u8f85\u5b66\u5b66\u957f\u90fd\u4f1a\u5728\u8f85\u5b66\u7fa4\u5185\u8fdb\u884c\u7b54\u7591\uff0c\u90e8\u5206\u8f85\u5b66\u5b66\u957f\u4f1a\u8fdb\u884c\u6388\u8bfe\u3002

  • \u6388\u8bfe\u4e00\u822c\u4f9d\u7167\u8bfe\u7a0b\u8fdb\u5ea6\u8fdb\u884c\uff0c\u5bf9\u4e13\u9898\u7684\u77e5\u8bc6\u8fdb\u884c\u603b\u7ed3\u590d\u4e60\uff0c\u6216\u662f\u5728\u671f\u4e2d\u671f\u672b\u8003\u524d\u8fdb\u884c\u590d\u4e60\u548c\u4e60\u9898\u8bb2\u89e3\u3002\u5f00\u5c55\u6388\u8bfe\u524d\u4e00\u5468\uff0c\u8f85\u5b66\u7fa4\u5185\u4f1a\u53d1\u5e03\u6388\u8bfe\u4fe1\u606f\u548c\u62a5\u540d\u95ee\u5377\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u6839\u636e\u81ea\u5df1\u7684\u9700\u6c42\u9009\u62e9\u53c2\u52a0\u3002

  • \u6b64\u5916\uff0c\u90e8\u5206\u8bfe\u7a0b\u5f00\u8bbe\u4e86\u8f85\u5b66\u7cbe\u54c1\u8bfe\u7a0b\u3002\u6388\u8bfe\u5b66\u957f\u5b66\u59d0\u4ee5\u8bfe\u7a0b\u7ec4\u7684\u5f62\u5f0f\u7ec4\u7ec7\u8d77\u6765\uff0c\u7f16\u5199\u7cfb\u7edf\u7684\u914d\u5957\u7684\u8bb2\u4e49\uff0c\u8fdb\u884c\u8fde\u8d2f\u7684\u6388\u8bfe\uff0c\u6df1\u5ea6\u5951\u5408\u7afa\u9662\u8363\u8a89\u8bfe\u7a0b\u7684\u5185\u5bb9\u3002\u6211\u4eec\u5e0c\u671b\u80fd\u643a\u624b\u4f18\u79c0\u7684\u5b66\u957f\u5b66\u59d0\uff0c\u4e3a\u7afa\u9662\u5b66\u5b50\u6253\u9020\u9ad8\u8d28\u91cf\u7684\u8f85\u5b66\u8bfe\u7a0b\u3002

"},{"location":"#_3","title":"\u5927\u6587\u4ef6\u5b58\u653e\u5904","text":"

\u8d85\u8fc7 20MB \u7684\u5927\u6587\u4ef6\u90fd\u653e\u7f6e\u5728\u5b66\u4e1a\u6307\u5bfc\u4e2d\u5fc3\u516c\u5171\u7f51\u76d8\u7684\u5206\u4eab\u94fe\u63a5\u4e2d\uff0c\u540c\u5b66\u4eec\u53ef\u4ee5\u70b9\u51fb\u4e0b\u9762\u7684\u94fe\u63a5\u67e5\u770b\u3002\u5982\u679c\u6709\u9700\u8981\u653e\u7f6e\u7684\u5927\u6587\u4ef6\uff0c\u8bf7\u8054\u7cfb\u5b66\u4e1a\u6307\u5bfc\u4e2d\u5fc3\u7684\u540c\u5b66\u4e0a\u4f20\u3002

  • \u767e\u5ea6\u7f51\u76d8-\u7afa\u9662\u8f85\u5b66\u8d44\u6599
"},{"location":"#_4","title":"\u76f8\u5173\u7f51\u7ad9","text":"
  • \u6d59\u6c5f\u5927\u5b66\u56fe\u7075\u73ed\u8bfe\u7a0b\u5b66\u4e60\u6307\u5357
  • \u6d59\u6c5f\u5927\u5b66\u8bfe\u7a0b\u653b\u7565\u5171\u4eab\u8ba1\u5212
"},{"location":"#_5","title":"\u8d21\u732e","text":"

\u5982\u679c\u60a8\u613f\u610f\u53c2\u4e0e\u8be5\u7f51\u7ad9\u7684\u5efa\u8bbe\uff0c\u8bf7\u5230 GitHub \u4e2d\u672c\u9879\u76ee\u7684\u4ed3\u5e93\u8fdb\u884c\u8d21\u732e\u3002

"},{"location":"test/","title":"LaTeX \u6570\u5b66\u516c\u5f0f\u6d4b\u8bd5","text":"

\u672c\u9875\u9762\u7528\u4e8e\u6d4b\u8bd5\u5404\u7c7b LaTeX \u516c\u5f0f\u662f\u5426\u80fd\u6b63\u5e38\u663e\u793a\u3002

simple

\\[ x ={-b \\pm \\sqrt{b^2-4ac}\\over 2a} \\]

matrix

\\[ \\left\\{\\begin{matrix} x=a + r\\text{cos}\\theta \\\\ y=b + r\\text{sin}\\theta \\end{matrix}\\right. \\]

array

\\[ \\begin{array}{l} a\\mathop{{x}}\\nolimits^{{2}}+bx+c=0 \\\\ \\Delta =\\mathop{{b}}\\nolimits^{{2}}-4ac \\\\ \\mathop{{x}}\\nolimits_{{1,2}}=\\frac{{-b \\pm \\sqrt{{\\mathop{{b}}\\nolimits^{{2}}-4ac}}}}{{2a}} \\\\ \\mathop{{x}}\\nolimits_{{1}}+\\mathop{{x}}\\nolimits_{{2}}=-\\frac{{b}}{{a}} \\\\ \\mathop{{x}}\\nolimits_{{1}}\\mathop{{x}}\\nolimits_{{2}}=\\frac{{c}}{{a}} \\end{array} \\]

calculus

\\[ \\int \\frac{1}{\\sqrt{1-x^{2}}}\\mathrm{d}x= \\arcsin x +C \\]

algebra

\\[ \\begin{vmatrix} \\mathbf{i}& \\mathbf{j}& \\mathbf{k} \\\\ \\frac{\\partial X}{\\partial u}& \\frac{\\partial Y}{\\partial u}& 0 \\\\ \\frac{\\partial X}{\\partial v}& \\frac{\\partial Y}{\\partial v}& 0 \\\\ \\end{vmatrix} \\]

physics

\\[ \\mathop \\Phi \\nolimits_e = \\oint { \\mathord{ \\buildrel{ \\lower3pt \\hbox{$ \\scriptscriptstyle \\rightharpoonup$}} \\over E} \\cdot {d \\mathord{ \\buildrel{ \\lower3pt \\hbox{$ \\scriptscriptstyle \\rightharpoonup$}} \\over S}} = {1 \\over {{\\varepsilon _0}}}\\sum {q} } \\]

Unicode

\\[ %\u6b64\u516c\u5f0f\u9700\u8981\u5728\u8bbe\u7f6e\u4e2d\u5f00\u542funicode\u6269\u5c55\u652f\u6301 \\begin{array}{l} {\\huge \\unicode{8751}}_\\mathbb{S} \\mathbf{E} \\cdot\\mathrm{d}s= \\cfrac{Q}{\\varepsilon_0} \\\\ {\\huge \\unicode{8751}}_\\mathbb{S} \\mathbf{B} \\cdot\\mathrm{d}s= 0 \\\\ {\\huge \\oint}_{\\mathbb{L}}^{} \\mathbf{E} \\cdot \\mathrm{d}l=-\\cfrac{\\mathrm{d}\\Phi _{\\mathbf{B}}}{\\mathrm{d}t } \\\\ {\\huge \\oint}_{\\mathbb{L}}^{} \\mathbf{B} \\cdot \\mathrm{d}l=\\mu_0I+ \\mu_0 \\varepsilon_0\\cfrac{\\mathrm{d}\\Phi _{\\mathbf{E}}}{\\mathrm{d}t } \\end{array} \\]

mhchem

\\[ %\u6b64\u516c\u5f0f\u9700\u8981\u5728\u3010\u8bbe\u7f6e\u3011\u4e2d\u5f00\u542fmhchem\u6269\u5c55\u652f\u6301 \u5177\u4f53\u7528\u6cd5\u8bf7\u53c2\u8003\u3010\u5e2e\u52a9\u30112.11.2 \\ce{SO4^2- + Ba^2+ -> BaSO4 v} \\]"},{"location":"algebra/","title":"\u7ebf\u6027\u4ee3\u6570\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u7ebf\u6027\u4ee3\u6570\u7248\u5757\ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"analysis/","title":"\u6570\u5b66\u5206\u6790\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u6570\u5b66\u5206\u6790\u7248\u5757 \ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"analysis/#2023-2024","title":"2023-2024 \u5b66\u5e74\u6388\u8bfe\u5f52\u6863","text":"\u8282\u6b21 \u65f6\u95f4 \u5185\u5bb9 \u4e3b\u8bb2 \u8bb2\u4e49 \u5f55\u64ad\u5730\u5740 1 Oct.14 \u6570\u5217\u6781\u9650 \u80e1\u80b2\u73ae \u7b2c\u4e00\u8bb2\uff1a\u6570\u5217\u6781\u9650"},{"location":"analysis/#_2","title":"\u8d44\u6e90\u5f52\u6863","text":"
  • \u6570\u5b66\u5206\u6790 I/II\uff08H\uff09\u5386\u5e74\u5377\u6574\u7406
  • 2023 \u5e74\u8f85\u5b66\u8d44\u6599\u5f52\u6863
"},{"location":"analysis/exam/","title":"\u6570\u5b66\u5206\u6790 I/II\uff08H\uff09\u5386\u5e74\u5377\u6574\u7406","text":""},{"location":"analysis/exam/#ih","title":"\u6570\u5b66\u5206\u6790 I\uff08H\uff09","text":"
  • 2022-2023 \u5b66\u5e74
    • \u5c0f\u6d4b1
    • \u5c0f\u6d4b2
    • \u671f\u672b\u8bd5\u5377
  • 2021-2022 \u5b66\u5e74
    • \u5c0f\u6d4b | \u7b54\u6848
    • \u671f\u672b\u8bd5\u5377 | \u7b54\u6848
  • 2020-2021 \u5b66\u5e74
    • \u671f\u672b\u8bd5\u5377\uff08\u90e8\u5206\uff09
"},{"location":"analysis/exam/#iih","title":"\u6570\u5b66\u5206\u6790 II\uff08H\uff09","text":"
  • 2022-2023 \u5b66\u5e74
    • \u5c0f\u6d4b1 | \u7b54\u6848
    • \u5c0f\u6d4b2 | \u7b54\u6848
    • \u671f\u672b\u8bd5\u5377 | \u7b54\u6848
  • 2021-2022 \u5b66\u5e74
    • \u671f\u672b\u8bd5\u5377 | \u7b54\u6848
  • 2020-2021 \u5b66\u5e74
    • \u671f\u672b\u8bd5\u5377
  • \u672a\u77e5\u5e74\u4efd
    • \u5c0f\u6d4b\u53ca\u7b54\u6848
"},{"location":"analysis/2023/","title":"2022-2023\u5b66\u5e74 \u6570\u5b66\u5206\u6790\u8f85\u5b66 \u8d44\u6599\u5f52\u6863","text":"\u8d44\u6599 \u8d21\u732e\u8005 \u4e0d\u5b9a\u79ef\u5206 \u9646\u6676\u5b87 \u6570\u5b66\u5206\u6790I \u8003\u524d\u590d\u4e601 \u90b1\u65e5\u5b8f \u6570\u5b66\u5206\u6790I \u8003\u524d\u590d\u4e602 | \u7b54\u6848 \u6f58\u6636\u7693 \u7ea7\u6570 | \u7b54\u6848 \u5218\u5fd7\u709c \u66f2\u7ebf\u3001\u66f2\u9762\u3001\u542b\u53c2\u53d8\u91cf\u79ef\u5206 \u738b\u5bb8\u660a"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/","title":"\u7b2c\u4e00\u8bb2 \u6570\u5217\u6781\u9650","text":"
  • PDF \u7248
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_2","title":"\u5b9e\u6570\u5b8c\u5907\u6027\u5b9a\u7406","text":""},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_3","title":"\u8981\u6c42","text":"
  1. \u7ed9\u51fa\u6982\u5ff5\u3001\u5b9a\u7406\u7684\u540d\u5b57\u53ef\u4ee5\u4f7f\u7528\u6570\u5b66\u8bed\u8a00\u51c6\u786e\u53d9\u8ff0\u3002

  2. \u638c\u63e1\u57fa\u672c\u7684\u5b9a\u7406\u8bc1\u660e\u94fe\uff08\u8be6\u7ec6\u53c2\u80031.4.1 1.4.2\uff09\uff1a

    • \u786e\u754c\u539f\u7406\\(\\rightarrow\\)\u5355\u8c03\u6709\u754c\u5b9a\u7406\\(\\rightarrow\\)\u81f4\u5bc6\u6027\u5b9a\u7406\\(\\rightarrow\\)Cauchy\u51c6\u5219

    • \u5355\u8c03\u6709\u754c\u5b9a\u7406\\(\\rightarrow\\)\u95ed\u533a\u95f4\u5957\u5b9a\u7406\\(\\rightarrow\\)\u6709\u9650\u8986\u76d6\u5b9a\u7406\uff08\u805a\u70b9\u539f\u7406\u548cDedekind\u5206\u5272\u5b9a\u7406\u4e0d\u8981\u6c42\uff09

    • \u786e\u754c\u539f\u7406\\(\\rightarrow\\)\u5404\u4e2a\u5b9a\u7406

  3. \u671f\u672b\u8003\u8bd5\u4f1a\u5728\u8fd9\u51e0\u4e2a\u5b9a\u7406\u91cc\u51fa\u53d9\u8ff0\u9898\u548c\u8bc1\u660e\u9898\uff1b\u5c0f\u6d4b\u4f1a\u8003\u5404\u4e2a\u5b9a\u7406\u7684\u6570\u5b66\u53d9\u8ff0\u7ec6\u8282\u3002

"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_4","title":"\u6982\u5ff5\u53d9\u8ff0","text":"
  1. \u6709\u754c\uff0c\u65e0\u754c

    \\[ \\begin{align} \u6570\u5217\u6709\u754c: &\\quad\\forall n>0,\\exists M\\in \\text{R},\u4f7f|x_n|<M\u6052\u6210\u7acb\\\\ \u6570\u5217\u65e0\u754c: &\\quad\\forall M\\in \\text{R},\\exists n>0,\u4f7f|x_n|>M \\\\ \u9519\u8bef(?): &\\quad\\exists n>0,\\forall M\\in \\text{R},\u4f7fx_n>M \\end{align} \\]

    \u6570\u5b66\u8bed\u8a00\u7684\u5426\u5b9a\uff1a\u8f6c\u6362\u5168\u79f0\u91cf\u8bcd\u548c\u5b58\u5728\u91cf\u8bcd\uff0c\u6ce8\u610f\u91cf\u8bcd\u987a\u5e8f\uff0c\u6539\u53d8\u7b26\u53f7

  2. \u6700\u5927\u6570\uff0c\u6700\u5c0f\u6570

    \\[ \\begin{align} \\max\\{S\\}=a &\\iff a\\in S\u4e14\\forall x\\in S,a\\ge x\\\\ \\min\\{S\\}=b &\\iff b\\in S\u4e14\\forall x\\in S,b\\le x \\end{align} \\]
  3. \u4e0a\u786e\u754c\uff0c\u4e0b\u786e\u754c

    \\[ \\begin{align} M=\\sup\\{S\\}\\iff& \\forall x\\in S,x\\le M\u4e14\\forall\\epsilon>0,\\exists x'\\in S\u6709x'>M-\\epsilon\\\\ m=\\inf\\{S\\}\\iff& \\forall x\\in S,x\\ge m\u4e14\\forall\\epsilon>0,\\exists x'\\in S\u6709x'<M+\\epsilon \\end{align} \\]
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_5","title":"\u5b9a\u7406\u53d9\u8ff0","text":"
  1. \u786e\u754c\u539f\u7406

    \u975e\u7a7a\u6709\u754c\u96c6\u5fc5\u6709\u4e0a\u4e0b\u786e\u754c

  2. \u5355\u8c03\u6709\u754c\u5b9a\u7406

    \u5355\u8c03\u6709\u754c\u6570\u5217\u5fc5\u6536\u655b

  3. \u81f4\u5bc6\u6027\u5b9a\u7406

    \u4efb\u4f55\u6709\u754c\u6570\u5217\u5fc5\u6709\u6536\u655b\u5b50\u5217

  4. Cauchy\u51c6\u5219

    \\[ a_n\u6536\u655b\\iff\\forall \\epsilon>0,\\exists N>0,\\forall m,n>N,\u5747\u6709|a_m-a_n|<\\epsilon \\\\ \\iff \\forall \\epsilon>0,\\exists N>0,\\forall n>N,p>0,\u5747\u6709|a_{n+p}-a_n|<\\epsilon \\]
  5. \u533a\u95f4\u5957\u5b9a\u7406

    \\[ \\begin{align} & \u8bbe\u95ed\u533a\u95f4\u5217\\{[a_n,b_n]\\}\u6ee1\u8db3:\\\\ & 1.[a_{n+1},b_{n+1}]\\subset[a_n,b_n],n=1,2,3..\\\\ & 2.\\lim_{n\\to\\infty}(b_n-a_n)=0 \\\\ & \u5219\u5b58\u5728\u552f\u4e00\u5b9e\u6570\\xi\uff0c\u6ee1\u8db3\\xi\\in[a_n,b_n],n=1,2.. \\end{align} \\]
  6. \u6709\u9650\u8986\u76d6\u5b9a\u7406

    \\[ \\begin{align} & \u8bbe[a,b]\u662f\u4e00\u4e2a\u95ed\u533a\u95f4\uff0c\\{E_\\lambda\\}_{\\lambda\\in\\Lambda}\u662f[a,b]\u7684\u4efb\u610f\u4e00\u4e2a\u5f00\u8986\u76d6\uff0c\\\\ & \u5219\u5fc5\u5b58\u5728\\{E_\\lambda\\}_{\\lambda\\in\\Lambda}\u7684\u4e00\u4e2a\u5b50\u96c6\u6784\u6210[a,b]\u7684\u4e00\u4e2a\u6709\u9650\u8986\u76d6\u3002 \\\\ \\iff & \u5728\\{E_\\lambda\\}_{\\lambda\\in\\Lambda}\u5fc5\u6709\u6709\u9650\u4e2a\u5f00\u533a\u95f4E_1,E_2..E_N\u4f7f[a,b]\\subset\\cup_{j=1}^NE_j \\end{align} \\]
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_6","title":"\u5e38\u7528\u6280\u5de7","text":"
  1. \u8bc1\u660e\u96c6\u5408\u76f8\u7b49\u7684\u5e38\u7528\u65b9\u6cd5\uff1a\u76f8\u4e92\u5305\u542b

    \u4f8b\u9898\uff1a\u786e\u754c\u7684\u5173\u7cfb\u5f0f

    \u8bbe \\(A,B\\) \u662f\u4e24\u4e2a\u7531\u975e\u8d1f\u6570\u7ec4\u6210\u7684\u4efb\u610f\u6570\u96c6,\u8bd5\u8bc1\u660e \\(\\sup_{x\\in A}\\{x\\}\\cdot \\sup_{y\\in B}\\{y\\}=\\sup_{x\\in A,y\\in B}\\{xy\\}\\)

  2. \u5bf9\u4e8e\u5b9e\u6570\u5b8c\u5907\u6027\u5b9a\u7406\u7684\u8bc1\u660e\u9898\uff0c\u9996\u5148\u5c06\u7ed9\u7684\u6761\u4ef6\u548c\u8bc1\u660e\u5185\u5bb9\u5747\u7ffb\u8bd1\u6210\u6570\u5b66\u8bed\u8a00\uff08\u65b9\u4fbf\u9a97\u5206\uff09\uff0c\u518d\u89c2\u5bdf\u6761\u4ef6\u548c\u8bc1\u660e\u5185\u5bb9\u7684\u8054\u7cfb\u3002

"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_7","title":"\u4f8b\u9898&\u4e60\u9898","text":"
  1. \u7528\u786e\u754c\u539f\u7406\u8bc1\u660e\u5355\u8c03\u6709\u754c\u539f\u7406\u3001\u81f4\u5bc6\u6027\u5b9a\u7406\u3001Cauchy\u51c6\u5219\u3001\u95ed\u533a\u95f4\u5957\u5b9a\u7406\u3001\u6709\u9650\u8986\u76d6\u5b9a\u7406\u3002
  2. \u7528\u5355\u8c03\u6709\u754c\u5b9a\u7406\u8bc1\u660e\u95ed\u533a\u95f4\u5957\u5b9a\u7406\uff0c\u7528\u95ed\u533a\u95f4\u5957\u5b9a\u7406\u8bc1\u660e\u6709\u9650\u8986\u76d6\u5b9a\u7406\uff1b\u7528\u81f4\u5bc6\u6027\u5b9a\u7406\u8bc1\u660eCauchy\u6536\u655b\u51c6\u5219\u3002
  3. \\(f,g\u4e3aD\u4e0a\u6709\u754c\u51fd\u6570,\\text{pf:}\\inf\\{f(x)+g(x)\\}\\le\\inf{f(x)}+\\sup{g(x)}\\)
  4. \u8bbe\\(f(x)\u5728[0,1]\u4e0a\u9012\u589e,f(0)>0,f(1)<1,\u6c42\u8bc1:\\exists x_0\\in(0,1),\u4f7f\u5f97f(x_0)=x_0^2\\) (Hint:\u786e\u754c\u539f\u7406or\u533a\u95f4\u5957\u5b9a\u7406)
  5. \u8bbe\\(f(x)\\)\u5728\\([a,b]\\)\u4e0a\u6709\u5b9a\u4e49\u4e14\u5728\u6bcf\u4e00\u70b9\u5904\u51fd\u6570\u7684\u6781\u9650\u5b58\u5728\uff0c\u6c42\u8bc1\\(f(x)\\)\u5728\\([a,b]\\)\u4e0a\u6709\u754c (Hint:\u6709\u9650\u8986\u76d6)
  6. \\(\u8bbef(x)\u5728(a,b)\u5185\u6709\u5b9a\u4e49\uff0c\\forall\\xi\\in(a,b),\\exists\\delta>0,\u5f53x\\in(\\xi-\\delta,\\xi+\\delta)\\cap(a,b)\u65f6,\\)\u6709\u5f53\\(x<\\xi\\)\u65f6,\\(f(x)<f(\\xi), \u5f53x>\\xi\\)\u65f6,\\(f(x)>f(\\xi)\\).\u8bf7\u8bc1\u660e:\\(f(x)\u5728(a,b)\\)\u5185\u4e25\u683c\u9012\u589e (Hint:\u6709\u9650\u8986\u76d6)
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_8","title":"\u6570\u5217\u6781\u9650","text":""},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_9","title":"\u8981\u6c42","text":"
  1. \u4ece\u5c0f\u6d4b\u7684\u89d2\u5ea6\u6765\u8bf4\uff0c\u6982\u5ff5\uff0c\u5b9a\u7406\u4ee5\u53ca\u5224\u65ad\u9898\u662f\u6bd4\u8f83\u91cd\u8981\uff08\u641e\u8111\u5b50\uff09\u7684\uff0c\u5f53\u7136\u4e5f\u4f1a\u6709\u8ba1\u7b97\u9898
  2. \u671f\u672b\u8003\u8bd5\u53ef\u80fd\u4f1a\u51fa1-2\u9053\u6c42\u6781\u9650\uff0c1\u9053\u975e\u5e38\u7b80\u5355\u7684\u6781\u9650\u8bc1\u660e\u9898\uff08\u9644\u5728\u5b9a\u7406\u53d9\u8ff0\u4e0a\uff09
  3. \u8ba1\u7b97\u4e5f\u9700\u8981\u638c\u63e1\uff0c\u4f46\u662f\u6280\u5de7\u6027\u5f3a\u7684\u53ef\u4ee5\u4e0d\u638c\u63e1
  4. \u5b66\u597d\u6570\u5217\u6781\u9650\u5bf9\u51fd\u6570\u6781\u9650\u548c\u7ea7\u6570\u90fd\u5f88\u6709\u5e2e\u52a9\uff0c\u800c\u5b66\u597d\u4e86\u51fd\u6570\u6781\u9650\u5c31\u53ef\u4ee5\u5b66\u597d\u5bfc\u6570\u548c\u79ef\u5206\uff0c\u7136\u540e\u4f60\u5c31\u5b66\u4f1a\u4e86\u6570\u52061
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_10","title":"\u6982\u5ff5\u53d9\u8ff0","text":"
  1. \u6570\u5217\u6781\u9650\uff08\\(\\epsilon-N\\)\u8bed\u8a00\uff09
\\[ \\forall\\epsilon>0,\\exists N>0,\\forall n>N,|x_n-A|<\\epsilon\u79f0\\lim_{x\\rightarrow\\infty}x_n=A\\\\ *:|x_n-A|<f(\\epsilon),f(x)\u6ee1\u8db3\\lim _{x\\rightarrow0}f(x)=0\u5373\u53ef \\]
  1. \u6570\u5217\u53d1\u6563
\\[ \\forall A\\in R,\\exists\\epsilon_0>0,\\forall N>0,\\exists n_N>N,|x_n-A|\\ge\\epsilon_0 \\]
  1. \u5b50\u5217

    \\[ \\{a_n\\}\u6536\u655b\\iff \\{a_n\\}\u7684\u4efb\u610f\u5b50\u5217\u90fd\u6536\u655b\u4e8eA(\u8bf7\u6ce8\u610f\u51cf\u5f31\u547d\u9898) \\]
  2. \u65e0\u7a77\u5c0f\u91cf\u548c\u65e0\u7a77\u5927\u91cf

    \\[ \\begin{align} & \u65e0\u7a77\u5c0f\u91cf : \\lim_{x\\rightarrow\\infty}= 0 \\\\ & \u65e0\u7a77\u5927\u91cf : \\forall M>0,\\exists N,\\forall n>N,|x_n|>M \\end{align} \\]
"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_11","title":"\u5b9a\u7406\u53d9\u8ff0","text":"
  1. Stolz\u5b9a\u7406

    \u5e38\u7528\u4e8e\u8ba1\u7b97\u5f62\u5f0f\u9700\u8981\u6d1b\u5fc5\u8fbe\u7684\u6781\u9650

  2. Cauchy\u6536\u655b\u51c6\u5219\u3001\u7b49\u4ef7\u5f62\u5f0f\u53ca\u5426\u5b9a

\\[ \\begin{align} a_n\u6536\u655b& \\iff\\forall \\epsilon>0,\\exists N>0,\\forall m,n>N,\u5747\u6709|a_m-a_n|<\\epsilon \\\\ & \\iff \\forall \\epsilon>0,\\exists N>0,\\forall n>N,p>0,\u5747\u6709|a_{n+p}-a_n|<\\epsilon \\\\ \u5426\u5b9a\u5f62\u5f0f:a_n\u53d1\u6563& \\iff\\exists\\epsilon_0>0,\\forall N,\\exists n_0>N,p>0,|x_{n_0+p}-x_{n_0}|\\ge\\epsilon_0 \\end{align} \\]"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_12","title":"\u5e38\u7528\u6280\u5de7","text":"
  1. \u4e00\u4e9b\u5173\u7cfb\u94fe\uff1a

    1. \\(n\\rightarrow\\infty\u65f6\\)
    \\[ \\log\\log n\\ll \\log n \\ll n^a\\ll b^n\\ll n!\\ll n^n\\quad(a,b>0) \\]
    1. \\(x\\rightarrow0\u65f6\\)
    \\[ \\begin{align} x \\sim &\\sin x\\sim \\tan x \\sim \\arcsin x\\sim \\arctan x \\\\ \\sim &\\ln{(1+x)} \\sim \\text{e}^x-1 \\sim \\frac{a^x-1}{\\ln a}\\sim \\frac{(1+x)^b-1}b \\quad(a>0,b\\neq0)\\\\ & 1-\\cos x \\sim \\frac12 x^2 \\end{align} \\]
  2. \u8bc1\u660e\u6570\u5217\u6781\u9650\u5b58\u5728\uff1a

    1. \u5b9a\u4e49\uff08\\(\\epsilon-N\\)\u65b9\u6cd5\uff09

    \u6280\u5de7\uff1a\u653e\u5927\u6cd5(\u5e38\u7528)/\u5206\u6b65\u6cd5/\u6784\u9020\u5f62\u5f0f\u7c7b\u4f3c\u7684\u9879/\u62df\u5408\u6cd5(\u6280\u5de7\u6027\u8f83\u5f3a)

    1. Cauchy\u51c6\u5219\uff1a\u4e0d\u9700\u8981\u77e5\u9053\u6781\u9650\u503c

    2. Cauchy\u51c6\u5219\u7684\u63a8\u8bba\uff1a\u5e38\u7528\u4e8e\u5224\u65ad\u6570\u9879\u7ea7\u6570\u662f\u5426\u6536\u655b(\\(a_n=\\sum_{n=1}^{\\infty}f(n)\\))

    3. \u5355\u8c03\u6709\u754c\u539f\u7406\uff1a\u4e0d\u52a8\u70b9\uff0c\u9012\u63a8\u5f0f\u8003\u8651

    4. \u6781\u9650\u7684\u8fd0\u7b97\u6027\u8d28\uff1a\u672c\u8eab\u5b58\u5728\u6781\u9650 \u6709\u9650\u9879\u8fd0\u7b97

  3. \u8bc1\u660e\u6570\u5217\u6781\u9650\u4e0d\u5b58\u5728\uff1a

    1. Cauchy\u547d\u9898\u7684\u5426\u5b9a\u5f62\u5f0f
    2. \u5b50\u5217\u4e0d\u6536\u655b\u6216\u6536\u655b\u4e8e\u4e0d\u540c\u7684\u6570
  4. \u6c42\u6570\u5217(\u51fd\u6570)\u6781\u9650\uff1a

    1. \u6781\u9650\u7684\u8fd0\u7b97\u6027\u8d28

    \u4e00\u4e9b\u91cd\u8981\u6781\u9650\uff1a\\(\\lim\\limits_{n\\rightarrow\\infty}n^\\frac1n=1\\)\uff0c\\(\\lim\\limits_{n\\rightarrow\\infty}(1+\\frac1n)^n=e\\)

    1. Stolz\u5b9a\u7406

    2. \u5939\u903c\u5b9a\u7406

    3. \u7b49\u4ef7\u4ee3\u6362\u4e0e\u521d\u7b49\u53d8\u5f62

    4. \u9012\u63a8\u5f62\u5f0f\u7684\u6781\u9650\uff1a\u5355\u8c03\u6709\u754c\u539f\u7406+\u8bc1\u660e/\u538b\u7f29\u6620\u50cf(\u7565\u96be)/Stolz\u516c\u5f0f\u7684\u5e94\u7528

    5. Taylor/L'Hospital/\u79ef\u5206\u5b9a\u4e49/\u6570\u9879\u7ea7\u6570/\u7ea7\u6570\u7684\u8fde\u7eed\u6027...\uff1a \u5f88\u91cd\u8981\uff0c\u4f46\u8fd9\u662f\u540e\u4e8b\u4e86

"},{"location":"analysis/2024/analysis_lecture1_sequence_limits/#_13","title":"\u4f8b\u9898&\u4e60\u9898","text":"
  1. \u5224\u65ad\u4e0b\u5217\u5173\u4e8e\u5b50\u5217\u7684\u547d\u9898

    1. \u8bbe\\(\\{a_n\\}\\)\u662f\u4e00\u4e2a\u6570\u5217\uff0c\u82e5\u5728\u4efb\u4e00\u5b50\u5217\\(\\{a_{n_k}\\}\\)\u4e2d\u5747\u5b58\u5728\u6536\u655b\u5b50\u5217\\(\\(\\{a_{n_{k_r}}\\}\\)\\),\u5219\\(\\(\\{a_n\\}\\)\\)\u5fc5\u6536\u655b
    2. \\(\\{a_n\\}\u5355\u8c03\u9012\u589e\uff0c\\{a_{n_k}\\}\u4e3a\u5176\u4e2d\u4e00\u4e2a\u5b50\u5217\uff0c\\lim\\limits_{k\\rightarrow\\infty}a_{n_k}=a,\u5219\\lim\\limits_{n\\rightarrow\\infty}{a_n}=a\\)
    3. \\(\\{a_{2k}\\}\\{a_{2p+1}\\}\\{a_{2023t+2024}\\}\u5747\u6536\u655b\uff0c\u5219\\{a_n\\}\u6536\u655b\\)
    4. \\(\\{a_{2k}\\}\\{a_{2t+1}\\}\\{a_{6p+5}\\}\u5747\u6536\u655b\uff0c\u5219\\{a_n\\}\u6536\u655b\\)
  2. \u5224\u65ad\u4e0b\u5217\u5173\u4e8e\u65e0\u7a77\u5c0f\u91cf\u7684\u547d\u9898

    1. \u65e0\u7a77\u591a\u4e2a\u65e0\u7a77\u5c0f\u91cf\u4e4b\u548c\u662f\u65e0\u7a77\u5c0f\u91cf
    2. \u65e0\u7a77\u591a\u4e2a\u65e0\u7a77\u5c0f\u91cf\u4e4b\u79ef\u662f\u65e0\u7a77\u5c0f\u91cf
    3. \u65e0\u7a77\u5c0f\u91cf\u4e0e\u6709\u754c\u91cf\u4e4b\u79ef\u4e3a\u65e0\u7a77\u5c0f\u91cf
  3. \u5224\u65ad\u4e0b\u5217\u5173\u4e8e\u6570\u5217\u6781\u9650\u7684\u547d\u9898

    1. \u6570\u5217\\(a_n\\)\u6536\u655b\\(\\iff \\forall p\\in N,\\lim\\limits_{n\\rightarrow+\\infty}{|a_{n+p}-a_n|=0}\\)
    2. \\(\\lim\\limits_{n\\rightarrow\\infty}x_n=A\\iff\\forall k\\in \\text{N},\\exists N>0,\\forall n>N,|x_n-A|<\\frac1k\\)
    3. \\(a_n\u6536\u655b \\iff \\exists N>0,\\forall \\epsilon>0,\\forall m,n>N,\u5747\u6709|a_m-a_n|<\\epsilon\\)
  4. \u91cd\u8981\u7684\u4e8c\u7ea7\u7ed3\u8bba\uff1a

\\[ Cauchy\u5b9a\u7406:\\lim_{n\\rightarrow\\infty}x_n=A,\u5219\\lim_{n\\rightarrow\\infty}\\frac{x_1+x_2+...+x_n}{n}=A \\]
  1. \\(x_n=\\sum_{i=1}^n\\sin(\\frac{2i-1}{n^2}a),\\text{pf:}\\lim\\limits_{n\\rightarrow\\infty}x_n=a\\) (Hint:\u62df\u5408\u6cd5)

  2. \u6c42\u6781\u9650\\(\\lim\\limits_{n\\rightarrow\\infty}x_n\\)\uff1a

    1. \\(x_n=\\cos\\frac x2\\cos\\frac x{2^2}\\cdots\\cos\\frac x{2^n}\\)
    2. \\(x_n=(\\frac{\\sqrt[n]a+\\sqrt[n]b}{2})^n\\)
    3. \\(x_n=\\frac 1{\\sqrt[n]{n!}}\\)
    4. \\(x_n={(n!)}^{\\frac1{n^2}}\\)
    5. \\(x_n=\\sqrt[6]{x^6+x^5}-\\sqrt[6]{x^6-x^5}\\)
  3. (2019(?)\u5e74\u6570\u52061\u671f\u672b)

\\[ \\begin{align} & \u5bf9\u4e8e\u6570\u5217x_0=a,0<a<\\frac\\pi2,x_n=\\sin x_{n-1}(n=1,2,\\cdots). \\\\ &\\text{pf:}(1)\\lim\\limits_{n\\rightarrow\\infty}x_n=0;(2)\\lim\\limits_{n\\rightarrow\\infty}{\\sqrt\\frac n3}x_n=1 \\end{align} \\]"},{"location":"calculus/","title":"\u5fae\u79ef\u5206\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u5fae\u79ef\u5206\u7248\u5757\ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"chemistry/","title":"\u666e\u901a\u5316\u5b66\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u666e\u901a\u5316\u5b66\u7248\u5757\ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"lalu/","title":"\u7ebf\u6027\u4ee3\u6570\uff1a\u672a\u7adf\u4e4b\u7f8e","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u7ebf\u6027\u4ee3\u6570\u8f85\u5b66\u7cbe\u54c1\u8bfe\u7a0b\u7248\u5757 \ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"lalu/#_2","title":"\u8bfe\u7a0b\u7b80\u4ecb","text":"

\u7ebf\u6027\u4ee3\u6570\u4f5c\u4e3a\u5927\u5b66\u6570\u5b66\u7684\u57fa\u7840\u8bfe\uff0c\u4e0e\u6570\u5b66\u5206\u6790\u4e0d\u540c\uff0c\u8fd9\u95e8\u8bfe\u7684\u4e00\u5f00\u59cb\u5c31\u4e0e\u4e2d\u5b66\u6570\u5b66\u7684\u98ce\u683c\u6709\u7740\u5f88\u5927\u7684\u5dee\u8ddd\uff0c\u8bb8\u591a\u540c\u5b66\u5728\u6b64\u95e8\u8bfe\u7684\u5165\u95e8\u4e0e\u8fdb\u9636\u65b9\u9762\u90fd\u9047\u89c1\u4e86\u5f88\u5927\u7684\u56f0\u96be\u3002\u4e3a\u89e3\u51b3\u6b64\u56f0\u96be\uff0c\u672c\u8bfe\u7a0b\u5e0c\u671b\u6df1\u5165\u6d45\u51fa\u5730\u5256\u6790\u6982\u5ff5\u4e0e\u5b9a\u7406\uff0c\u5e2e\u52a9\u540c\u5b66\u4eec\u4e86\u89e3\u7ebf\u6027\u4ee3\u6570\u201c\u5e72\u7684\u662f\u4ec0\u4e48\u4e8b\u201d\uff0c\u7406\u89e3\u7ebf\u6027\u4ee3\u6570\u7684\u672c\u8d28\uff0c\u4ee5\u53ca\u66f4\u597d\u638c\u63e1\u540e\u7eed\u7684\u8ba1\u7b97\u6280\u5de7\uff0c\u5b66\u597d\u7ebf\u4ee3\u8fd9\u95e8\u5927\u5b66\u7684\u5165\u95e8\u8bfe\uff01

"},{"location":"lalu/#_3","title":"\u8bfe\u9898\u7ec4\u6210\u5458","text":"
  • \u5434\u4e00\u822a \u56fe\u70752001
  • \u6885\u654f\u70ab \u56fe\u70752201
  • \u6f58\u90b9\u7eac \u5f3a\u72692101
  • \u859b\u8fb0\u7acb \u56fe\u70752203
"},{"location":"lalu/#_4","title":"\u8bfe\u7a0b\u5b89\u6392","text":"
  • \u7b2c\u4e00\u8bb2 \u5f15\u5165 \u7ebf\u6027\u7a7a\u95f4
    • \u9884\u8ba1\u7b2c 6 \u5468\uff0c\u5206\u4e24\u4e2a\u6559\u5b66\u73ed\u5f00\u8bfe\uff0c\u5434\u5fd7\u7965\u73ed\u4e0a\u5b8c\u5185\u79ef\uff0c\u8c08\u4e4b\u5955\u73ed\u4e0d\u4e0a\u5185\u79ef\uff08\u6216\u5434\u5fd7\u7965\u7b2c 5 \u5468\uff0c\u8c08\u4e4b\u5955\u7b2c 6 \u5468\uff09
    • \u8bb2\u4e49 1-2 \u8bb2\u91cd\u70b9\u5728\u4e8e\u4f20\u8fbe\u4e00\u4e9b\u57fa\u672c\u601d\u60f3\uff0c\u4f4e\u8d77\u70b9\u5f15\u5165\u4f46\u9ad8\u843d\u70b9
    • \u8bb2\u4e49\u7b2c 3 \u8bb2\u300a\u6709\u9650\u7ef4\u7ebf\u6027\u7a7a\u95f4\u300b\u4e00\u8bb2\u5efa\u8bae\u6309\u7167\u601d\u7ef4\u5bfc\u56fe\u8fdb\u884c\u5b8c\u6574\u4ecb\u7ecd
  • \u7b2c\u4e8c\u8bb2 \u7ebf\u6027\u6620\u5c04 \u671f\u4e2d\u590d\u4e60
    • \u9884\u8ba1\u7b2c 8 \u5468\uff0c\u5206\u4e24\u4e2a\u6559\u5b66\u73ed\u5f00\u8bfe\uff0c\u5434\u5fd7\u7965\u73ed\u4e0a\u5b8c\u77e9\u9635\u4e58\u6cd5\uff08\u77e9\u9635\u90e8\u5206\u53ef\u4ee5\u7565\u8bb2\uff0c\u4e4b\u540e\u6709\u4e13\u9898\uff09\uff0c\u8c08\u4e4b\u5955\u73ed\u4e0a\u5230\u7ebf\u6027\u6620\u5c04\u7ed3\u675f
    • \u5efa\u7acb\u5bf9\u7ebf\u6027\u7a7a\u95f4\u4e0e\u7ebf\u6027\u6620\u5c04\u7684\u6574\u4f53\u8ba4\u8bc6\uff0c\u7406\u89e3\u4e24\u4e2a\u7ef4\u6570\u516c\u5f0f\uff0c\u7406\u89e3\u540c\u6784
    • \u590d\u4e60\u90e8\u5206\u5bf9\u7279\u5b9a\u7684\u9898\u578b\u8fdb\u884c\u8bb2\u89e3\uff1a\u65b9\u7a0b\u7ec4\uff08\u542b\u53c2\uff09\uff0c\u6781\u5927\u7ebf\u6027\u65e0\u5173\u7ec4\uff0c\u76f4\u548c\u8bc1\u660e\uff0c\u50cf\u7a7a\u95f4\u6838\u7a7a\u95f4\u8bc1\u660e\u7b49\uff08\u7ed3\u5408\u5386\u5e74\u5377\u548c\u8bb2\u4e49\uff09
  • \u7b2c\u4e09\u8bb2 \u77e9\u9635
    • \u9884\u8ba1\u7b2c 11 \u5468\uff0c\u53ef\u4ee5\u5408\u73ed\u6559\u5b66\uff08\u6216\u5434\u5fd7\u7965\u7b2c 10 \u5468\uff0c\u8c08\u4e4b\u5955\u7b2c 11 \u5468\uff09
    • \u91cd\u70b9\u5728\u4e09\u4e2a\u5185\u5bb9\uff1a\u4e00\u4e2a\u662f\u7ebf\u6027\u6620\u5c04\u77e9\u9635\u8868\u793a\uff0c\u4e00\u4e2a\u662f\u77e9\u9635\u7684\u79e9\u7684\u6574\u4f53\u8ba4\u8bc6\uff0c\u6700\u540e\u662f\u4e00\u4e9b\u4e0a\u8bfe\u4e0d\u592a\u8bb2\u7684\u6280\u5de7
  • \u7b2c\u56db\u8bb2 \u884c\u5217\u5f0f \u7ebf\u6027\u65b9\u7a0b\u7ec4
    • \u9884\u8ba1\u7b2c 13 \u5468\uff0c\u53ef\u4ee5\u5408\u73ed\u6559\u5b66
    • \u884c\u5217\u5f0f\u91cd\u70b9\u5728\u7075\u6d3b\u8fd0\u7528\u4e00\u4e9b\u6027\u8d28\uff0c\u884c\u5217\u5f0f\u8ba1\u7b97\u89c6\u60c5\u51b5\u7ebf\u4e0b\u6388\u8bfe\u53ef\u4ee5\u629b\u5f03\uff08\u51c6\u5907\u7ebf\u4e0a\u8d44\u6599\u66ff\u4ee3\uff09\uff0c\u7ebf\u6027\u65b9\u7a0b\u7ec4\u91cd\u70b9\u5728\u4f53\u73b0\u300a\u671d\u82b1\u5915\u62fe\u300b\u7684\u6838\u5fc3\u601d\u60f3\uff0c\u7ebf\u6027\u65b9\u7a0b\u7ec4\u7406\u8bba\u610f\u5c3d
  • \u7b2c\u4e94\u8bb2 \u7279\u5f81\u503c\u4e0e\u77e9\u9635\u6807\u51c6\u5f62 \u671f\u672b\u590d\u4e60
    • \u9884\u8ba1\u7b2c 15 \u5468\uff0c\u53ef\u4ee5\u5408\u73ed\u6559\u5b66\uff0c\u4e5f\u53ef\u4ee5\u6309\u96be\u5ea6\u5206\u5c42\u6559\u5b66
    • \u7279\u5f81\u503c\u4e0e\u77e9\u9635\u6807\u51c6\u5f62\u90e8\u5206\u6839\u636e\u73ed\u7ea7\u6388\u8bfe\u8fdb\u5ea6\u786e\u5b9a\u5185\u5bb9\uff0c\u5982\u679c\u65f6\u95f4\u6709\u9650\u6216\u6559\u5b66\u73ed\u6ca1\u6709\u4e0a\u5b8c\u6b63\u8bfe\uff0c\u90e8\u5206\u5185\u5bb9\u79fb\u81f3\u7ebf\u4e0a\u51c6\u5907\u89c6\u9891
    • \u671f\u672b\u590d\u4e60\u90e8\u5206\u6574\u7406\u672c\u5b66\u671f\u5b8c\u6574\u601d\u8def\uff0c\u7ed3\u5408\u5386\u5e74\u5377\u548c\u8bb2\u4e49\u8bb2\u89e3\u6700\u6838\u5fc3\u7684\u9898\u578b
"},{"location":"lalu/#_5","title":"\u8bfe\u7a0b\u8bb2\u4e49","text":"

LALU \u8bfe\u7a0b\u7684\u8bb2\u4e49\u5b58\u653e\u5728\u4e0b\u9762\u7684\u4ed3\u5e93\u4e2d\uff0c\u4f60\u53ef\u4ee5\u70b9\u51fb\u56fe\u7247\u8df3\u8f6c\u5230\u4ed3\u5e93\u9875\u9762\u3002\u6b22\u8fce\u63d0\u51fa issue \u548c pull request\u3002

\u70b9\u51fb\u4e0b\u9762\u7684\u94fe\u63a5\u53ef\u4ee5\u4e0b\u8f7d\u8bb2\u4e49\u7684\u6700\u65b0 Release \u7248\u672c\uff1a

  • \u70b9\u51fb\u4e0b\u8f7d

"},{"location":"physics/","title":"\u666e\u7269\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u666e\u7269\u8f85\u5b66\u7248\u5757\ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"programming/","title":"\u7a0b\u5e8f\u8bbe\u8ba1\u8f85\u5b66","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u8f85\u5b66\u7a0b\u8bbe\u7248\u5757\ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

"},{"location":"programming/#faq","title":"FAQ","text":"

\u6211\u4eec\u4e3a\u5404\u4e2a\u6a21\u5757\u540c\u5b66\u4eec\u7ecf\u5e38\u9047\u5230\u7684\u95ee\u9898\u6574\u7406\u4e86\u4e00\u4e9b FAQ\uff1a

\u77e5\u8bc6\u6a21\u5757 FAQ \u6682\u65e0 \u6682\u65e0"},{"location":"programming/#_2","title":"\u5386\u5e74\u5377","text":"

\u8bf7\u8df3\u8f6c\u5230 \u5386\u5e74\u5377 \u9875\u9762\u3002\u5386\u5e74\u5377\u5747\u5df2\u4e0a\u4f20\u5b8c\u6210\uff0c\u7ecf\u5178\u9898\u76ee\u89e3\u6790\u8fd8\u5728\u6574\u7406\u4e2d\u3002

"},{"location":"programming/#_3","title":"\u5176\u4ed6\u8d44\u6e90","text":""},{"location":"programming/#_4","title":"\u5e38\u7528\u7f51\u7ad9","text":"
  • CPPReference\uff1aC/C++ \u53c2\u8003\u624b\u518c\uff0c\u53ef\u4ee5\u67e5\u627e C/C++ \u8bed\u6cd5\u548c\u6807\u51c6\u5e93\u7684\u7528\u6cd5\u7b49\u3002
"},{"location":"programming/#_5","title":"\u5b66\u957f\u5b66\u59d0\u7684\u7b14\u8bb0\u672c","text":"

\u5f88\u591a\u5b66\u957f\u5b66\u59d0\u90fd\u5728\u81ea\u5df1\u7684\u535a\u5ba2/\u7b14\u8bb0\u672c\u4e2d\u5199\u4e86\u4e00\u4e9b\u5173\u4e8e\u7a0b\u5e8f\u8bbe\u8ba1\u7684\u5185\u5bb9\uff0c\u8fd9\u91cc\u5217\u51fa\u4e00\u4e9b\u94fe\u63a5\uff0c\u4f9b\u5927\u5bb6\u53c2\u8003\u3002

  • \u56fe\u7075\u73ed\u5b66\u4e60\u6307\u5357\uff1a\u7a0b\u5e8f\u8bbe\u8ba1\u4e0e\u7b97\u6cd5\u57fa\u7840
  • TimeMachine\uff1aC-review
  • \u9e64\u7fd4\u4e07\u91cc\uff1aC \u8bed\u8a00\u6742\u9879
  • Isshiki\u4fee\uff1aC\u5c0f\u7a0b \u7410\u788e\u77e5\u8bc6\u70b9\u6574\u7406
  • \u6e90\u8679\u7ffc\uff1aZJU\u79cb\u7a0b\u8bbe\u5b66\u4e60\u7b14\u8bb0
"},{"location":"programming/faq/","title":"\u5e38\u89c1\u95ee\u9898","text":""},{"location":"programming/faq/#_2","title":"\u6307\u9488\u3001\u58f0\u660e","text":""},{"location":"programming/faq/#_3","title":"\u600e\u4e48\u8bfb\u58f0\u660e\uff1f","text":"
  • \u8be6\u89c1\uff1aReading C type declarations (unixwiz.net)
"},{"location":"programming/faq/#_4","title":"\u51fd\u6570\u4e0e\u51fd\u6570\u6307\u9488","text":"

Author\uff1a45gfg9\u3001Anston Sun

\u9996\u5148\uff0c\u8ba9\u6211\u4ecb\u7ecd\u4e00\u4e0b\u4e24\u4e2a\u60f9\u4eba\u559c\u7231\u7684\u5c0f\u5bb6\u4f19\u3002

int function(int arg)\n{\n    return 2 * arg;\n}\n

\u4e00\u822c\u901a\u8fc7\u51fd\u6570\uff0c\u7c7b\u578b\u662f int (int)\u3002

int (*func_ptr)(int);\n

\u829d\u58eb\u4ec0\u4e48\uff1f\u829d\u58eb\u51fd\u6570\u6307\u9488\uff0c\u7c7b\u578b\u662f int (*)(int)\u3002

\u90a3\u4e48\uff0c\u8fd9\u4e24\u4e2a\u5c0f\u5bb6\u4f19\u80fd\u5e72\u4ec0\u4e48\u5462\uff1f

func_ptr = &function;\nfunc_ptr = function;\n

\u524d\u8005\u662f\u4ec0\u4e48\uff1f\u6307\u9488\u3002\u6ca1\u9519\uff0c\u5e73\u5e73\u65e0\u5947\u7684\u53d6\u5730\u5740\u64cd\u4f5c\uff0c\u6d12\u6d12\u6c34\u5566\u3002 \u540e\u8005\u662f\u4ec0\u4e48\uff1f\u6211\u4eec\u77e5\u9053\u6307\u9488\u7684\u503c\u5b9e\u9645\u4e0a\u662f\u67d0\u5757\u5185\u5b58\u5730\u5740\uff0c\u4e0d\u8003\u8651\u5947\u6280\u6deb\u5de7\u7684\u8bdd\uff0c\u5c06\u6240\u6307\u5bf9\u8c61\u7684\u503c\u8d4b\u503c\u7ed9\u6307\u9488\u662f\u6ca1\u6709\u610f\u4e49\u7684\u3002\u4f46\u662f\uff0c\u5c06\u51fd\u6570\u6307\u4ee3\u5668 function \u8d4b\u503c\u7ed9\u51fd\u6570\u6307\u9488 func_ptr\uff0c\u5374\u6ca1\u6709\u4ea7\u751f\u4efb\u4f55\u95ee\u9898\u3002

\u574f\u4e86\uff0c\u81ea\u52a8\u64ad\u653e\u5988\u5988\u751f\u7684\uff0c\u5927\u8111\u8981\u6253\u9ad8\u7aef\u5c40\u4e86\u3002\u4e0d\u8fc7\u4f60\u5148\u522b\u6025\uff0c\u8fd9\u4e2a\u770b\u8d77\u6765\u4e0d\u77e5\u6240\u4e91\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u5176\u5b9e\u4e0e\u524d\u8005\u5b8c\u5168\u7b49\u6548\u3002C \u6807\u51c6\u662f\u4ec1\u6148\u7684\uff0c\u5b83\u4e0d\u5fcd\u5fc3\u770b\u5230\u88ab\u51fd\u6570\u7ed5\u6655\u7684\u521d\u5b66\u8005\u9762\u5bf9\u9519\u8bef\u7684\u89e3\u5f15\u7528\u4e0d\u77e5\u6240\u63aa\uff0c\u4e8e\u662f\u89c4\u5b9a\u4e86\u51fd\u6570\u5230\u6307\u9488\u7684\u9690\u5f0f\u8f6c\u6362\u3002

\u8fd9\u91cc function \u7ecf\u8fc7\u4e00\u6b21\u9690\u5f0f\u8f6c\u6362\u53d8\u6210 &function\u3002\u8fd9\u4e00\u6b65\u8f6c\u6362\u5e76\u4e0d\u6539\u53d8\u503c\uff0c\u800c\u7c7b\u578b\u4ece int (int) \u53d8\u6210 int (*)(int) \u4e86\u3002\u4e5f\u5c31\u662f\u5b9e\u9645\u4e0a\u5728\u7f16\u8bd1\u5668\u770b\u6765\uff0c\u7b2c\u4e8c\u884c\u5c31\u662f\u7b2c\u4e00\u884c\u3002

\u73b0\u5728\u4f60\u5df2\u7ecf\u5bf9\u51fd\u6570\u548c\u51fd\u6570\u6307\u9488\u6709\u4e86\u4e00\u5b9a\u4e86\u89e3\uff0c\u5c31\u8ba9\u6211\u4eec\u770b\u4e00\u770b\u4e0b\u9762\u8fd9\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u628a\u6211\u4eec\u5df2\u7ecf\u5b66\u5230\u7684\u77e5\u8bc6\u8fd0\u7528\u5230\u5b9e\u8df5\u4e2d\u5427\u3002

\u8bf7\u89e3\u91ca\u4ee5\u4e0b\u4ee3\u7801\u7684\u4f5c\u7528\uff1a

// \u8bd5\u8bd5\u770b\uff01\n(*(void(*)())0)();\n

\u597d\u5427\uff0c\u8fd9\u6837\u7684\u8868\u8fbe\u5f0f\u6216\u8bb8\u5bf9\u4f60\u6765\u8bf4\u4e3a\u65f6\u5c1a\u65e9\u3002\u6211\u4eec\u6362\u4e00\u4e2a\u7b80\u5355\u70b9\u7684\u4f8b\u5b50\u3002

function(20);\n(function)(20);\n(*&function)(20);\n(&function)(20);\n(*function)(20);\n(***********function)(20); // \u4e0d\u7528\u6570\u4e86\uff0c11 \u4e2a\n

\u5148\u4e0d\u7ba1\u7b2c\u516d\u4e2a\u662f\u4ec0\u4e48\u4e1c\u897f\u3002\u6211\u4eec\u770b\u770b\u524d\u4e94\u4e2a\u3002

\u7b2c\u4e00\u4e2a\u4e0d\u80fd\u518d\u719f\u6089\u4e86\uff0c\u4e00\u4e2a\u4eba\u755c\u65e0\u5bb3\u7684\u51fd\u6570\u8c03\u7528\u3002

\u7b2c\u4e8c\u4e2a\u770b\u7740\u548c\u7b2c\u4e00\u4e2a\u5dee\u4e0d\u591a\u2026\u2026\u6ca1\u9519\uff0c\u76f8\u4fe1\u81ea\u5df1\uff0c\u5b83\u4eec\u5b8c\u5168\u4e00\u6837\u3002

\u7b2c\u4e09\u4e2a\u5462\uff1f\u6ca1\u9519\uff0c\u53d6\u5730\u5740\u518d\u89e3\u5f15\u7528\uff0c\u9664\u4e86\u51fa\u9898\u6ca1\u6709\u7528\u3002\u8fde\u7f16\u8bd1\u5668\u90fd\u4f1a\u6beb\u4e0d\u72b9\u8c6b\u5730\u4f18\u5316\u6389\u3002

\u7b2c\u56db\u4e2a\u5f00\u59cb\u5947\u602a\u4e86\u8d77\u6765\u3002\u7f3a\u5931\u7684\u89e3\u5f15\u7528\u5e76\u975e\u7c97\u5fc3\u5927\u610f\uff0c\u5b83\u8c61\u5f81\u7740\u6211\u4eec\u73a9\u8f6c\u6307\u9488\u7684\u81ea\u4fe1\u4e0e\u60ec\u610f\uff0c\u4ee5\u53ca\u634d\u536b\u6307\u9488\u5730\u4f4d\u7684\u51b3\u5fc3\u3002\u9274\u4e8e C \u6807\u51c6\u5141\u8bb8\u901a\u8fc7\u51fd\u6570\u6307\u9488\u8c03\u7528\u51fd\u6570\uff0c\u7f16\u8bd1\u5668\u5bf9\u6b64\u4e5f\u6ca1\u4ec0\u4e48\u610f\u89c1\u3002

\u7b2c\u4e94\u4e2a\u6362\u4e86\u79cd\u6298\u78e8\u65b9\u5f0f\u3002\u806a\u660e\u5982\u4f60\u65e9\u5df2\u6599\u5230\u6700\u540e\u7684\u7ed3\u679c\u3002\u4f46\u662f\u4e3a\u4ec0\u4e48\uff1f\u5f15\u8a00\u5b9a\u771f\uff0c\u9274\u5b9a\u4e3a\u9690\u5f0f\u8f6c\u6362\u60ef\u7684\u3002\u56de\u5fc6\u4e00\u4e0b\u51fd\u6570\u5230\u6307\u9488\u7684\u9690\u5f0f\u8f6c\u6362\uff0c*function \u7b49\u6548\u4e8e *&function\uff0c\u8fd9\u4e0b\u770b\u61c2\u4e86\u3002

\u73b0\u5728\u7b2c\u516d\u4e2a\u4f60\u5e94\u8be5\u4e5f\u80fd\u7406\u89e3\u4e86\u3002\u6bcf\u6b21\u5c1d\u8bd5\u5bf9 function \u89e3\u5f15\u7528\uff0c\u90fd\u4f1a\u8feb\u4f7f\u7f16\u8bd1\u5668\u5c06\u5b83\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488\uff0c\u4ee5\u6ee1\u8db3\u4f60\u5bf9\u4ee3\u7801\u98ce\u683c\u7684\u5947\u602a\u7656\u597d\u3002

\u8fd8\u662f\u770b\u770b\u8fdc\u5904\u7684 func_ptr \u5427\u5bb6\u4eba\u4eec\u3002

(*func_ptr)(20);\nfunc_ptr(20);\n(****func_ptr)(20);\n(&func_ptr)(20);\n

\u7b2c\u4e00\u4e2a\uff0c\u7b80\u5355\u6613\u61c2\u7684\u6307\u9488\u89e3\u5f15\u7528\uff0c\u76f8\u5f53\u4e8e\u4e0a\u9762\u7684\u7b2c\u4e8c\u4e2a\u3002

\u7b2c\u4e8c\u4e2a\uff0c\u4eba\u755c\u65e0\u5bb3\u7684\u51fd\u6570\u6307\u9488\u8c03\u7528\u51fd\u6570\uff0c\u76f8\u5f53\u4e8e\u4e0a\u9762\u7684\u7b2c\u56db\u4e2a\u3002

\u7b2c\u4e09\u4e2a\uff0c\u51fd\u6570\u5230\u6307\u9488\u7684\u9690\u5f0f\u8f6c\u6362\u53d1\u751f\u4e86\u6574\u6574\u4e09\u56de\u554a\u4e09\u56de\uff0c\u7c7b\u4f3c\u4e0a\u9762\u7684\u7b2c\u516d\u4e2a\u3002

\u7b2c\u56db\u4e2a\uff0c\u7f16\u8bd1\u5668\u8ddf\u4f60\u7206\u4e86\u3002\u600e\u4e48\u4f1a\u662f\u5462\uff1f\u6211\u4eec\u4e0d\u59a8\u62c6\u5f00\u770b\u770b\uff1a

int (*func_ptr)(int) = &function;    // \u8fd9\u662f\u4e4b\u524d\u7684\nint (**second_ptr)(int) = &func_ptr; // \u8fd9\u662f\u6211\u4eec\u6b63\u5728\u505a\u7684\nsecond_ptr(20);                      // \u6211\u4eec\u60f3\u8fd9\u6837\n

\u5728\u8fd9\u91cc\uff0csecond_ptr \u5df2\u7ecf\u662f\u4e2a\u4e8c\u7ea7\u6307\u9488\u4e86\u3002\u51fd\u6570\u5230\u51fd\u6570\u6307\u9488\uff08\u5b83\u662f\u4e2a\u4e00\u7ea7\u6307\u9488\uff09\u7684\u53d8\u5316\uff0c\u5730\u5740\u503c\u662f\u4e0d\u4f1a\u6539\u53d8\u7684\uff0c\u5c31\u662f\u8fd9\u4e2a\u51fd\u6570\u7684\u53ef\u6267\u884c\u4ee3\u7801\u6240\u5728\u7684\u4f4d\u7f6e\u3002\u95ee\u9898\u5728\u4e8e\uff0c\u4e8c\u7ea7\u6307\u9488\u7684\u503c\u4e0d\u662f function \u7684\u5730\u5740\uff0c\u800c\u662f func_ptr \u8fd9\u4e2a\u53d8\u91cf\u7684\u5730\u5740\u3002\u8fd9\u8fd8\u5f97\u4e86\uff0c\u9a97\u81ea\u5df1\u53ef\u4ee5\uff0c\u9a97\u5144\u5f1f\u4e5f\u5c31\u7b97\u4e86\uff0c\u7f16\u8bd1\u5668\u53ef\u4e0d\u5403\u4f60\u8fd9\u5957\u3002

\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u518d\u770b\u70b9\u4e0d\u592a\u4e00\u6837\u7684\uff1a

int func_two(int a, int f(int arg))\n{\n    return 3 * f(a);\n}\n

\u8fd9\u662f\u4ec0\u4e48\uff1f\u51fd\u6570\uff0c\u8c03\u7528\u4e00\u4e0b\uff1a

// function \u5982\u4e0a\u6587\u5b9a\u4e49\nint function(int arg);\n\nint a = 1;\nint b = func_two(a, function);\n

\u76f8\u4fe1\u806a\u660e\u7684\u4f60\u5df2\u7ecf\u731c\u5230\u4e86\uff0cb \u7684\u503c\u5c31\u662f 6\u3002\u6865\u8c46\u9ebb\u888b\uff0c\u597d\u50cf\u6709\u54ea\u91cc\u4e0d\u592a\u5bf9\u52b2\u3002func_two \u7684\u4e24\u4e2a\u53c2\u6570\u7c7b\u578b\u5206\u522b\u662f int \u548c int (int)\uff0c\u4f46\u662f\u8c03\u7528\u65f6\u5374\u4f20\u5165\u4e86\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff08\u8fd8\u8bb0\u5f97\u9690\u5f0f\u8f6c\u6362\u5417\uff1f\uff09\uff0c\u8fd9\u5374\u6ca1\u6709\u4ea7\u751f\u4efb\u4f55\u95ee\u9898\u3002\u8fd9\u53c8\u662f\u4ec0\u4e48\u64cd\u4f5c\uff1f

\u53c8\u662f\u9690\u5f0f\u8f6c\u6362\uff1fBingo\uff01\u4e0d\u8fc7\u9700\u8981\u6ce8\u610f\u53d1\u751f\u9690\u5f0f\u8f6c\u6362\u7684\u4f4d\u7f6e\u3002func_two \u7684\u7b2c\u4e8c\u4e2a\u5f62\u53c2\u5b9e\u9645\u4e0a\u662f int (*)(int) \uff0c\u800c\u975e\u5b57\u9762\u4e0a\u7684 int (int)\u3002\u8fd9\u5c31\u548c void f(int a[]) \u5b9e\u9645\u4e0a\u5c31\u662f void f(int *a) \u4e00\u6837\uff0c\u540c\u6837\u662f\u51fa\u4e8e\u8282\u7ea6\u8d44\u6e90\u7684\u8003\u8651\u3002\u4e5f\u5c31\u662f\u8bf4\uff0c\u7f16\u8bd1\u5668\u773c\u4e2d\u7684 func_two \u662f int func_two(int a, int (*f)(int)\u3002\u641e\u6e05\u695a\u8fd9\u4e00\u70b9\uff0c\u5176\u4f59\u90e8\u5206\u4e5f\u5c31\u987a\u7406\u6210\u7ae0\u4e86\u3002

\u7ecf\u8fc7\u7ec3\u4e60\uff0c\u4f60\u5e94\u8be5\u5df2\u7ecf\u53ef\u4ee5\u770b\u51fa\uff0c\u4ece\u51fd\u6570\u5230\u6307\u9488\u7684\u9690\u5f0f\u8f6c\u6362\u89c4\u5b9a\u51fa\u53d1\uff0c\u7406\u89e3\u4e0a\u8ff0\u60c5\u666f\u5e76\u975e\u96be\u4e8b\u3002\u5bf9\u51fd\u6570\u6307\u9488\u7684\u754f\u60e7\uff0c\u5f80\u5f80\u662f\u56e0\u4e3a\u4e0d\u719f\u6089\u8f6c\u6362\u89c4\u5219\uff0c\u6216\u53d7\u590d\u6742\u7684\u58f0\u660e\u8bed\u6cd5\u5e72\u6270\u3002\u56e0\u6b64\uff0c\u63d0\u9ad8\u8bc6\u522b\u7c7b\u578b\u7684\u719f\u7ec3\u5ea6\uff0c\u8db3\u4ee5\u8ba9\u4f60\u81ea\u4fe1\u8fd0\u7528\u51fd\u6570\u6307\u9488\u3002

"},{"location":"programming/faq/#_5","title":"\u51fd\u6570\u5230\u6307\u9488\u8f6c\u6362","text":"

\u4efb\u4f55\u51fd\u6570\u6307\u4ee3\u5668\u8868\u8fbe\u5f0f\uff0c\u5728\u7528\u4e8e\u5f02\u4e8e\u4e0b\u5217\u8bed\u5883\u65f6

  • \u4f5c\u4e3a\u53d6\u5740\u8fd0\u7b97\u7b26\u7684\u64cd\u4f5c\u6570
  • \u4f5c\u4e3a sizeof \u7684\u64cd\u4f5c\u6570

\u4f1a\u7ecf\u5386\u5230\u6307\u5411\u8868\u8fbe\u5f0f\u6240\u6307\u4ee3\u51fd\u6570\u7684\u6307\u9488\u7684\u8f6c\u6362\u3002

"},{"location":"programming/faq/#_6","title":"\u56fe\u5f62\u5e93","text":"

\u7b80\u8981\u6574\u7406\u4e00\u4e0b libgraphics \u7528\u6cd5\uff1a

"},{"location":"programming/faq/#_7","title":"\u5fc5\u5907\u51fd\u6570","text":"

\u56fe\u5f62\u4e0e\u6587\u5b57

\u503c\u5f97\u6ce8\u610f\u7684\u4e00\u70b9\u662f\uff1alibgraphics \u7684\u5750\u6807\u7cfb\u7edf\u4e0e ACLLib \u4e0d\u540c\u3002\u524d\u8005\u4ee5\u5de6\u4e0b\u89d2\u4e3a\u539f\u70b9\uff0c\u7b26\u5408\u6211\u4eec\u5e38\u7528\u7684\u6570\u5b66\u8868\u8fbe\uff1b\u540e\u8005\u4ee5\u5de6\u4e0a\u89d2\u4e3a\u9876\u70b9\uff0c\u4f7f\u7528\u7a97\u53e3\u5750\u6807\u7cfb\u7edf\u3002

  • void InitGraphics(void)\uff1a\u4f7f\u7528\u56fe\u5f62\u5e93\u4e2d\u7684\u51fd\u6570\u524d\u8c03\u7528
  • void MovePen(double x, double y)\uff1a\u5c06\u7b14\u79fb\u52a8\u5230\u67d0\u70b9\uff08\u6ce8\u610f\u4e0d\u662f\u76f8\u5bf9\u79fb\u52a8\uff09
  • void DrawLine(double dx, double dy)\uff1a\u4ece\u5f53\u524d\u70b9 \\((x,y)\\) \u753b\u5230 \\((x+dx, y+dy)\\) \u7684\u7ebf\uff0c\u753b\u7b14\u968f\u4e4b\u79fb\u52a8
  • void DrawArc(double r, double start, double sweep)\uff1a\u4ee5\u5f53\u524d\u70b9\u4e3a\u5706\u5fc3\uff0c\u4ece \\(\\phi=start\\) \u89d2\u5f00\u59cb\uff0c\u753b\u534a\u5f84\u4e3a \\(r\\)\uff0c\u5706\u5fc3\u89d2\u4e3a \\(\\Delta\\phi=sweep\\) \u7684\u5706\u5f27\u3002
  • double GetWindowWidth(void)\uff1a\u83b7\u53d6\u7a97\u53e3\u5bbd\u5ea6
  • double GetWindowHeight(void)
  • double GetCurrentX(void)\uff1a\u83b7\u53d6\u5f53\u524d\u753b\u7b14\u7684\u4f4d\u7f6e
  • double GetCurrentY(void)
  • void DrawTextString(string text)\uff1a\u5728\u5f53\u524d\u4f4d\u7f6e\u6253\u5370\u5b57\u7b26\u4e32
  • double TextStringWidth(string text)\uff1a\u83b7\u53d6\u8be5\u5b57\u7b26\u4e32\u6253\u5370\u65f6\u7684\u5bbd\u5ea6

\u5173\u4e8e SetEraseMode() \u548c GetEraseMode() \u6211\u76f4\u63a5\u628a\u6ce8\u91ca\u8d34\u5728\u8fd9\u4e86\uff0c\u76f4\u63a5\u8bfb\u5427\uff1a

/*\n * Function: SetEraseMode\n * Usage: SetEraseMode(TRUE);\n *        SetEraseMode(FALSE);\n * ---------------------------\n * The SetEraseMode function sets the value of the internal\n * erasing flag.  Setting this flag is similar to setting the\n * color to \"White\" in its effect but does not affect the\n * current color setting.  When erase mode is set to FALSE,\n * normal drawing is restored, using the current color.\n */\n\nvoid SetEraseMode(bool mode);\n\n/*\n * Function: GetEraseMode\n * Usage: mode = GetEraseMode();\n * -----------------------------\n * This function returns the current state of the erase mode flag.\n */\n\nbool GetEraseMode(void);\n

\u8fd8\u662f\u9644\u4e2a\u7ffb\u8bd1\u5427\uff1aSetEraseMode \u51fd\u6570\u8bbe\u7f6e\u5185\u90e8\u64e6\u9664\u6807\u5fd7\u7684\u503c\u3002\u8bbe\u7f6e\u8fd9\u4e2a\u503c\u7684\u6548\u679c\u5c31\u50cf\u628a\u989c\u8272\u8bbe\u7f6e\u4e3a\u201c\u767d\u8272\u201d\uff0c\u4f46\u4e0d\u4f1a\u5f71\u54cd\u5f53\u524d\u7684\u989c\u8272\u8bbe\u7f6e\u3002\u5f53\u64e6\u9664\u6a21\u5f0f\u8bbe\u7f6e\u4e3a FALSE \u65f6\uff0c\u6062\u590d\u5230\u6b63\u5e38\u7684\u7ed8\u753b\u72b6\u6001\uff0c\u4f7f\u7528\u5f53\u524d\u7684\u989c\u8272\u3002

\u63a7\u5236\u53f0\u4ea4\u4e92\uff1a\u8fd9\u4e9b\u6e90\u4ee3\u7801\u5728 simpio.h \u4e2d

  • void InitConsole(void)\uff1a\u6253\u5f00\u4e00\u4e2a\u65b0\u7684\u63a7\u5236\u53f0\uff0c\u8981\u4f7f\u7528 stdio.h \u4e2d\u7684\u6807\u51c6\u8f93\u5165\u8f93\u51fa\u51fd\u6570\u524d\u8bb0\u5f97\u5199\u4e0a\u8fd9\u4e2a\u3002

  • int GetInteger(void)\uff1a\u4ece\u6807\u51c6\u8f93\u5165\u4e2d\u8bfb\u5165\u4e00\u884c\uff0c\u5e76\u5c1d\u8bd5\u8bfb\u53d6\u4e00\u4e2a\u6574\u6570\u3002\u5982\u679c\u9047\u5230\u610f\u5916\u60c5\u51b5\uff0c\u4f1a\u8981\u6c42\u7528\u6237\u91cd\u65b0\u8f93\u5165\u3002\u6e90\u7801\u5982\u4e0b\uff1a

    int GetInteger(void)\n{\n    string line;\n    int value;\n    char termch;\n\n    while (TRUE) {\n        line = GetLine();\n        if (line == NULL) Error(\"GetInteger: unexpected end of file\");\n        switch (sscanf(line, \" %d %c\", &value, &termch)) {\n          case 1:\n            FreeBlock(line);\n            return (value);\n          case 2:\n            printf(\"Unexpected character: '%c'\\n\", termch);\n            break;\n          default:\n            printf(\"Please enter an integer\\n\");\n            break;\n        }\n        FreeBlock(line);\n        printf(\"Retry: \");\n    }\n}\n
  • double GetReal(void)\uff1a\u8bfb\u53d6\u4e00\u4e2a\u5b9e\u6570\uff0c\u5177\u4f53\u540c\u4e0a\u3002

  • string GetLine(void)

  • string ReadLine(FILE *infile)\uff1a\u4ece\u6307\u5b9a\u7684\u6587\u4ef6\u4e2d\u8bfb\u5165\u4e00\u884c\u3002

"},{"location":"programming/faq/#_8","title":"\u5b9a\u65f6\u542f\u52a8\u2014\u2014\u8ba1\u65f6\u5668\u56de\u8c03","text":"

\u8ba1\u65f6\u5668\u7528\u4e8e\u5ef6\u65f6\u6216\u91cd\u590d\u6267\u884c\u540c\u7c7b\u4efb\u52a1\u3002\u76f8\u6bd4\u949f\u8868\u7b49\u7eaf\u7cb9\u7684\u8ba1\u65f6\u5de5\u5177\uff0c\u8ba1\u65f6\u5668\u66f4\u63a5\u8fd1\u4e8e\u65e5\u7a0b\u5b89\u6392\u3002\u8ba1\u65f6\u5668\u7684\u6838\u5fc3\u529f\u80fd\u5982\u4e0b\uff1a\u6bcf\u7ecf\u8fc7\u9884\u5148\u8bbe\u5b9a\u7684\u65f6\u957f\uff0c\u8ba1\u65f6\u5668\u4fbf\u4f1a\u901a\u8fc7\u67d0\u79cd\u673a\u5236\uff0c\u6267\u884c\u7279\u5b9a\u7684\u6307\u4ee4\u3002

libgraphics \u5e93\u901a\u8fc7\u4e8b\u4ef6\u56de\u8c03\u673a\u5236\u5b9e\u73b0\u5b9a\u65f6\u89e6\u53d1\u7684\u529f\u80fd\u3002\u56de\u8c03\u673a\u5236\u6b64\u5904\u4e0d\u518d\u8d58\u8ff0\u3002

"},{"location":"programming/faq/#_9","title":"\u8ba1\u65f6\u5668","text":"

\u4e0e\u8ba1\u65f6\u5668\u76f8\u5173\u7684\u51fd\u6570\u5982\u4e0b\uff1a

  • void startTimer(int timerID, int interval)
  • void cancelTimer(int timerID)

\u987e\u540d\u601d\u4e49\uff0c\u4e24\u4e2a\u51fd\u6570\u5206\u522b\u7528\u4e8e\u542f\u52a8\u4e0e\u7ec8\u6b62\u5b9a\u65f6\u5668\u3002interval \u662f\u9884\u5148\u8bbe\u5b9a\u7684\u65f6\u957f\uff0c\u5373\u6bcf\u4e24\u6b21\u89e6\u53d1\u7684\u65f6\u95f4\u95f4\u9694\u3002timerID \u4e3a\u8ba1\u65f6\u5668\u7684\u6807\u8bc6\u7b26\uff0c\u53ef\u7406\u89e3\u4e3a\u8ba1\u65f6\u5668\u7684\u4e13\u7528\u540d\u79f0\u3002

\u4e3a\u4e86\u5b8c\u6210\u591a\u9879\u5b9a\u65f6\u4efb\u52a1\uff0c\u5f80\u5f80\u9700\u8981\u5206\u522b\u542f\u52a8\u591a\u4e2a\u95f4\u9694\u4e0d\u540c\u7684\u5b9a\u65f6\u5668\u3002\u7531\u4e8e\u6240\u6709\u8ba1\u65f6\u5668\u5747\u4f1a\u89e6\u53d1 TimerEvent\uff0c\u5728\u56de\u8c03\u51fd\u6570\u5185\u9700\u8981\u4f7f\u7528 timerID \u533a\u5206\u4e0d\u540c\u7684\u5b9a\u65f6\u5668\u3002

"},{"location":"programming/faq/#_10","title":"\u56de\u8c03\u6ce8\u518c\u51fd\u6570","text":"
  • void registerTimerEvent(TimerEventCallback)\uff1a\u6ce8\u518c\u8ba1\u65f6\u5668\u4e8b\u4ef6\u3002 TimerEventCallback \u7c7b\u578b\u89c1\u4e0b\u3002
"},{"location":"programming/faq/#_11","title":"\u56de\u8c03\u51fd\u6570","text":"
  • typedef void (*TimerEventCallback)(int timerID)

TimerEventCallback \u662f\u4e00\u4e2a\u51fd\u6570\u6307\u9488\u7c7b\u578b\uff0c\u8be5\u7c7b\u578b\u53d8\u91cf\u6307\u5411\u51fd\u6570\uff08\u5047\u8bbe\u540d\u79f0\u4e3a func\uff09\u7684\u7c7b\u578b\u4e3a void func(int timerID)\u3002\u901a\u8fc7\u56de\u8c03\u673a\u5236\uff0c\u6bcf\u5f53\u4efb\u4e00\u8ba1\u65f6\u5668\u5230\u8fbe\u8bbe\u5b9a\u65f6\u95f4\u65f6\uff0c\u5747\u4f1a\u901a\u8fc7\u8be5\u7c7b\u578b\u51fd\u6570\u6307\u9488\u8c03\u7528 func \u51fd\u6570\u3002\u901a\u8fc7\u4f20\u5165\u7684 timerID\uff0c\u56de\u8c03\u51fd\u6570\u5185\u53ef\u4ee5\u533a\u5206\u4e0d\u540c\u8ba1\u65f6\u5668\u7684\u89e6\u53d1\u4e8b\u4ef6\uff0c\u5e76\u6267\u884c\u7279\u5b9a\u64cd\u4f5c\u3002

"},{"location":"programming/faq/#_12","title":"\u8865\u5145\u601d\u8003","text":"

\u4ee5\u4e0a\u4ecb\u7ecd\u5747\u96c6\u4e2d\u4e8e\u91cd\u590d\u6267\u884c\uff0c\u4f46\u662f\u524d\u9762\u63d0\u5230\u8ba1\u65f6\u5668\u4e5f\u53ef\u7528\u4e8e\u5ef6\u65f6\u6267\u884c\uff0c\u5373\u5728\u9884\u5148\u8bbe\u5b9a\u7684\u65f6\u957f\u540e\u6267\u884c\u7279\u5b9a\u6b21\u6570\u7684\u7279\u5b9a\u64cd\u4f5c\u3002\u7ed3\u5408 cancelTimer \u51fd\u6570\uff0c\u60f3\u60f3\u600e\u6837\u5b9e\u73b0\u8fd9\u4e00\u76ee\u6807\u3002

"},{"location":"programming/faq/#_13","title":"\u56de\u8c03\u51fd\u6570","text":"
typedef void (*KeyboardEventCallback) (int key,int event);\ntypedef void (*CharEventCallback) (char c);\ntypedef void (*MouseEventCallback) (int x, int y, int button, int event);\ntypedef void (*TimerEventCallback) (int timerID);\n\nvoid registerKeyboardEvent(KeyboardEventCallback callback);\nvoid registerCharEvent(CharEventCallback callback);\nvoid registerMouseEvent(MouseEventCallback callback);\nvoid registerTimerEvent(TimerEventCallback callback);\nvoid startTimer(int id,int timeinterval);\n

\u56e0\u4e3a\u8fd9\u4e9b\u56de\u8c03\u51fd\u6570\u5728 graphics \u5e93\u4e2d\u90fd\u6ca1\u6709\u6ce8\u91ca\uff0c\u6211\u5c31\u4e0d\u4f5c\u89e3\u91ca\u4e86\uff0c\u8bfe\u4e0a\u90fd\u8bb2\u8fc7\u56de\u8c03\u51fd\u6570\u600e\u4e48\u7528\u3002

  • \u8ba1\u65f6\u5668\uff1a\u4ee5 20 \u5e74\u7a0b\u5e8f\u586b\u7a7a\u7b2c 3 \u9898\u4e3a\u4f8b\uff1a

    void Main()\n{\n    InitGraphics();\n    registerTimerEvent(TimerEventProcess);\n    //...\n    startTimer(TIMER_CURSOR, 500);/*start 500ms cursor blinking timer*/\n}\nvoid TimerEventProcess(int timerID)\n{\n    bool erasemode;\n    if(TIMER_CURSOR == timerID)\n    {\n        //...\n    }\n}\n

    \u4ece\u8fd9\u6bb5\u4f8b\u7a0b\u4e2d\u53ef\u4ee5\u4e86\u89e3\u5230\u51e0\u4e2a\u91cd\u8981\u7684\u70b9\uff1a

    • \u4f7f\u7528 void registerTimerEvent(TimerEventCallback callback) \u6ce8\u518c\u56de\u8c03\u51fd\u6570 callback \u540e\uff0c\u8fd8\u9700\u8981\u7528 void startTimer(int id,int timeinterval) \u8bbe\u5b9a\u5e76\u542f\u52a8\u4e00\u4e2a\u8ba1\u65f6\u5668\uff0c\u8bbe\u5b9a\u8fd9\u4e2a\u8ba1\u65f6\u5668\u7684 id \u548c timeinterval\u3002
    • \u6bcf\u5f53\u8ba1\u65f6\u5668\u5230\u8fbe\u6307\u5b9a\u65f6\u95f4\u540e\uff0c\u8ba1\u65f6\u5668\u5c31\u4f1a\u8c03\u7528\u6240\u6709\u7684\u56de\u8c03\u51fd\u6570\uff0c\u56de\u8c03\u51fd\u6570\u4f1a\u63a5\u6536\u8fd9\u4e2a\u8ba1\u65f6\u5668\u7684 id \u5e76\u68c0\u67e5\u662f\u4e0d\u662f\u81ea\u5df1\u9700\u8981\u8fdb\u884c\u52a8\u4f5c\u7684\u90a3\u4e2a\u8ba1\u65f6\u5668\u3002\u8fd9\u5c31\u662f TimerEventProcess \u51fd\u6570\u4e2d if \u8bed\u53e5\u7684\u4f5c\u7528\u3002
"},{"location":"programming/faq/#_14","title":"\u4f7f\u7528\u65b9\u6cd5","text":"
  • \u4e3b\u51fd\u6570\u662f void Main() \u522b\u5199\u9519\u4e86
  • \u4e0b\u9762\u662f\u4e00\u4e2a\u6700\u7b80\u5355\u7684\u4f8b\u7a0b\uff1a
#include <stdio.h>\n#include \"graphics.h\"\n\nvoid Main(void)\n{\n    InitGraphics();\n    MovePen(1.5, 1.0);\n    DrawArc(0.5, 0, 360);\n}\n
"},{"location":"programming/faq/#new","title":"New() \u51fd\u6570","text":"

\u5411\u4e0b\u7ffb\uff0c\u627e\u5230 2019 \u5e74\u7a0b\u5e8f\u586b\u7a7a\u7b2c 3 \u9898\uff0c\u4f7f\u7528\u65b9\u6cd5\u5728\u90a3\u91cc\u3002

"},{"location":"programming/faq/#_15","title":"\u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790","text":"
  • \u8bb0\u4f4f\uff1a\u6392\u5e8f\u7b97\u6cd5\u7684\u65f6\u95f4\u590d\u6742\u5ea6\u4e0e\u4e24\u9879\u64cd\u4f5c\u7684\u6b21\u6570\u6709\u5173\uff1a\u6bd4\u8f83\u548c\u4ea4\u6362\u3002

    • \u4f60\u53ef\u4ee5\u8fd9\u6837\u60f3\uff1a\u521b\u5efa\u4e00\u4e2a\u5168\u5c40\u53d8\u91cf\u4f5c\u4e3a\u8ba1\u6570\u5668\uff0c\u5728\u6240\u6709\u6d89\u53ca\u6bd4\u8f83\u548c\u4ea4\u6362\u7684\u5730\u65b9\u8ba9\u5b83 ++\uff0c\u8fd0\u884c\u5b8c\u7684\u7ed3\u679c\u5c31\u662f\u5176\u65f6\u95f4\u590d\u6742\u5ea6\u3002\u6bd4\u5982\uff1a

      int count = 0;\nfor (int i = 0; i < n; ++i) {\n  for (int j = 0; j < n; ++j) {\n    for (int k = 0; k < m; ++k) {\n        count++;\n    }\n  }\n}\n

      \u8fd0\u884c\u5b8c\u8fd9\u6bb5\u4ee3\u7801\uff0ccount = n*n*m\uff0c\u5219\u5176\u65f6\u95f4\u590d\u6742\u5ea6\u4e3a \\(O(n^2m)\\)\u3002

  • \u8bb0\u4f4f\u5e76\u7406\u89e3\u4e00\u4e9b\u5e38\u89c1\u7684\u7b97\u6cd5\u7684\u5e73\u5747\u65f6\u95f4\u590d\u6742\u5ea6\u3001\u6700\u4f18\u3001\u6700\u5dee\u60c5\u51b5\u590d\u6742\u5ea6\uff1a

    \u6765\u6e90\uff1a\u5e38\u7528\u6392\u5e8f\u7b97\u6cd5\u603b\u7ed3\u5bf9\u6bd4 | \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 \u7cfb\u5217\u6559\u7a0b\uff08\u7b14\u8bb0\uff09 (zq99299.github.io)

"},{"location":"programming/faq/#_16","title":"\u540e\u7f00\u8868\u8fbe\u5f0f","text":"

\u8fd9\u4e1c\u897f\u524d\u4e24\u4e09\u5e74\u90fd\u8003\u4e86\uff0c\u9700\u8981\u4e86\u89e3\u4e00\u4e0b\u3002\u5173\u4e8e\u8868\u8fbe\u5f0f\u6811\u7684\u76f8\u5173\u5185\u5bb9\u8bf7\u53c2\u89c1\uff1a

  • \u8868\u8fbe\u5f0f\u6c42\u503c - OI Wiki (oi-wiki.org)
  • \u6811\u57fa\u7840 - OI Wiki (oi-wiki.org)

\u5728\u524d\u7f00\u3001\u4e2d\u7f00\u3001\u540e\u7f00\u8868\u8fbe\u5f0f\u4e4b\u95f4\u8fdb\u884c\u8f6c\u6362\u7684\u6700\u597d\u65b9\u6cd5\u662f\u5c06\u5176\u60f3\u8c61\u6210\u4e00\u4e2a\u6811\u72b6\u7ed3\u6784\u3002

  • \u4e2d\u7f00\u8868\u8fbe\u5f0f\uff1a\u5bf9\u8fd9\u68f5\u6811\u8fdb\u884c\u4e2d\u5e8f\u904d\u5386\uff0c\u5373\u5de6\u3001\u6839\u3001\u53f3
    • a+b*(c-d)-(e/f)
  • \u524d\u7f00\u8868\u8fbe\u5f0f\uff1a\u5bf9\u8fd9\u68f5\u6811\u8fdb\u884c\u5148\u5e8f\u904d\u5386\uff0c\u5373\u6839\u3001\u5de6\u3001\u53f3
    • -+a*b-cd/ef
  • \u540e\u7f00\u8868\u8fbe\u5f0f\uff1a\u5bf9\u8fd9\u68f5\u6811\u8fdb\u884c\u540e\u5e8f\u904d\u5386\uff0c\u5373\u5de6\u3001\u53f3\u3001\u6839\u3002\u6ce8\u610f\u5230\u5de6\u53f3\u5b50\u8282\u70b9\u90fd\u6bd4\u6839\u5148\u904d\u5386\uff0c\u6240\u4ee5\u53ef\u4ee5\u4e00\u8def\u5f80\u4e0b\u627e\u5230\u6700\u6df1\u7684\u5b50\u8282\u70b9\uff0c\u7136\u540e\u5411\u4e0a\u89e3\u6790\u3002
    • abcd-*+ef/-

\u503c\u5f97\u4e00\u63d0\u7684\u662f\u540e\u7f00\u8868\u8fbe\u5f0f\u5177\u6709\u51e0\u4e2a\u65b9\u4fbf\u7684\u6027\u8d28\uff1a

  • \u8ba1\u7b97\u540e\u7f00\u8868\u8fbe\u5f0f\uff0c\u53ea\u9700\u8981\u7ef4\u62a4\u4e00\u4e2a\u6570\u5b57\u6808\uff0c\u6bcf\u6b21\u9047\u5230\u4e00\u4e2a\u8fd0\u7b97\u7b26\uff0c\u5c31\u53d6\u51fa\u4e24\u4e2a\u6808\u9876\u5143\u7d20\uff0c\u5c06\u8fd0\u7b97\u7ed3\u679c\u91cd\u65b0\u538b\u5165\u6808\u4e2d\u3002
  • \u540e\u7f00\u8868\u8fbe\u5f0f\u4e0e\u8868\u8fbe\u5f0f\u6811\u4e00\u4e00\u5bf9\u5e94\u3002\u540e\u7f00\u8868\u8fbe\u5f0f\u4e0d\u9700\u8981\u62ec\u53f7\u8868\u793a\uff0c\u5b83\u7684\u8fd0\u7b97\u987a\u5e8f\u662f\u552f\u4e00\u786e\u5b9a\u7684\u3002
"},{"location":"programming/exam/","title":"\u5386\u5e74\u5377\u6574\u7406","text":""},{"location":"programming/exam/#_2","title":"\u7a0b\u5e8f\u8bbe\u8ba1\u4e0e\u7b97\u6cd5\u57fa\u7840","text":"

\u6682\u65e0

"},{"location":"programming/exam/#_3","title":"\u7a0b\u5e8f\u8bbe\u8ba1\u57fa\u7840\u4e0e\u5b9e\u9a8c","text":"

\u6682\u65e0

"},{"location":"programming/exam/#2013-20182020","title":"\u3010\u5df2\u505c\u5f00\u3011\u7a0b\u5e8f\u8bbe\u8ba1\u57fa\u7840\uff082013-2018+2020\uff09","text":"

\u8be5\u8bfe\u7a0b\u5df2\u4e8e 2022-2023 \u5b66\u5e74\u505c\u5f00\uff0c\u7ecf\u5178\u9898\u76ee\u89e3\u6790\u89c1C \u5927\u7ecf\u5178\u9898\u76ee\u89e3\u6790

\u5e74\u4efd \u8bd5\u5377 \u7b54\u6848 2013 \u8bd5\u5377 \u7b54\u6848 2014 \u8bd5\u5377 \u7b54\u6848 2015 \u8bd5\u5377 \u7b54\u6848 2016 \u8bd5\u5377 \u7b54\u6848 2017 \u8bd5\u5377 \u7b54\u6848 2018 \u8bd5\u5377 \u7b54\u6848 2020 \u6a21\u62df\u5377 1 \u53ca\u7b54\u6848 \u6a21\u62df\u5377 2 \u53ca\u7b54\u6848 \u6a21\u62df\u5377 3 \u53ca\u7b54\u6848"},{"location":"programming/exam/#c-2013-2019","title":"\u3010\u5df2\u505c\u5f00\u3011C \u7a0b\u5e8f\u8bbe\u8ba1\u4e13\u9898\uff082013-2019\uff09","text":"

\u8be5\u8bfe\u7a0b\u5df2\u4e8e 2022-2023 \u5b66\u5e74\u505c\u5f00\uff0c\u7ecf\u5178\u9898\u76ee\u89e3\u6790\u89c1C \u5c0f\u7ecf\u5178\u9898\u76ee\u89e3\u6790

\u5e74\u4efd \u8bd5\u5377 \u7b54\u6848 2013 \u8bd5\u5377 \u7b54\u6848 2014 \u8bd5\u5377 \u7b54\u6848 2015 \u8bd5\u5377 \u7b54\u6848 2016 \u8bd5\u5377 \u7b54\u6848 2017 \u8bd5\u5377 \u7b54\u6848 2018 \u8bd5\u5377 \u7b54\u6848 2019 \u8bd5\u5377 \u7b54\u6848"},{"location":"programming/exam/lectures_on_c_programming/","title":"C \u7a0b\u5e8f\u8bbe\u8ba1\u4e13\u9898 \u5386\u5e74\u5377\u7ecf\u5178\u9898\u76ee\u89e3\u6790","text":"

\u9875\u9762\u6b63\u5728\u65bd\u5de5\u4e2d

"},{"location":"programming/exam/lectures_on_c_programming/#2020-2021","title":"2020-2021 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 1 typedef

\u6ce8\u610f\u8fd9\u91cc\u7684 typedef struct{char * name;} *T; \u628a T \u5b9a\u4e49\u4e3a struct{char * name;}*; \u7684\u522b\u540d\u3002\u4e0b\u4e00\u4e2a\u8bed\u53e5\u5373\u58f0\u660e\u53d8\u91cf t \u4e3a\u8be5\u7c7b\u578b\u3002

  • A\uff1achar *
  • B\uff1a\u8be5\u8868\u8fbe\u5f0f\u5b9e\u9645\u4e3a &(t->name[0])\uff0c\u5373 char * \u7c7b\u578b\u3002
  • C\uff1achar *
  • D\uff1a*(t.name) \u662f\u4e00\u4e2a\u9519\u8bef\u7684\u7528\u6cd5\uff0c\u4e0d\u80fd\u76f4\u63a5\u5bf9\u7ed3\u6784\u7684\u6307\u9488\u4f7f\u7528 . \u8fd0\u7b97\u7b26\u8bbf\u95ee\u5176\u6210\u5458\u3002
  • \u9009\u62e9\u9898 3 \u6307\u9488\u7c7b\u578b

\u51fd\u6570\u540d\u3001\u6570\u7ec4\u540d\u90fd\u4e0d\u662f\u6307\u9488\u54e6\uff0c\u867d\u7136\u5b83\u4eec\u5e38\u5e38\u9000\u5316\u6210\u6307\u9488\u3002

  • A\uff1ap \u662f\u51fd\u6570\u540d
  • B\uff1ap \u662f\u51fd\u6570\u540d
  • C\uff1ap \u662f\u6307\u5411 int[5] \u7684\u6307\u9488
  • D\uff1ap \u662f\u4e00\u4e2a\u6570\u7ec4
  • \u9009\u62e9\u9898 4 \u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26

C \u8bed\u8a00\u4e2d\u4e00\u5171\u6709 5 \u4e2a\u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26\uff0c\u8bf7\u56de\u5fc6\u5b83\u4eec\u7684\u4f5c\u7528\uff1a

  • auto\uff1a\u9ed8\u8ba4\u7684\u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26\uff0c\u7528\u4e8e\u5c40\u90e8\u53d8\u91cf\uff0c\u8868\u793a\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u4e0e\u51fd\u6570\u8c03\u7528\u76f8\u540c\u3002
  • register\uff1a\u7528\u4e8e\u5c40\u90e8\u53d8\u91cf\uff0c\u8868\u793a\u53d8\u91cf\u53ef\u80fd\u5b58\u50a8\u5728 CPU \u5bc4\u5b58\u5668\u4e2d\uff0c\u4ee5\u52a0\u5feb\u8bbf\u95ee\u901f\u5ea6\u3002
  • extern\uff1a\u7528\u4e8e\u5168\u5c40\u53d8\u91cf\uff0c\u8868\u793a\u53d8\u91cf\u5728\u5176\u4ed6\u6587\u4ef6\u4e2d\u5b9a\u4e49\u3002
  • static\uff1a

    • \u7528\u4e8e\u5c40\u90e8\u53d8\u91cf\uff0c\u8868\u793a\u53d8\u91cf\u7684\u751f\u547d\u5468\u671f\u4e0e\u7a0b\u5e8f\u8fd0\u884c\u76f8\u540c\u3002
    • \u7528\u4e8e\u5168\u5c40\u53d8\u91cf\uff0c\u8868\u793a\u53d8\u91cf\u7684\u4f5c\u7528\u57df\u4ec5\u9650\u4e8e\u5f53\u524d\u6587\u4ef6\u3002
  • _Thread_local\uff1a\u4e0d\u4f5c\u8981\u6c42\u3002

\u5176\u5b9e typedef \u6309\u8bed\u6cd5\u529f\u80fd\u4e5f\u88ab\u5206\u5728\u8fd9\u4e00\u7c7b\uff0c\u6211\u4eec\u4e0d\u7ba1\u5b83\u3002

\u5728\u4efb\u4f55\u58f0\u660e\u4e2d\uff0c\u53ea\u80fd\u540c\u65f6\u5b58\u5728\u6700\u591a\u4e00\u4e2a\u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26\u3002\u8fd9\u4e0e const\u3001volatile\u3001restrict \u7b49\u7c7b\u578b\u9650\u5b9a\u7b26\u4e0d\u540c\uff0c\u5b83\u4eec\u53ef\u4ee5\u540c\u65f6\u5b58\u5728\u3002

  • \u9009\u62e9\u9898 5 \u51fd\u6570\u6307\u9488

\u89c1 2019 \u5e74\u9009\u62e9\u9898 6

  • \u9009\u62e9\u9898 8 \u6570\u636e\u7ed3\u6784\u7684\u4f7f\u7528

\u8fd9\u79cd\u9898\u901a\u7528\u7684\u65b9\u6cd5\u5c31\u662f\u6bcf\u4e2a\u9009\u9879\u5c1d\u8bd5\u4e00\u904d\u3002\u53ea\u8981\u5bf9\u6808\u3001\u961f\u5217\u64cd\u4f5c\u719f\u6089\u7684\u8bdd\uff0c\u4e00\u4e2a\u4e2a\u8bd5\u5f88\u5feb\u5c31\u51fa\u6765\u4e86\u3002

  • \u7b80\u7b54\u9898 1.1 \u540e\u7f00\u8868\u8fbe\u5f0f

\u5982\u679c\u4f60\u7684\u7b54\u6848\u548c\u53c2\u8003\u7b54\u6848\u4e0d\u4e00\u6837\uff0c\u4e5f\u662f\u6709\u5bf9\u7684\u53ef\u80fd\u7684\uff0c\u5c31\u50cf\u4e2d\u7f00\u8868\u8fbe\u5f0f\u90a3\u6837\uff0c\u4e8c\u5143\u8fd0\u7b97\u7b26\u7684\u64cd\u4f5c\u6570\u662f\u53ef\u4ee5\u6362\u5e8f\u7684\uff08

\u6ce8\u610f\u8fd9\u9053\u9898\u4e2d\u7684 ^ \u8fd0\u7b97\u7b26\u7684\u53f3\u7ed3\u5408\u95ee\u9898\uff0c\u52a0\u4e0a\u62ec\u53f7\u540e\u53d8\u6210 d^(e^f) \u800c\u4e0d\u662f (d^e)^f\uff0c\u8f6c\u6362\u6210\u540e\u7f00\u8868\u8fbe\u5f0f\u53ea\u80fd\u662f def^^\uff0c\u800c fed^^ \u4e4b\u7c7b\u7684\u5168\u662f\u9519\u7684\u3002

  • \u7b80\u7b54\u9898 5 \u6392\u5e8f\u7b97\u6cd5\u6700\u4f18\u60c5\u51b5

\u89c1\u5e38\u89c1\u95ee\u9898-\u7b97\u6cd5\u590d\u6742\u5ea6

\u5f15\u7528\u4e00\u4e0b ztgg \u7684\u89e3\u91ca\uff1a

  • \u5e73\u5747\u60c5\u51b5\u4e0b\uff0c\u63d2\u5165\u5143\u7d20\u5bfc\u81f4\u7684\u79fb\u52a8\u4f9d\u65e7\u662f \\(O(n)\\) \u7684\uff0c\u5e76\u6ca1\u6709\u4f18\u5316\uff0c\u6240\u4ee5\u603b\u590d\u6742\u5ea6\u8fd8\u662f \\(O(n^2)\\)\u3002\uff08\u6279\u6ce8\uff1a\u4ea4\u6362\u7684\u590d\u6742\u5ea6\u4e3a \\(O(n^2)\\)\uff0c\u6bd4\u8f83\u7684\u590d\u6742\u5ea6\u4e3a \\(O(n\\log n)\\)\uff0c\u524d\u8005\u8f83\u5927\uff0c\u5360\u636e\u4e3b\u5bfc\u5730\u4f4d\uff09\u3002
  • \u6700\u4f73\u60c5\u51b5\u5e94\u8be5\u662f\u63d2\u5165\u5143\u7d20\u65f6\uff0c\u4e0d\u9700\u8981\u79fb\u52a8\u539f\u6765\u7684\u5143\u7d20\uff0c\u4e5f\u5c31\u662f\u6570\u7ec4\u5df2\u7ecf\u6392\u597d\u5e8f\u4e86\u3002\u8fd9\u4e2a\u60c5\u51b5\u4e0b\uff0c\u6bcf\u6b21\u63d2\u5165\u53ea\u6709\u4e8c\u5206\u67e5\u627e\u7684\u4ee3\u4ef7\uff0c\u5373\u4e3a \\(O(n\\log n)\\)\u3002
  • \u7b80\u7b54\u9898 6 \u961f\u5217\u64cd\u4f5c

\u5982\u679c\u7b2c\u4e00\u4e2a while \u5faa\u73af\u8bfb\u4e0d\u61c2\u4e00\u5b9a\u8981\u627e\u540c\u5b66/\u8001\u5e08\u95ee\u6e05\u695a\u634f\uff0c\u961f\u5217\u7684\u4f7f\u7528\u662f\u5f88\u57fa\u672c\u7684\u3002\u8bf7\u601d\u8003\u8fd9\u4e2a while \u5faa\u73af\u4e3a\u4ec0\u4e48\u9700\u8981\u9010\u4e2a malloc() \u5462\uff1f

\u4e2d\u95f4\u90a3\u4e2a while \u5faa\u73af\u6709\u70b9\u8ff7\u60d1\u3002\u5b83\u5176\u5b9e\u53ea\u662f\u5728\u5c06 eQueue \u4e2d\u7684\u6bcf\u4e2a\u5143\u7d20\u653e\u5230 dQueue \u65f6\u540c\u65f6\u628a\u540e\u9762\u4e00\u4e2a\u5143\u7d20\u6362\u5230\u961f\u5c3e\u53bb\u3002\u7406\u89e3\u5230\u8fd9\u91cc\u5c31\u80fd\u505a\u5bf9\u5566\u3002

  • \u7a0b\u5e8f\u586b\u7a7a 3

\u8fd9\u51e0\u4e2a\u7a7a\u90fd\u9700\u8981\u82b1\u4e00\u4f1a\u513f\u65f6\u95f4\u6765\u63a8\u65ad\u7684\uff1a

  • InitGraphics() \u4e00\u5b9a\u8981\u8bb0\u5f97
  • \u8bb0\u4f4f\u51e0\u79cd\u56de\u8c03\u51fd\u6570\u7684\u4f7f\u7528\u65b9\u6cd5\uff0cvoid registerTimerEvent(TimerEventCallback callback) \u4e0e void startTimer(int id,int timeinterval) \u914d\u5bf9\u4f7f\u7528\uff0c\u5b83\u4eec\u5404\u81ea\u7684\u53c2\u6570\u610f\u4e49\u3002
  • \u8ba1\u65f6\u5668\u56de\u8c03\u51fd\u6570\u600e\u4e48\u5199\uff1f\u53c2\u6570 timerID \u662f\u7528\u6765\u505a\u4ec0\u4e48\u7684\uff1f
  • \u7b2c 14 \u7a7a\u53ef\u80fd\u4e0d\u5bb9\u6613\u60f3\u5230\uff0c\u53cd\u6b63\u8bb0\u4f4f\u5728\u6bcf\u6b21\u753b\u70b9\u4ec0\u4e48\u4e1c\u897f\u4e4b\u524d\uff0c\u90fd\u8981\u68c0\u67e5\u753b\u7b14\u4f4d\u7f6e\u662f\u5426\u6b63\u786e\uff0c\u8fd9\u5728\u7ed8\u5236\u5206\u5f62\u56fe\u5f62\u65f6\u4e5f\u5f88\u91cd\u8981\u3002
  • \u7b97\u6cd5\u8bbe\u8ba1 1 \u94fe\u8868\u5faa\u73af\u68c0\u6d4b

\u60f3\u8c61\u4e00\u4e2a\u89e3\u8c1c\u573a\u666f\uff1a\u5982\u679c\u4f60\u548c\u4f60\u7684\u670b\u53cb\u8d70\u5728\u4e00\u6761\u8def\u4e0a\uff0c\u4f60\u4eec\u8981\u600e\u4e48\u505a\u624d\u80fd\u5224\u65ad\u6709\u6ca1\u6709\u9047\u5230\u9b3c\u6253\u5899\uff08\u5373\u5728\u539f\u8def\u7ed5\u5708\uff09 \uff1f

\u7b54\u6848\u5f88\u7b80\u5355\uff1a\u4e00\u4e2a\u4eba\u8d70\u5feb\u70b9\uff0c\u4e00\u4e2a\u4eba\u8d70\u6162\u70b9\u3002\u5982\u679c\u8fd9\u6761\u8def\u6709\u5c3d\u5934\uff0c\u5148\u8d70\u7684\u4eba\u4e00\u5b9a\u4f1a\u5148\u5230\u8fbe\u5c3d\u5934\uff1b\u5982\u679c\u6ca1\u6709\u5230\u8fbe\u5c3d\u5934\uff0c\u90a3\u4e48\u4ed6\u4e00\u5b9a\u4f1a\u91cd\u65b0\u770b\u89c1\u4f60\u3002

LoopDetect() \u51fd\u6570\u7684\u601d\u8def\u4e5f\u7c7b\u4f3c\uff1a\u4f7f\u7528\u4e24\u4e2a\u6307\u9488 fast \u548c late\uff0cfast \u6bcf\u6b21\u6b65\u8fdb\u4e24\u4e2a\u8282\u70b9\uff0clate \u6bcf\u6b21\u6b65\u8fdb\u4e00\u4e2a\u8282\u70b9\u3002\u6700\u540e\u7ec8\u6b62\u65f6\u53ea\u6709\u4e24\u79cd\u6761\u4ef6\uff1afast \u65e0\u6cd5\u7ee7\u7eed\u6b65\u8fdb\u6216 fast \u5728\u524d\u8fdb\u7684\u8def\u4e0a\u770b\u89c1 late\u3002\u524d\u8005\u8868\u660e\u6ca1\u6709\u5faa\u73af\uff0c\u540e\u8005\u8868\u660e\u6709\u5faa\u73af\u3002

  • \u7b97\u6cd5\u8bbe\u8ba1 2 \u6709\u5e8f\u6570\u7ec4\u539f\u5730\u53bb\u91cd

\u770b\u5230\u8fd9\u9053\u9898\u4f60\u6709\u6ca1\u6709\u60f3\u8d77\u5b57\u7b26\u4e32\u53bb\u7a7a\u683c\u7684\u4e00\u4e2a\u4f8b\u7a0b\uff1f

char *a;\nfor(int i = 0, j = 0; i < length; i++){\n    if(a[i] != ' ')\n        a[j++] = a[i];\n}\n

\u6709\u5e8f\u6570\u7ec4\u53bb\u91cd\u4e0e\u8fd9\u4e2a\u7b97\u6cd5\u4e5f\u6709\u4e9b\u7c7b\u4f3c\uff0c\u53ea\u662f\u6bd4\u8f83\u6761\u4ef6\u6362\u6210 a[i]!=a[j] \u4e86\u800c\u5df2\u3002

"},{"location":"programming/exam/lectures_on_c_programming/#2019-2020","title":"2019-2020 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 1 \u9012\u5f52\u51fd\u6570
  • D \u9879 \u8c03\u7528\u6808\u4f4d\u4e8e\u5806\u6808\u6bb5\uff08Stack Segment\uff09\uff0c\u5728\u8fd0\u884c\u65f6\u521b\u5efa\uff0c\u4e5f\u6709\u81ea\u5df1\u7684\u5927\u5c0f\uff0c\u4e0d\u80fd\u8d8a\u754c\u8bbf\u95ee\u3002\u8d8a\u754c\u9020\u6210\u6bb5\u9519\u8bef\uff08Segmentation Fault\uff09\u3002\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u6dfb\u52a0\u6808\u5e27\uff0c\u9020\u6210\u7684\u8d8a\u754c\u79f0\u4e3a\u6808\u6ea2\u51fa\uff08Stack Overflow\uff09\u3002\u5806\u6808\u6bb5\u4e2d\u4fdd\u5b58\u7740\u51fd\u6570\u8c03\u7528\u5173\u7cfb\u548c\u5c40\u90e8\u53d8\u91cf\u3002\u5c40\u90e8\u53d8\u91cf\u8fc7\u5927\u4e5f\u53ef\u80fd\u9020\u6210\u6808\u6ea2\u51fa\u3002
  • \u9009\u62e9\u9898 2 \u65f6\u95f4\u590d\u6742\u5ea6\u5206\u6790
  • \u9009\u62e9\u9898 6 \u51fd\u6570\u6307\u9488

\u4e00\u53e5\u8bdd\u603b\u7ed3\uff1a\u4f5c\u4e3a\u51fd\u6570\u4f5c\u4e3a\u5f62\u53c2\uff0c\u4f1a\u81ea\u52a8\u9000\u5316\u6210\u51fd\u6570\u6307\u9488\uff0c\u5c31\u50cf\u6570\u7ec4\u540d\u4f5c\u4e3a\u5f62\u53c2\u81ea\u52a8\u9000\u5316\u6210\u6307\u9488\u90a3\u6837\u3002\u8fd9\u53e5\u8bdd\u5728\u4e0b\u9762\u7684\u82f1\u6587\u90e8\u5206\u63d0\u5230\u4e86\u3002

The type of a function is determined using the following rules. [...] After determining the type of each parameter, any parameter of type \u201carray of T\u201d or of function type T is adjusted to be \u201cpointer to T\u201d. [...]

  • \u51fd\u6570\u6307\u9488\uff1a\u6307\u5411\u51fd\u6570\u7684\u6307\u9488\u4e2d\u50a8\u5b58\u7740\u51fd\u6570\u4ee3\u7801\u7684\u8d77\u59cb\u5904\u5730\u5740\uff0c\u8981\u6307\u660e\u51fd\u6570\u7684\u7c7b\u578b\uff0c\u8981\u6307\u660e\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u548c\u5f62\u53c2\u7c7b\u578b\u3002\u628a\u51fd\u6570\u540d\u66ff\u6362\u6210 (*pf) \u7684\u5f62\u5f0f\u662f\u6700\u7b80\u5355\u7684\u65b9\u6cd5\uff0c\u5982 void ToUpper(char *) \u6539\u4e3a\u51fd\u6570\u6307\u9488 void (*pf)(char *)\u3002
  • \u58f0\u660e\u51fd\u6570\u6307\u9488\u540e\uff0c\u53ef\u4ee5\u5c06\u51fd\u6570\u7684\u5730\u5740\u8d4b\u7ed9\u5b83\uff0c\u8fd9\u79cd\u8bed\u5883\u4e0b\u51fd\u6570\u540d\u53ef\u4ee5\u8868\u793a\u51fd\u6570\u7684\u5730\u5740\u3002\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u5199\uff1apf = ToUpper\uff0c\u6ce8\u610f\u4e0d\u662f pf = ToUpper()\u3002

  • \u4f7f\u7528\u51fd\u6570\u6307\u9488\u8c03\u7528\u51fd\u6570\u6709\u4e24\u79cd\u65b9\u6cd5\uff1a(*pf)(mis) \u548c pf(mis)\uff0c\u5b83\u4eec\u770b\u8d77\u6765\u77db\u76fe\u3002\u4e8b\u5b9e\u4e0a\uff0cK&R C \u4e0d\u5141\u8bb8\u7b2c\u4e8c\u79cd\u5f62\u5f0f\uff0c\u6211\u4e5f\u63a8\u8350\u5927\u5bb6\u59cb\u7ec8\u5c06\u51fd\u6570\u8c03\u7528\u7406\u89e3\u4e3a\u7b2c\u4e00\u79cd\u5f62\u5f0f\u3002

    • \u7b2c\u4e00\u79cd\u5f62\u5f0f\uff0c\u5148\u89e3\u5f15\u7528\u51fd\u6570\u6307\u9488\u518d\u8c03\u7528\u8be5\u51fd\u6570\uff0c\u8fd9\u4e2a\u601d\u8def\u5f88\u76f4\u63a5\u3002
    • \u7b2c\u4e8c\u79cd\u5f62\u5f0f\uff0c\u6765\u6e90\u662f\u4e0a\u9762\u7684\u8d4b\u503c\u8bed\u53e5\uff0c\u5728\u4e0a\u9762\u7684\u8d4b\u503c\u8bed\u5883\u4e0b\uff0c\u6307\u9488\u548c\u51fd\u6570\u540d\u53ef\u4ee5\u4e92\u6362\u4f7f\u7528\u3002
  • \u53d6\u51fd\u6570\u7684\u5730\u5740\u4e5f\u6709\u4e24\u79cd\u65b9\u6cd5\uff1af \u548c &f\u3002

  • C \u9879 \u6216\u8bb8\u901a\u8fc7\u4e0a\u9762\u7684\u8bb2\u89e3\uff0c\u4f60\u80fd\u7406\u89e3 (*cmd) \u4e0e cmd \u7684\u7b49\u4ef7\u4e4b\u5904\u3002\u4e0b\u9762\u662f StackOverflow \u4e2d\u7684\u8ba8\u8bba\uff1ac++ - What does void f(void()) mean? - Stack Overflow\u3002

As mentioned in dcl.fct of the working draft (emphasis mine):

The type of a function is determined using the following rules. [...] After determining the type of each parameter, any parameter of type \u201carray of T\u201d or of function type T is adjusted to be \u201cpointer to T\u201d. [...]

Because of that, the following function:

void f(void());\n

Has the same type of:

void f(void(*)());\n

Thus the definitions below are identical:

void f(void(g)());\nvoid f(void(*g)());\n

Correct me if I'm wrong, AFAIK function names are pointers just like array names so in the first example you are passing function object and compiler does implicit conversion, in the second example you are directly passing function pointer which is explicit conversion.

  • \u9009\u62e9\u9898 7 \u51fd\u6570\u6307\u9488

\u540c\u6837\u4f9d\u636e\u4e0a\u9762\u7684\u8bb2\u89e3\u80fd\u591f\u9009\u51fa\u6b63\u786e\u7b54\u6848

  • \u9009\u62e9\u9898 8 \u51fd\u6570\u53c2\u6570

\u6211\u89c9\u5f97 D \u9879\u7684\u8868\u8ff0\u672c\u6765\u5c31\u5f88\u6df7\u4e71\u3002\u51fd\u6570\u53c2\u6570\u5982\u679c\u4e3a void \u5c31\u8868\u793a\u51fd\u6570\u4e0d\u63a5\u6536\u53c2\u6570\uff0c\u8fd9\u5c31\u662f void \u5173\u952e\u5b57\u7684\u4f5c\u7528\uff0c\u800c\u4e0d\u662f\u9009\u9879\u4e2d\u8bf4\u7684\u4ec0\u4e48\u201c\u51fd\u6570\u6709\u4e00\u4e2a void \u7c7b\u578b\u7684\u53c2\u6570\u201d\u3002

  • \u9009\u62e9\u9898 9 \u56fe\u5f62\u5e93

\u8bf7 WK \u73ed\u540c\u5b66\u4e00\u5b9a\u8981\u53bb\u770b\u8f85\u5b66\u7fa4\u91cc\u5176\u4ed6\u8001\u5e08\u7684\u56fe\u5f62\u5e93\u8bfe\u4ef6

  • \u9009\u62e9\u9898 10 \u8fd8\u662f\u51fd\u6570\u6307\u9488
  • \u7b2c\u4e00\u884c\uff1aF \u5b9a\u4e49\u4e3a int (int) \u7c7b\u578b\u7684\u51fd\u6570\u3002
  • \u7b2c\u4e8c\u884c\uff1a\u58f0\u660e\u4e24\u4e2a\u7c7b\u578b\u4e3a F \u7684\u51fd\u6570 g \u548c h\u3002\u5176\u5b9e\u5c31\u662f int g(int a) \u548c int h(int a)\u3002
  • \u7b2c\u4e09\u884c\uff1a\u58f0\u660e\u4e00\u4e2a\u6570\u7ec4 p\uff0c\u5176\u4e2d\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f int (*)(int) \u7c7b\u578b\uff08\u4e0e F \u7b49\u4ef7\uff09\u3002\u5e76\u7528 g \u548c h \u6765\u521d\u59cb\u5316\u8fd9\u4e2a\u6570\u7ec4\u3002
    • \u8ba9\u6211\u4eec\u4ece\u5185\u5f80\u5916\u8bfb\u8fd9\u4e2a\u58f0\u660e\uff1ap \u662f\u6807\u8bc6\u7b26\u7684\u540d\u79f0\uff0c\u5411\u53f3 [] \u8868\u660e\u8fd9\u662f\u4e00\u4e2a\u6570\u7ec4\uff0c\u5411\u5de6 * \u8868\u793a\u5176\u5143\u7d20\u662f\u6307\u9488\uff0c\u518d\u5411\u53f3 (int) \u8868\u793a\u5176\u6240\u6307\u7c7b\u578b\u662f\u51fd\u6570\uff0c\u8fd9\u79cd\u51fd\u6570\u63a5\u53d7 int \u7c7b\u578b\u53c2\u6570\uff0c\u518d\u5411\u5de6 int \u8bf4\u660e\u8fd9\u79cd\u51fd\u6570\u8fd4\u56de int \u7c7b\u578b\u3002
    • \u7528 g \u548c h \u521d\u59cb\u5316\u8fd9\u4e2a\u6570\u7ec4\u65f6\uff0cg \u548c h \u88ab\u8f6c\u6362\u4e3a\u51fd\u6570\u6307\u9488\uff08\u56de\u987e\u4e0a\u9762\u7684\u8ba8\u8bba\uff09\u3002
  • \u7b2c\u56db\u884c\uff1a\u58f0\u660e\u4e00\u4e2a\u51fd\u6570 q \u8fd9\u4e2a\u51fd\u6570\u8fd4\u56de int\uff0c\u63a5\u53d7\u4e00\u79cd\u6570\u7ec4\uff0c\u8fd9\u79cd\u6570\u7ec4\u7684\u6bcf\u4e2a\u5143\u7d20\u90fd\u662f F* \u7c7b\u578b\uff0c\u5373 int (*)(int)\u3002\u6545\u51fd\u6570 q \u7684\u53c2\u6570\u7c7b\u578b\u4e3a int (**)(int)\u3002

  • A \u9879\uff1a\u6570\u7ec4\u540d\u5c31\u662f\u9996\u5143\u7d20\u6307\u9488\uff0c\u4e3a int (**)(int)\uff0c\u5339\u914d\u3002

  • C \u9879\uff1a\u663e\u7136\u7c7b\u578b\u5339\u914d\u3002
  • D \u9879\uff1a\u5bf9\u51fd\u6570\u53d6\u5730\u5740\uff0c\u5f97\u5230 int (*)(int)\uff0c\u4e0e int (**)(int) \u7c7b\u578b\u4e0d\u5339\u914d\u3002
  • \u7b80\u7b54\u9898 1

\u5982\u679c\u7a0b\u5e8f\u4ee3\u7801\u6709\u9519\uff0c\u5c31\u52c7\u6562\u5730\u5199\u201c\u8be5\u6bb5\u7a0b\u5e8f\u53ef\u80fd\u8fd0\u884c\u5931\u8d25\u201d\u3002

  • \u7b80\u7b54\u9898 3

\u6ce8\u610f\uff0c\u5408\u5e76\u6570\u7ec4\u7684\u65f6\u5019\u90e8\u5206\u53bb\u91cd\u4e86\u3002\u5982\u679c\u79bb\u5f00\u4e86\u7b2c\u4e00\u4e2a while \u5faa\u73af\uff0c\u5219\u4e0d\u4f1a\u53bb\u91cd\u3002

  • \u7b80\u7b54\u9898 4

\u8ba9\u6211\u4eec\u770b main() \u51fd\u6570\u7684\u7b2c\u4e00\u884c\u7684\u8868\u8fbe\u5f0f\uff1a

  • \u5916\u5c42\uff1a((H)\u5185\u5c42\u8868\u8fbe\u5f0f )(100);\uff0c\u5b83\u4f1a\u5c06\u5185\u5c42\u8868\u8fbe\u5f0f\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u4e3a H \u7c7b\u578b\u7684\u51fd\u6570\uff0c\u7136\u540e\u5bf9\u8be5\u51fd\u6570\u6267\u884c\u51fd\u6570\u8c03\u7528\u3002
  • \u5185\u5c42\uff1ah(0)\u3002\u8c03\u7528\u540e\u8fd4\u56de\u4e86 h\uff0c\u5373\u51fd\u6570\u81ea\u5df1\uff0c\u4e5f\u5c31\u662f\u51fd\u6570\u81ea\u5df1\u7684\u6307\u9488\u3002\u4f5c\u4e3a void * \u7c7b\u578b\u8fd4\u56de\uff0c\u8868\u660e\u5b83\u662f\u4e00\u4e2a\u6307\u9488\uff0c\u4f46\u4e0d\u77e5\u9053\u6240\u6307\u5411\u7684\u7c7b\u578b\u3002
  • \u5185\u5c42\u8c03\u7528\u540e\uff0c\u5916\u5c42\u5c31\u76f8\u5f53\u4e8e h(100)\u4e86\uff0c\u56e0\u4e3a h \u672c\u6765\u5c31\u662f H \u7c7b\u578b\u7684\u51fd\u6570\u3002
  • \u7a0b\u5e8f\u586b\u7a7a 3 geblib.h

WK \u73ed\u540c\u5b66\u5e94\u5f53\u8865\u5145\u9605\u8bfb libgraphics \u5e93\u4e2d\u7684\u4e00\u4e9b\u5185\u5bb9\uff0c\u6211\u4eec\u76f4\u63a5\u8bfb\u6e90\u7801\u5427\uff1a

  • New() \u5b8f\u51fd\u6570\uff1a

    • Usage: p = New(pointer-type);

    • The New pseudofunction allocates enough space to hold an object of the type to which pointer-type points and returns a pointer to the newly allocated pointer. Note that \"New\" is different from the \"new\" operator used in C++; the former takes a pointer type and the latter takes the target type.

    • \u6e90\u7801\uff1a

      void *GetBlock(size_t nbytes);\n#define New(type) ((type) GetBlock(sizeof *((type) NULL)))\n
    • \u4e3e\u4e2a\u4f8b\u5b50\uff1a\u8c03\u7528 New(char*)

      • \u5b8f\u5c55\u5f00\u4e3a ((char*) GetBlock(sizeof *((char*) NULL)))
      • GetBlock() \u51fd\u6570\u63a5\u6536\u9700\u8981\u5206\u914d\u7684\u5b57\u8282\u6570\uff0c\u8fd4\u56de\u5206\u914d\u6210\u529f\u7684\u6307\u9488\u3002\u5bf9\u4e8e\u4e0a\u9762\u7684\u5b8f\u5c55\u5f00\u540e\u7684\u8c03\u7528\u53c2\u6570\uff0cNULL \u88ab\u8f6c\u6362\u4e3a char* \u968f\u540e\u89e3\u5f15\u7528\u4ecd\u4e3a char \u7c7b\u578b\u7684\u5927\u5c0f\u3002
      • \u8fd9\u4e2a\u8c03\u7528\u5c31\u8fd4\u56de\u4e86\u4e00\u4e2a char* \u7684\u6307\u9488\u3002
  • FreeBlock() \u51fd\u6570\uff1a

    • \u539f\u578b\uff1avoid FreeBlock(void *ptr)
    • \u4e0e free() \u529f\u80fd\u7c7b\u4f3c\uff0c\u4e0d\u52a0\u89e3\u91ca\u3002

\u7b2c 15 \u7a7a\u6709\u610f\u601d\uff0cFreeBlock(PopStack(stack)) \u7684\u5d4c\u5957\u5199\u6cd5\u3002

  • \u7b97\u6cd5\u8bbe\u8ba1 1 \u5206\u5f62

\u8fd9\u7c7b\u7b97\u6cd5\u8bbe\u8ba1\u9898\u76ee\uff0c\u600e\u4e48\u7b80\u6d01\u600e\u4e48\u6765\uff0c\u4ee5 OI \u7801\u98ce\u53bb\u5199\u662f\u6700\u5408\u9002\u7684\u3002\u4e0d\u8981\u8bd5\u56fe\u5f04\u5b8c\u5584\u7684\u4ea4\u4e92\uff0c\u90a3\u662f\u6d6a\u8d39\u65f6\u95f4\u3002

\u4ee5\u4e0b\u662f\u6211\u81ea\u5df1\u505a\u7684\u65f6\u5019\u5199\u7684\uff0c\u4f5c\u4e3a\u4e00\u4e2a\u4e0d\u597d\u7684\u53c2\u8003\uff08

\u7406\u89e3\u9519\u9898\u610f\u4e86\uff0c\u539f\u6765 order \u4e0d\u662f\u65b9\u5411\u800c\u662f\u5206\u5f62\u6b21\u5e8f\u3002

  • \u57fa\u51c6\u60c5\u5f62\uff1a\u957f\u5ea6\u7f29\u5c0f\u5230\u67d0\u503c\u3002
  • \u9012\u5f52\u60c5\u5f62\uff1a\u753b\u4e00\u6839\uff0c\u968f\u540e\u4e24\u6b21\u9012\u5f52\u8c03\u7528\uff0c\u7ed8\u5236\u4e0b\u4e00\u652f\u7684 length \u548c order\u3002\u6bcf\u6b21\u9012\u5f52\u8c03\u7528\u540e\uff0c\u90fd\u5e94\u5f53\u8fd4\u56de\u539f\u4f4d\u3002

    #include <stdio.h>\n#include <math.h>\n#include <stdlib.h>\n#include \"graphics.h\"\n#define MIN_LEN .1\n\ndouble toRadius(double deg)\n{\n    return deg * 3.1415926 / 180;\n}\n\nvoid DrawBranch(double len, double deg)\n{\n    DrawLine(len * cos(toRadius(deg)), len * sin(toRadius(deg)));\n    if (len * 0.75 < MIN_LEN)\n        return;\n    DrawBranch(len * 0.75, deg - 15);\n    MovePen(GetCurrentX() - len * 0.75 * cos(toRadius(deg - 15)),\n            GetCurrentY() - len * 0.75 * sin(toRadius(deg - 15)));\n    //\u4e5f\u53ef\u4ee5\u7528 DrawLine \u5b9e\u73b0\n    DrawBranch(len * 0.75, deg + 15);\n    MovePen(GetCurrentX() - len * 0.75 * cos(toRadius(deg + 15)),\n            GetCurrentY() - len * 0.75 * sin(toRadius(deg + 15)));\n}\n\nint main(void)\n{\n  double length;\n    char order;\n    printf(\"Please enter initial length: \");\n    scanf(\"%lf\", &length);\n    getchar();\n    printf(\"Please enter order (u)pper, (d)own, (r)ight, (l)eft: \");\n    scanf(\"%c\", &order);\n    double deg;\n    switch(order)\n    {\n        case 'u': deg = 90; break;\n        case 'd': deg = -90; break;\n        case 'r': deg = 0; break;\n        case 'l': deg = 180; break;\n        default: printf(\"error.\\n\"); return 1;\n    }\n    InitGraphics();\n    MovePen(GetWindowWidth()/2, GetWindowHeight()/2);\n  DrawBranch(length, deg);\n    return 0;\n}\n
  • \u7b97\u6cd5\u8bbe\u8ba1 2 \u5217\u8868\u53d8\u5e8f

\u5c31\u7528\u6807\u7b54\u7684\u65b9\u6cd5\uff0c\u5c06\u5076\u6570\u8282\u70b9\u79fb\u52a8\u5230\u53e6\u4e00\u4e2a\u94fe\u8868\uff0c\u518d\u5408\u5e76\u4e24\u4e2a\u94fe\u8868\u3002

"},{"location":"programming/exam/lectures_on_c_programming/#2018-2019","title":"2018-2019 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 4 \u9012\u5f52\u8ba1\u7b97

\u50cf\u8fd9\u79cd\u9012\u5f52\u8ba1\u7b97\uff0c\u5c31\u8001\u8001\u5b9e\u5b9e\u628a\u51fd\u6570\u9012\u5f52\u5c55\u5f00\u5427\u3002\u5c55\u5f00\u8fc7\u7a0b\u4e2d\u8bb0\u5f97\u4f9d\u6b21\u8bb0\u4e0b\u5df2\u7ecf\u8ba1\u7b97\u5b8c\u7684 f(0)\u3001f(1) \u7b49\u503c\uff0c\u65b9\u4fbf\u540e\u7eed\u8ba1\u7b97\u3002

  • \u9009\u62e9\u9898 6 \u7b97\u6cd5\u590d\u6742\u5ea6\u5206\u6790

\u8fd9\u9053\u9898\u6211\u7684\u60f3\u6cd5\u633a\u5947\u8469\u7684\uff0c\u6211\u662f\u60f3\u53ea\u8981\u5168\u90e8\u6392\u5e8f\u4e00\u904d \\(O(N\\log N)\\)\uff0c\u7136\u540e\u7528 \\(O(1)\\) \u7684\u65f6\u95f4\u68c0\u67e5\u4e00\u4e0b\u5934\u3001\u4e2d\u95f4\u3001\u5c3e\u90e8\u7684\u5143\u7d20\u4e0d\u5c31\u597d\u4e86\u5417\uff08doge

  • \u9009\u62e9\u9898 9 \u9012\u589e\u8fd0\u7b97\u7b26

\u524d\u7f00\u9012\u589e\u8fd0\u7b97\u7b26\u5148\u9012\u589e\u518d\u4f7f\u7528\u3002

  • \u7b80\u7b54\u9898 1.2

\u672c\u9898\u82f1\u6587\u6709\u70b9\u70eb\u5634\uff0c\u6211\u7ffb\u8bd1\u4e00\u4e0b\uff1a

\u4e3a\u4e86\u7528\u7c7b\u4f3c T p \u7684\u65b9\u5f0f\u58f0\u660e\u4e00\u4e2a\u6307\u9488 p\uff0c\u8bf7\u5199\u51fa\u590d\u5408\u7c7b\u578b T \u7684\u5b9a\u4e49\u3002p \u662f\u4e00\u4e2a\u51fd\u6570\u7684\u6307\u9488\uff0c\u8be5\u51fd\u6570\u63a5\u6536 (char *, double) \u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u4e00\u4e2a int *\u3002

\u8bfb\u61c2\u9898\u76ee\u5269\u4e0b\u7684\u5c31\u4e0d\u7528\u8bf4\u5566\u3002

  • \u7b80\u7b54\u9898 2 \u6570\u636e\u4e0e\u5b57\u8282

\u6ce8\u610f\uff1axx-bit system\uff08n \u4f4d\u7cfb\u7edf\uff09\u6307\u7684\u662f\u8fd9\u4e2a\u7cfb\u7edf\u7684\u6307\u9488\u957f\u5ea6\u6709 \\(n\\) \u6bd4\u7279\uff0c\\(8\\) \u6bd4\u7279\u4e3a\u4e00\u4e2a\u5b57\u8282\u3002\u6545\u672c\u9898\u7684\u6240\u6709\u6307\u9488\u90fd\u662f \\(4\\) \u5b57\u8282\u3002

\u4ee5\u4e0b\u662f\u5404\u7c7b\u578b\u7684\u5927\u5c0f\uff1a

  • StudentInfo\uff1a\u4e24\u4e2a char \u6570\u7ec4 + \u4e00\u4e2a\u6307\u9488 = \\(12 + 20 + 4 = 36\\)
  • PtrStudentInfo\uff1a\\(4\\)
  • pStudent->name\uff1a\u4e00\u4e2a char \u6570\u7ec4 \\(=20\\)
  • pStudent->photo\uff1a\u4e00\u4e2a void* \u6307\u9488 \\(=4\\)

\u4ece\u4e0a\u9762\u518d\u6b21\u770b\u5230\uff0c\u6570\u7ec4\u540d\u5e76\u4e0d\u80fd\u7b80\u5355\u88ab\u770b\u4f5c\u6307\u9488\uff0c\u5b83\u8fd8\u5305\u542b\u6570\u7ec4\u7684\u7c7b\u578b\u4fe1\u606f\u3002

  • \u7b80\u7b54\u9898 3 \u94fe\u8868\u64cd\u4f5c

\u8fd9\u9053\u9898\u7b54\u6848\u611f\u89c9\u6709\u70b9\u95ee\u9898\u554a\u3002\u53cd\u6b63\u53ea\u8981\u77e5\u9053\u8fd4\u56de\u7684\u65f6\u5019 p \u6307\u5411 \\(2\\) \u8fd9\u4e2a\u8282\u70b9\u5c31\u7b97\u5bf9\u4e86\uff0c\u9898\u76ee\u8bf4 node \u90a3\u5e94\u8be5\u4e0d\u7528\u5427\u540e\u9762\u7684\u8282\u70b9\u90fd\u5199\u51fa\u6765\u5427\u3002

  • \u7b80\u7b54\u9898 4 \u94fe\u8868\u64cd\u4f5c

\u8fd9\u4e2a\u51fd\u6570\u5408\u5e76\u4e86\u4e24\u4e2a\u94fe\u8868\uff0c\u6309\u5347\u5e8f\u5408\u5e76\u3002

HEAD \u662f\u4e00\u4e2a\u4e34\u65f6\u4f7f\u7528\u7684\u54d1\u8282\u70b9\u3002

\u8c03\u7528\u540e\uff0c\u539f\u6765\u7684\u4e24\u4e2a\u6307\u9488\u6307\u7684\u4f4d\u7f6e\u4e0d\u53d8\uff0cl1 \u4ecd\u7136\u6307\u5411 \\(1\\) \u8fd9\u4e2a\u8282\u70b9\u3002\u4f46\u8282\u70b9\u4e4b\u95f4\u7684\u8fde\u63a5\u53d8\u4e86\uff0c\u8fd9\u65f6 l1 \u540e\u9762\u94fe\u4e0a\u4e86\u4ece l2 \u5408\u5e76\u8fdb\u6765\u7684\u5176\u4ed6\u8282\u70b9\u3002\u6240\u4ee5\u53ef\u4ee5\u770b\u4f5c\u201c\u94fe\u8868\u201d l1 \u53d1\u751f\u4e86\u6539\u53d8\u3002

  • \u7b80\u7b54\u9898 5 \u53cc\u5411\u6808

\u8fd9\u662f\u4e00\u4e2a\u53cc\u5411\u7684\u6808\u3002\u6bcf\u6b21\u5165/\u51fa\u6808\u65f6\uff0c\u9700\u8981\u7528 Tag \u53c2\u6570\u6307\u5b9a\u662f\u54ea\u4e00\u5934\u3002\u4ece\u6570\u7ec4\u7684\u89d2\u5ea6\u6765\u770b\uff0cTop1 \u662f\u5de6\u8fb9\uff08\u5934\u90e8\uff09\u90a3\u5934\uff0cTop2 \u662f\u53f3\u8fb9\uff08\u5c3e\u90e8\uff09\u90a3\u5934\u3002

\u8bfb\u8fd9\u79cd\u9898\u65f6\uff0c\u6211\u63a8\u8350\u5148\u8bfb main() \u4e2d\u7684\u5185\u5bb9\uff0c\u5373\u89c2\u5bdf\u9898\u76ee\u7ed9\u7684\u6570\u636e\u7ed3\u6784\u662f\u600e\u4e48\u88ab\u4f7f\u7528\u7684\u3002\u7136\u540e\u4e0d\u660e\u767d\u7684\u5730\u65b9\u518d\u53bb\u770b\u5177\u4f53\u5b9e\u73b0\u7684\u4ee3\u7801\uff0c\u5176\u4ed6\u90e8\u5206\u5c31\u4e00\u70b9\u90fd\u4e0d\u7528\u770b\u3002\u6bd4\u5982\u8fd9\u9053\u9898\uff1a

  • \u5148\u770b main() \u4e2d\u7684 Push() \uff0c\u8fd9\u600e\u4e48\u6bd4\u5e73\u5e38\u7684 Push() \u591a\u4e00\u4e2a\u53c2\u6570\u5462\uff1f
  • \u518d\u770b\u7c7b\u578b\u5b9a\u4e49\uff0c\u600e\u4e48\u6709\u4e24\u4e2a Top\uff1f\u56de\u60f3 main() \u4e2d\u4e00\u4e2a\u4ee4\u4e3a -1 \u4e00\u4e2a\u4ee4\u4e3a MaxSize \u4fbf\u77e5\u9053\u8fd9\u662f\u4e00\u4e2a\u53cc\u5411\u6808\u4e86\u3002
  • Push() \u548c Pop() \u7684\u4ee3\u7801\u5c31\u4e0d\u7528\u770b\u4e86\uff0c\u60f3\u8c61\u5f97\u5230\u662f\u600e\u4e48\u64cd\u4f5c\u7684\u3002\u6700\u591a\u518d\u591a\u770b\u4e00\u773c if(Tag == 1) \u77e5\u9053\u54ea\u4e2a\u503c\u5bf9\u5e94\u54ea\u4e00\u5934\uff0c\u5c31\u53ef\u4ee5\u5b8c\u6210\u8fd9\u9053\u9898\u4e86\u3002
  • \u7b80\u7b54\u9898 6 \u4e0d\u77e5\u9053\u662f\u4ec0\u4e48

\u8fd9\u4e2a\u4e1c\u897f\uff0c\u4fdd\u9669\u8d77\u89c1\u63a8\u8350\u624b\u5de5\u6a21\u62df\uff0c\u800c\u4e14\u624b\u5de5\u6a21\u62df\u51e0\u6b21\u540e\u4f60\u5c31\u77e5\u9053\u8fd9\u4e2a\u51fd\u6570\u5728\u5e72\u561b\u4e86\u3002

\u5176\u5b9e\u8fd9\u4e2a\u51fd\u6570\u7684\u4f5c\u7528\u662f\uff1a\u8c03\u7528\u540e\u4fdd\u8bc1\u6570\u7ec4 a[k] \u5de6\u4fa7\u7684\u5143\u7d20\u90fd\u6bd4 a[k] \u5c0f\uff0c\u53f3\u4fa7\u90fd\u6bd4 a[k] \u5927\u3002\u6700\u540e\u8fd4\u56de a[k] \u4e0a\u7684\u5143\u7d20\u3002\u4f46\u4e0d\u4f1a\u4fdd\u8bc1\u5176\u4ed6\u5143\u7d20\u4e4b\u95f4\u7684\u76f8\u5bf9\u987a\u5e8f\u3002

\u5177\u4f53\u7684\u64cd\u4f5c\u5c31\u662f\uff1a\u6bcf\u8f6e\u5faa\u73af\u628a\u7b2c a[k] \u4f4d\u7f6e\u4e0a\u7684\u5143\u7d20\u63d0\u51fa\u6765\u4f5c\u4e3a x\uff0c\u7136\u540e\u7528 i \u548c j \u5206\u522b\u4ece\u5de6\u53f3\u904d\u5386\u5e76\u4ea4\u6362\u4e24\u4fa7\u4e0d\u7b26\u5408\u8981\u6c42\u7684\u6570\u3002\u4ea4\u6362\u5b8c\u6210\u540e\uff0c\u6570\u7ec4\u4e2d\u6bd4 x \u5c0f\u7684\u6570\u90fd\u5728\u76f8\u5bf9\u5de6\u8fb9\u7684\u4f4d\u7f6e\uff0c\u6bd4 x \u5927\u7684\u6570\u90fd\u5728\u76f8\u5bf9\u53f3\u8fb9\u7684\u4f4d\u7f6e\u3002

\u5982\u679c\u4f60\u5bf9\u5feb\u6392\u6bd4\u8f83\u719f\u6089\uff0c\u90a3\u4e48\u8fd9\u5c31\u662f\u201c\u5982\u679c\u76ee\u6807\u4f4d\u7f6e\u4e0d\u5728\u7684\u4e00\u8fb9\u76f4\u63a5\u820d\u5f03\u201d\u7684\u5feb\u6392\u3002\u76f8\u5f53\u4e8e\u672c\u6765\u5feb\u6392\u533a\u95f4\u5f62\u6210\u4e00\u9897\u6811\uff0c\u4f46\u662f\u73b0\u5728\u5c31\u53ea\u8d70\u4e00\u6761\u8def\uff0c\u53ea\u6392 a[k] \u6240\u5728\u7684\u90a3\u4e9b\u533a\u95f4\u5957\u3002

  • \u7a0b\u5e8f\u586b\u7a7a 1 \u5206\u578b

\u753b\u4e2a\u5750\u6807\u8f74\uff0c\u4e00\u5207\u90fd\u6e05\u6670\u8d77\u6765\u4e86\u3002\u7136\u540e Main() \u91cc\u6700\u5f00\u59cb\u5bf9\u5927\u4e09\u89d2\u5f62\u4e09\u4e2a\u9876\u70b9\u7684\u6c42\u503c\u53ef\u80fd\u4f1a\u5f15\u8d77\u56f0\u60d1\uff0c\u5176\u5b9e\u53ef\u4ee5\u4e0d\u7528\u7ba1\u5b83\uff0c\u5b83\u4e0d\u5f71\u54cd\u4f60\u5206\u6790\u9012\u5f52\u8c03\u7528\u8fc7\u7a0b\u3002\u5b83\u53ea\u662f\u5728\u7528\u4e09\u89d2\u51fd\u6570\u8ba1\u7b97\u4f4d\u7f6e\u4f7f\u8fd9\u4e2a\u5927\u4e09\u89d2\u5f62\u7684\u4e2d\u5fc3\u5728\u5c4f\u5e55\u4e2d\u592e\u7f62\u4e86\u3002\u7ed9\u4e2a\u5f88\u8349\u7684\u8349\u7a3f\u793a\u610f\u56fe\uff1a

\u753b\u8fd9\u4e2a\u5206\u5f62\u7684\u6b65\u9aa4\u5c31\u662f\uff1a\u5148\u753b\u5927\u4e09\u89d2\uff0c\u7136\u540e\u5404\u8fb9\u53d6\u4e2d\u70b9\u3002\u5927\u4e09\u89d2\u7684\u6bcf\u4e2a\u9876\u70b9\u548c\u76f8\u90bb\u4e24\u8fb9\u4e2d\u70b9\u6784\u6210\u4e24\u4e2a\u5c0f\u4e09\u89d2\u3002

  • \u7a0b\u5e8f\u586b\u7a7a 2 \u5faa\u73af\u961f\u5217\u5b9e\u73b0

\u672c\u8d28\u4e0a\u8fd8\u662f\u7528\u6570\u7ec4\u5b9e\u73b0\u5faa\u73af\u961f\u5217\uff0c\u53ea\u4e0d\u8fc7\u672c\u9898\u8fdb\u884c\u4e86\u6bd4\u8f83\u5b8c\u5584\u7684\u5c01\u88c5\u3002

\u5982\u679c\u8fd8\u4e0d\u77e5\u9053\u5faa\u73af\u961f\u5217\u662f\u4ec0\u4e48\u4e1c\u897f\uff0c\u53bb\u7f51\u4e0a\u641c\u4e00\u641c\u3002\u5faa\u73af\u961f\u5217\u7684\u8981\u70b9\u5c31\u662f\uff1a\u6240\u6709\u52a0\u6cd5\u64cd\u4f5c\u5168\u90e8\u8981\u5957\u4e0a\u4e00\u6b21\u53d6\u6a21\u64cd\u4f5c\u3002\u672c\u9898\u6ce8\u610f\u4e00\u4e0b\u95f4\u63a5\u6210\u5458\u8fd0\u7b97\u7b26 -> \u7684\u4f7f\u7528\u3002

\u6b64\u5916\u5faa\u73af\u961f\u5217\u7684 rear \u4e5f\u6709\u4e0d\u540c\u5b9e\u73b0\u65b9\u6cd5\uff0c\u5728\u672c\u9898\u4e2d\uff0c\u5b83\u6807\u5fd7\u961f\u5217\u5c3e\u90e8\u7684\u540e\u4e00\u4e2a\u5143\u7d20\uff0c\u4e5f\u5c31\u662f\u4e0b\u4e00\u4e2a\u5143\u7d20\u5e94\u8be5\u63d2\u5165\u7684\u5730\u65b9\uff1b\u5728\u53e6\u4e00\u4e9b\u5b9e\u73b0\u4e2d\uff0c\u5b83\u76f4\u63a5\u6807\u5fd7\u961f\u5217\u5c3e\u90e8\u7684\u5143\u7d20\u3002\u6bd4\u5982\u5982\u679c\u672c\u9898\u5728\u521b\u5efa\u6570\u7ec4\u7684\u65f6\u5019 Q->rear = maxsize - 1\uff0c\u8fd9\u4e9b\u7a7a\u5e94\u8be5\u4f5c\u600e\u6837\u7684\u6539\u53d8\u5462\uff1f

  • \u7a0b\u5e8f\u586b\u7a7a 3 \u56fe\u5f62\u5e93

\u53c2\u89c1\u5e38\u89c1\u95ee\u9898-\u56fe\u5f62\u5e93-\u8ba1\u65f6\u5668

  • \u7b97\u6cd5\u8bbe\u8ba1 1 \u5bfb\u627e\u7b2c\u4e00\u4e2a\u516c\u5171\u8282\u70b9

\u60f3\u8c61\u8fd9\u6837\u4e00\u4e2a\u60c5\u5883\uff1a\u8fd8\u662f\u60f3\u8c61\u4f60\u548c\u4f60\u7684\u670b\u53cb\u7ad9\u5728\u9898\u76ee\u6240\u793a\u7684\u4e24\u4e2a\u94fe\u8868\u7684\u8d77\u59cb\u5904\u3002\u8fd9\u4e24\u4e2a\u94fe\u8868\u6709\u53ef\u80fd\u76f8\u4ea4\uff0c\u4f60\u4eec\u60f3\u8981\u5c3d\u5feb\u627e\u5230\u4f1a\u5408\u70b9\uff0c\u600e\u4e48\u529e\u5462\uff1f\u800c\u4e14\u4e00\u4e2a\u6709\u7528\u7684\u4fe1\u606f\u662f\uff0c\u4f60\u4eec\u90fd\u77e5\u9053\u81ea\u5df1\u79bb\u7ec8\u70b9\u8fd8\u6709\u591a\u8fdc\u3002

\u5982\u679c\u76f8\u4ea4\uff0c\u4f60\u4eec\u80af\u5b9a\u6709\u516c\u5171\u5b50\u94fe\u8868\u3002\u5269\u4e0b\u4e0d\u540c\u7684\u90e8\u5206\u5c31\u662f\u4f60\u4eec\u5404\u81ea\u5b50\u94fe\u8868\u7684\u957f\u5ea6\u3002\u56e0\u6b64\uff0c\u4f60\u4eec\u5e94\u5f53\u5148\u76f8\u5bf9\u7ec8\u70b9\u5bf9\u9f50\u5f7c\u6b64\u7684\u4f4d\u7f6e\uff0c\u4f7f\u81ea\u5df1\u5269\u4f59\u7684\u5b50\u94fe\u8868\u7684\u7684\u957f\u5ea6\u76f8\u7b49\u3002\u63a5\u4e0b\u6765\u4ee5\u76f8\u540c\u7684\u901f\u5ea6\u524d\u8fdb\uff0c\u5982\u679c\u4f60\u4eec\u5728\u67d0\u5904\u4f1a\u5408\u4e86\uff0c\u90a3\u4e48\u8fd9\u4e00\u5b9a\u662f\u516c\u5171\u5b50\u94fe\u8868\u7684\u8d77\u59cb\u5904\u3002

\u53c2\u7b54\u4e2d\uff0clPtr \u6307\u5411\u8f83\u957f\u7684\u94fe\u8868\uff0csPtr \u6307\u5411\u8f83\u77ed\u7684\u94fe\u8868\uff0cnumLeftNodes \u5c31\u662f\u4e24\u94fe\u8868\u8282\u70b9\u6570\u7684\u5dee\u503c\uff0clPtr=lPtr->next \u7684 for \u5faa\u73af\u5c31\u662f\u5728\u5bf9\u9f50\u4e24\u4eba\u7684\u4f4d\u7f6e\u3002

\u5faa\u73af\u7ec8\u6b62\u7684\u6761\u4ef6\u662f\uff1a\u5176\u4e2d\u67d0\u4eba\u8d70\u5230\u4e86\u5c3d\u5934 NULL\uff0c\u6216\u4e24\u4eba\u76f8\u9047 lPtr==sPtr\u3002\u8fd4\u56de\u6700\u7ec8\u4f4d\u7f6e\u5373\u53ef\u3002

  • \u7b97\u6cd5\u8bbe\u8ba1 2 \u4e8c\u5206\u63d2\u5165\u6392\u5e8f

\u8fd9\u9898\u7b80\u5355\uff0c\u4e0d\u4f5c\u89e3\u6790\u3002\u53c2\u7b54\u4e2d\u6f0f\u4e86\u68c0\u67e5 minPos == rh \u7684\u60c5\u51b5\uff0c\u60f3\u60f3\u8fd9\u6837\u4f1a\u9020\u6210\u4ec0\u4e48\u540e\u679c\uff1f

"},{"location":"programming/exam/lectures_on_c_programming/#2017-2018","title":"2017-2018 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 1 \u6570\u636e\u7c7b\u578b\u4e0e\u6307\u9488\u64cd\u4f5c
  • C \u9879\uff1astrcpy() \u53ea\u80fd\u7528\u4e8e\u5b57\u7b26\u4e32\u3002\u8fdb\u4e00\u6b65\u8bf4\uff0c\u5b83\u4f9d\u636e\u5b57\u7b26\u4e32\u672b\u5c3e\u7684 \\0 \u6765\u51b3\u5b9a\u662f\u5426\u505c\u6b62\u590d\u5236\uff0c\u56e0\u6b64\u4e0d\u5b9c\u7528\u4e8e\u6b64\u60c5\u5883\u3002
  • D \u9879\uff1a\u6bcf\u6b21 *pc2++ = *pc1++\uff0c\u90fd\u4f1a\u5c06 pc1 \u7684\u4e00\u4e2a\u5b57\u8282\u62f7\u8d1d\u5230 pc2 \u6307\u5411\u7684\u4f4d\u7f6e\uff0c\u5e76\u8ba9\u8fd9\u4e24\u4e2a\u6307\u9488\u5411\u540e\u79fb\u52a8\u4e00\u4e2a char \u7684\u4f4d\u7f6e\u3002\u7531\u4e8e p1 \u548c p2 \u4e24\u4e2a\u7ed3\u6784\u53d8\u91cf\u5927\u5c0f\u90fd\u662f \\(8+8=16\\) \u5b57\u8282\uff0c\u56e0\u6b64\u8be5\u9009\u9879\u6b63\u786e\u5730\u6267\u884c\u4e86\u62f7\u8d1d\u3002
  • \u9009\u62e9\u9898 7 \u5192\u6ce1\u6392\u5e8f

\u8fd9\u9053\u9898\u65f6\uff0c\u6211\u9009\u7684\u662f D \u9879\u3002\u56e0\u4e3a\u6211\u8bb0\u5fc6\u4e2d\u7684\u5192\u6ce1\u6392\u5e8f\u662f\u8fd9\u6837\u7684\uff1a

void bubble_sort(int *arr, int len) {\n int i, j, tmp;\n for (i = 0; i < len - 1; i++) {\n     for (j = len - 1; j > i; j--) {//Bubble\n         if (arr[j] < arr[j - 1]) {\n             tmp = arr[j];\n             arr[j] = arr[j - 1];\n             arr[j - 1] = tmp;\n         }\n     }\n }\n}\n

\u4e0a\u9762\u8fd9\u6837\u7684\u5199\u6cd5\u5bf9\u4e8e\u4efb\u4f55\u60c5\u51b5\u7684\u590d\u6742\u5ea6\u90fd\u662f \\(O(n^2)\\)\u3002\u4f46\u662f\u5192\u6ce1\u6392\u5e8f\u666e\u904d\u4f1a\u4f5c\u8fd9\u6837\u7684\u4f18\u5316\uff1a

  • \u5982\u679c\u5728\u4e0a\u4e00\u8f6e\u7684 Bubble \u4e2d\uff0c\u6ca1\u6709\u53d1\u751f\u4efb\u4f55\u4ea4\u6362\uff0c\u5219\u8bf4\u660e\u8fd9\u4e2a\u5e8f\u5217\u4e5f\u662f\u6709\u5e8f\u7684\uff0c\u4e0d\u518d\u9700\u8981\u540e\u7eed\u64cd\u4f5c\u4e86\u3002

\u56e0\u6b64\u53ef\u4ee5\u5728\u5916\u5faa\u73af\u5f00\u5934\u6dfb\u52a0 bool flag = 0;\uff0c\u7ed3\u5c3e\u6dfb\u52a0 if(!flag)break;\uff0c\u4ea4\u6362\u64cd\u4f5c\u4e2d\u6dfb\u52a0 flag=true \u5373\u53ef\u5c06\u6700\u4f18\u60c5\u51b5\u4f18\u5316\u81f3 \\(O(n)\\)\u3002

  • \u9009\u62e9\u9898 9 \u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26
  • D \u9879\uff1astatic \u6b64\u5904\u4fee\u9970\u7684\u662f\u6307\u9488 p\u3002\u4e8b\u5b9e\u4e0a\uff0c\u4e5f\u4e0d\u5b58\u5728\u6307\u9488\u6307\u5411 static int \u8fd9\u79cd\u8bf4\u6cd5\u3002static \u4f5c\u4e3a\u5b58\u50a8\u7c7b\u522b\u9650\u5b9a\u7b26\uff0c\u5728\u53d8\u91cf\u7684\u58f0\u660e\u4e2d\u8868\u793a\u8be5\u53d8\u91cf\u5177\u6709\u9759\u6001\u5b58\u50a8\u671f\u3002\u4e00\u4e2a\u6307\u9488\uff0c\u53ea\u9700\u8981\u7ba1\u5b83\u6307\u5411\u7684\u662f\u4ec0\u4e48\u7c7b\u578b\uff0c\u4e0d\u9700\u8981\u77e5\u9053\u8fd9\u4e2a\u5bf9\u8c61\u7684\u5b58\u50a8\u671f\u3002
  • \u7b80\u7b54\u9898 1.(2) \u5199\u51fd\u6570\u58f0\u660e

\u5148\u60f3\u60f3\u81ea\u5df1\u4f1a\u600e\u4e48\u8c03\u7528\u8fd9\u4e2a fun \u51fd\u6570\u624d\u80fd\u5f97\u5230 void \u7c7b\u578b\uff1a

  • \u7b2c\u4e00\u6b65\uff0c\u8c03\u7528\u51fd\u6570\u83b7\u53d6\u8fd4\u56de\u503c\uff1afun(int)\u3002
  • \u7b2c\u4e8c\u6b65\uff0c\u89e3\u5f15\u7528\u8fd4\u56de\u503c\uff0c\u83b7\u5f97\u51fd\u6570\uff0c\u8c03\u7528\u8be5\u51fd\u6570\uff1a(*fun(int))(int)\u3002\u6ce8\u610f\uff0c\u51fd\u6570\u6307\u9488\u5e94\u5f53\u4f7f\u7528 (*fp)() \u5f62\u5f0f\u8c03\u7528\u3002

\u5f97\u5230\u4e86\u7b54\u6848\uff1avoid (*fun(int))(int)\u3002

  • \u7b80\u7b54\u9898 5 \u6700\u5927\u5b50\u5217\u548c

\u5176\u5b9e\u8fd9\u662f\u4e00\u4e2a\u7ecf\u5178\u7684\u7b97\u6cd5\uff1a\u6240\u6709\u8fde\u7eed\u5b50\u5217\u5143\u7d20\u7684\u548c\u4e2d\u6700\u5927\u8005\u3002\u5728\u7f51\u4e0a\u53ef\u4ee5\u641c\u5230\u5f88\u591a\u8be5\u7b97\u6cd5\u7684\u539f\u7406\u4ecb\u7ecd\uff0c\u8bf7\u53bb\u770b\u4e00\u770b\uff0c\u770b\u5b8c\u5c31\u80fd\u7acb\u523b\u660e\u767d\u8fd9\u6bb5\u4ee3\u7801\u4e86\u3002

thisp \u88ab\u653e\u7f6e\u5728\u6700\u5927\u5b50\u5217\u7684\u5f00\u5934\uff0cmaxp \u88ab\u653e\u7f6e\u5728\u6700\u5927\u5b50\u5217\u7684\u672b\u5c3e\u3002

  • \u7b80\u7b54\u9898 6 \u4f8f\u5112\u6392\u5e8f

\u57fa\u4e8e\u6bd4\u8f83\u7684\u6392\u5e8f\u7b97\u6cd5\uff0c\u5927\u6982\u90fd\u80fd\u4f18\u5316\u5230\u6700\u4f18\u60c5\u51b5\u590d\u6742\u5ea6\u4e3a \\(O(n)\\) \u5427\uff1f

  • \u7a0b\u5e8f\u586b\u7a7a 2 \u591a\u9879\u5f0f\u8ba1\u7b97

\u8fd9\u9898\u86ee\u5751\u7684\uff0c\u6211\u770b\u4e86\u597d\u4e00\u4f1a\u513f\u624d\u660e\u767d\u7b2c (7)(8) \u7a7a\u5728\u5e72\u561b\u3002\u5b83\u5176\u5b9e\u5c31\u662f\u5148\u628a\u524d\u9762\u7684\u9ad8\u6b21\u9879\u63d0\u516c\u56e0\u5f0f\uff0c\u7136\u540e\u5728\u9010\u6b65\u5411\u540e\u6c42\u548c\u7684\u8fc7\u7a0b\u7ed9\u5b83\u6574\u4f53\u4e58\u4e0a \\(x\\)\u3002\u6bd4\u5982 \\(3x^4+2x^2+1\\) \u53ef\u4ee5\u8fd9\u6837\u8ba1\u7b97\uff1a

  • \\((((3x)x^2)+2x)x + 1\\)

\u8fd9\u6837\u505a\u4e00\u5b9a\u7a0b\u5ea6\u4e0a\u51cf\u5c11\u4e86\u8ba1\u7b97\u4e58\u79ef\u7684\u6b21\u6570\u3002

\u540c\u6837\u6ce8\u610f -> \u8fd0\u7b97\u7b26\u7684\u4f7f\u7528\u3002

"},{"location":"programming/exam/lectures_on_c_programming/#2016-2017","title":"2016-2017 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 1 \u5012\u5e8f\u6808

\u6ce8\u610f\u9898\u76ee\u4e2d\u8bf4\u660e\u4e86\u6808\u9876\u6307\u9488\u4f4d\u4e8e N\uff0c\u8fd9\u4e2a\u6808\u662f\u4ece\u6570\u7ec4\u7684\u5c3e\u90e8\u5f00\u59cb\u7d2f\u79ef\u7684\u3002

  • \u7b80\u7b54\u9898 1.(2) \u5199\u51fd\u6570\u6307\u9488

\u7b80\u5355\u51fd\u6570\u6307\u9488\uff0c\u76f4\u63a5\u8fd9\u6837\u8bb0\uff1atypedef \u8fd4\u56de\u7c7b\u578b (*\u65b0\u540d\u5b57)(\u53c2\u6570\u5217\u8868)

  • \u7b80\u7b54\u9898 3 \u5947\u5076\u6392\u5e8f

\u548c\u524d\u4e00\u5e74\u7684\u4f8f\u5112\u6392\u5e8f\u6709\u70b9\u50cf\uff0c\u6709\u5e8f\u60c5\u51b5\u4e5f\u662f\u4e00\u904d\u8fc7\uff0c\u6700\u4f18\u65f6\u95f4\u590d\u6742\u5ea6\u4e5f\u662f \\(O(n)\\)\u3002

  • \u7b80\u7b54\u9898 4 \u94fe\u8868\u64cd\u4f5c

\u8fc7\u7a0b\u4e2d\uff0c\u8be5\u94fe\u8868\u987a\u5e8f\u88ab\u91cd\u65b0\u6392\u5217\u3002\u6bd4 x \u5c0f\u7684\u8282\u70b9\u4f9d\u6b21\u79fb\u52a8\u5230 root \u4e3a\u9996\u7684\u5e26\u54e8\u5175\u94fe\u8868\u4e2d\uff0c\u5927\u7684\u4f9d\u6b21\u79fb\u52a8\u5230 pivot \u4e3a\u9996\u7684\u54e8\u5175\u94fe\u8868\u4e2d\uff0c\u6700\u540e\u5c06\u4e24\u4e2a\u94fe\u8868\u5408\u5e76\uff0c\u8fd4\u56de\u5408\u5e76\u540e\u7684\u94fe\u8868\u3002

  • \u7b80\u7b54\u9898 5 \u56e0\u6570\u5206\u89e3

\u672c\u9898\u5176\u5b9e\u5c31\u662f\u5728\u4ece\u5c0f\u5230\u8fbe\u6c42\u56e0\u6570\u3001\u7ea6\u53bb\u8fd9\u4e2a\u56e0\u6570\u3001\u6c42\u4e0b\u4e00\u4e2a\u66f4\u5927\u7684\u56e0\u6570...\u3002\u6a21\u62df\u4e00\u904d\u5373\u53ef\u3002

  • \u7a0b\u5e8f\u586b\u7a7a 1 \u8ba1\u6570\u6392\u5e8f

\u6392\u5e8f\u539f\u7406\u9898\u76ee\u5df2\u7ecf\u8bb2\u6e05\u695a\u4e86\uff0c\u8fd9\u91cc\u8bb2\u4e00\u4e0b\u5faa\u73af\u4e2d\u51e0\u4e2a\u53d8\u91cf\u7684\u4f5c\u7528\uff1a

  • count \u6570\u7ec4\uff1a\u5148\u7528\u4e8e\u7edf\u8ba1\u51fa\u73b0\u6b21\u6570\uff0c\u540e\u7528\u6765\u6807\u8bb0\u5f00\u59cb\u4f4d\u7f6e\u3002
  • output_array[count[input_array[i]]] = input_array[i] \u6211\u4eec\u6765\u62c6\u89e3\u4e00\u4e0b\uff1a
    • intput_array[i] \u5c31\u662f\u7b2c i \u4e2a\u5143\u7d20
    • \u628a\u5b83\u653e\u5230 count[] \u5c31\u80fd\u67e5\u5230\u8fd9\u4e2a\u6570\u5e94\u8be5\u653e\u7f6e\u7684\u8d77\u59cb\u4f4d\u7f6e\u3002
    • \u6240\u4ee5\u7b2c 4 \u7a7a\u5f53\u7136\u8981\u9012\u589e\u5566\u3002
  • \u7a0b\u5e8f\u586b\u7a7a 3 \u5dee\u96c6

\u503c\u5f97\u4e00\u63d0\u7684\u662f\uff0c\u8fd9\u4e24\u4e2a\u94fe\u8868\u90fd\u662f\u96c6\u5408\uff0c\u8fd9\u610f\u5473\u7740\u5176\u4e2d\u7684\u5143\u7d20\u90fd\u662f\u552f\u4e00\u7684\uff0c\u6240\u4ee5\u4e0d\u9700\u8981\u8003\u8651\u91cd\u590d\u5143\u7d20\u7684\u60c5\u51b5\uff0c\u4e0d\u9700\u8981\u5b8c\u6574\u904d\u5386 \\(A\\)\u3002

"},{"location":"programming/exam/lectures_on_c_programming/#2015-2016","title":"2015-2016 \u5e74\u5377","text":"
  • \u9009\u62e9\u9898 5 \u5b8f\u7684\u5c55\u5f00

\u5b8f\u5c55\u5f00\u53ea\u662f\u7b80\u5355\u7684\u6587\u672c\u66ff\u6362\u3002

  • \u5148\u5c55\u5f00 DD \u5f97\u5230 SQ(2*3) - SQ(2+3)\uff0c\u5f97\u5230 2 * 3 * 2 * 3 - 2 + 3 * 2 + 3
  • \u5148\u5c55\u5f00 SQ \u5f97\u5230 DD(x, y) = x * x - y * y\uff0c\u5f97\u5230 2 * 3 * 2 * 3 - 2 + 3 * 2 + 3

\u4ece\u4e0a\u9762\u7684\u5c55\u5f00\u4e2d\u6211\u4eec\u770b\u5230\uff0c\u5b8f\u51fd\u6570\u7684\u5c55\u5f00\u987a\u5e8f\u5e76\u4e0d\u91cd\u8981\u3002\u6700\u7ec8\u7ed3\u679c\u5e94\u5f53\u4e00\u81f4\u3002

"},{"location":"programming_lecture/","title":"\u7a0b\u8bbe\u8f85\u5b66\u8bfe\u7a0b \u7cfb\u7edf\u77e5\u8bc6\u62fe\u9057","text":"

\u6b22\u8fce\u6765\u5230\u7afa\u9662\u7a0b\u8bbe\u8f85\u5b66\u7cfb\u7edf\u77e5\u8bc6\u62fe\u9057\u7248\u5757 \ud83e\udd17\u3002\u4f60\u53ef\u4ee5\u5728\u5de6\u4fa7\u5bfc\u822a\u680f\u4e2d\u8be6\u7ec6\u6d4f\u89c8\u672c\u6a21\u5757\u7684\u5185\u5bb9\u3002

\u672c\u671f\u8bfe\u7a0b

"},{"location":"programming_lecture/#_2","title":"\u8bfe\u7a0b\u7b80\u4ecb","text":"

\u7a0b\u5e8f\u8bbe\u8ba1\u4e0e\u7b97\u6cd5\u57fa\u7840\u8bfe\u7a0b\u8bb2\u8ff0\u7684\u5185\u5bb9\u5c40\u9650\u4e8e\u8bed\u8a00\u672c\u8eab\uff0c\u8f83\u4e3a\u8868\u8c61\u3002\u7136\u800c\uff0cC \u8bed\u8a00\u5b9e\u8d28\u4e0a\u662f\u4e00\u95e8\u5f88\u96be\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u4e0d\u61c2\u7f16\u8bd1\u539f\u7406\u3001\u64cd\u4f5c\u7cfb\u7edf\u548c\u8ba1\u7b97\u673a\u4f53\u7cfb\u7ed3\u6784\u65e0\u6cd5\u83b7\u5f97\u6df1\u5165\u7684\u7406\u89e3\uff0c\u800c\u8fd9\u4e9b\u4e5f\u662f\u5b66\u4e60\u8ba1\u7b97\u673a\u4e13\u4e1a\u7684\u540c\u5b66\u5e94\u5f53\u5c3d\u65e9\u4e86\u89e3\u7684\u77e5\u8bc6\u3002

\u672c\u8f85\u5b66\u8bfe\u7a0b\u5c06\u7ed3\u5408\u8ba1\u7b97\u673a\u7cfb\u7edf\u65b9\u9762\u7684\u77e5\u8bc6\uff0c\u4e3a\u540c\u5b66\u4eec\u63d0\u4f9b\u6df1\u5165\u7406\u89e3 C \u8bed\u8a00\u7684\u89c6\u89d2\u3002\u6211\u4eec\u7684\u76ee\u7684\u662f\u89e3\u7b54\u7a0b\u5e8f\u8bbe\u8ba1\u4e2d\u8f83\u4e3a\u5e95\u5c42\u7684\u95ee\u9898\uff1a

  • \u7f16\u8bd1\u65f6\u6211\u7684\u4ee3\u7801\u7ecf\u5386\u4e86\u4ec0\u4e48\uff1f\u64cd\u4f5c\u7cfb\u7edf\u5982\u4f55\u8fd0\u884c\u6211\u7684\u7a0b\u5e8f\uff1f\u5982\u4f55\u4f7f\u7528\u8c03\u8bd5\u5668\u5feb\u901f\u5b9a\u4f4d\u9519\u8bef\uff1f
  • \u6307\u9488\u7a76\u7adf\u662f\u4ec0\u4e48\uff1f\u5185\u5b58\u4e2d\u7684\u6570\u636e\u662f\u5982\u4f55\u7ec4\u7ec7\u7684\uff1f
  • C \u6807\u51c6\u5e93\u4e2d\u7684 I/O \u51fd\u6570\u5982\u4f55\u4e0e\u64cd\u4f5c\u7cfb\u7edf\u4ea4\u4e92\uff1f
  • C \u6807\u51c6\u5e93\u662f\u5982\u4f55\u7f16\u5199\u7684\uff1f\u600e\u6837\u5199\u51fa\u5177\u6709\u5de5\u4e1a\u5f3a\u5ea6\u7684\u5065\u58ee\u4ee3\u7801\uff1f
  • \u5982\u4f55\u4f7f\u7528\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u89e3\u51b3\u5b9e\u9645\u95ee\u9898\uff1f

\u5e0c\u671b\u8fd9\u4e9b\u5185\u5bb9\u80fd\u591f\u4e3a\u4f60\u5f00\u542f\u4ece C \u8bed\u8a00\u5230\u8ba1\u7b97\u673a\u79d1\u5b66\u4e0e\u6280\u672f\u7684\u771f\u6b63\u7684\u5927\u95e8\u3002\u5982\u679c\u5bf9\u8bfe\u7a0b\u5185\u5bb9\u6709\u4efb\u4f55\u7591\u95ee\u548c\u5efa\u8bae\uff0c\u6b22\u8fce\u4f60\u8054\u7cfb\u6211\u4eec\u3002\u4f60\u53ef\u4ee5\u5728\u4ed3\u5e93\u4e2d\u53d1\u8d77 issue \u6216\u53d1\u9001\u90ae\u4ef6\u5230 zhubaolin228@gmail.com\u3002

"},{"location":"programming_lecture/#_3","title":"\u8bfe\u7a0b\u5b89\u6392","text":"

2023-2024 \u5b66\u5e74\uff0c\u7a0b\u8bbe\u8f85\u5b66\u7cfb\u7edf\u77e5\u8bc6\u62fe\u9057\u8bfe\u9898\u7ec4\u540c\u5b66\u6709\uff1a

  • \u6731\u5b9d\u6797 \u6df7\u5408 2205
  • \u674e\u82f1\u7426 \u56fe\u7075 2201
  • \u8c22\u96c6 \u6df7\u5408 2206
  • \u80e1\u80b2\u73ae \u6df7\u5408 2206
  • \u82cf\u715c\u7a0b \u56fe\u7075 2201
  • \u5b59\u5146\u6c5f \u6df7\u5408 2204

\u8bfe\u7a0b\u5b89\u6392\u5982\u4e0b\uff1a

\u8282\u6b21 \u5185\u5bb9 \u4e3b\u8bb2 \u65f6\u95f4 \u5730\u70b9 \u8bfe\u524d\u8d44\u6599 PPT \u4e0e\u8bb2\u4e49 1 \u7a0b\u5e8f\u7f16\u8bd1\u8fc7\u7a0b\u4e0e\u8c03\u8bd5\u6280\u672f \u6731\u5b9d\u6797 10.14 \u4e0b\u5348 2:30-4:30 \u51c6\u5907\u5f00\u53d1\u4e0e\u8c03\u8bd5\u73af\u5883 \u8bb2\u4e49 2 \u7c7b\u578b\u7cfb\u7edf\u4e0e\u5185\u5b58\u6a21\u578b \u674e\u82f1\u7426 \u3010\u6682\u5b9a\u301110.21 3 I/O \u4e0e\u6587\u4ef6 \u80e1\u80b2\u73ae \u3010\u6682\u5b9a\u301111.18 4 C \u6807\u51c6\u5e93 \u674e\u82f1\u7426 \u3010\u6682\u5b9a\u301111.25 5 \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 \u8c22\u96c6\u82cf\u715c\u7a0b \u3010\u6682\u5b9a\u301112.15"},{"location":"programming_lecture/lecture1/lecture1/","title":"\u8bb2\u4e49\uff1a\u7a0b\u5e8f\u7f16\u8bd1\u8fc7\u7a0b\u4e0e\u8c03\u8bd5\u6280\u672f","text":"\u672c\u9875\u9762\u6b63\u5728\u65bd\u5de5\u4e2d \u5185\u5bb9\u63d0\u8981
  • C \u8bed\u8a00\u7a0b\u5e8f\u57fa\u672c\u7ed3\u6784
  • \u7f16\u8bd1\u8fc7\u7a0b\uff1a\u4ece\u6e90\u4ee3\u7801\u5230\u53ef\u6267\u884c\u6587\u4ef6
  • \u7f16\u8bd1\u5668\u548c\u5f00\u53d1\u5957\u4ef6\uff1agcc\u3001clang \u548c llvm \u7a76\u7adf\u662f\u4ec0\u4e48\uff1f
  • \u8c03\u8bd5\u5668\uff1a\u5982\u4f55\u4f7f\u7528 gdb \u6216 lldb \u8bbe\u7f6e\u65ad\u70b9\u3001\u627e\u5230\u6bb5\u9519\u8bef\u7684\u6839\u6e90\uff1f
\u5982\u4f55\u98df\u7528\u672c\u8bb2\u4e49

\u4f5c\u4e3a\u5728\u7ebf\u8bb2\u4e49\uff0c\u6211\u4f1a\u5c3d\u91cf\u5199\u5f97\u8be6\u7ec6\u4e00\u4e9b\uff0c\u4e3a\u540c\u5b66\u4eec\u63d0\u4f9b\u590d\u4e60\u548c\u8fdb\u4e00\u6b65\u6269\u5c55\u7684\u6307\u5f15\u3002\u56e0\u4e3a\u65f6\u95f4\u6709\u9650\uff0c\u5728\u8bfe\u4e0a\u6211\u65e0\u6cd5\u8986\u76d6\u8bb2\u4e49\u4e2d\u6240\u6709\u7684\u5185\u5bb9\u3002\u540c\u5b66\u4eec\u53ef\u4ee5\u6839\u636e\u81ea\u5df1\u7684\u4e60\u60ef\u9009\u62e9\u5728\u8bfe\u524d\u8bfe\u540e\u6d4f\u89c8\u672c\u8bb2\u4e49\uff5e

\u672c\u6b21\u8bfe\u7684\u6838\u5fc3\u5185\u5bb9\u4ece\u300c\u7a0b\u5e8f\u7684\u7f16\u8bd1\u8fc7\u7a0b\u300d\u5f00\u59cb\u3002\u524d\u9762\u7684\u5185\u5bb9\u4f5c\u4e3a\u9884\u5907\u77e5\u8bc6\uff0c\u5728\u8bfe\u4e0a\u5c06\u4f1a\u5feb\u901f\u5e26\u8fc7\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_2","title":"\u8bfe\u7a0b\u5bfc\u8a00","text":"

Hi\uff0c\u6b22\u8fce\u5404\u4f4d\u540c\u5b66\u6765\u5230\u7afa\u9662\u7a0b\u8bbe\u8f85\u5b66\u300c\u7cfb\u7edf\u77e5\u8bc6\u62fe\u9057\u300d\u7684\u7b2c\u4e00\u8282\u8bfe\u3002

\u5728\u524d\u51e0\u5468\u7684\u7a0b\u5e8f\u8bbe\u8ba1\u8bfe\u7a0b\u4e2d\uff0c\u8001\u5e08\u4eec\u5e94\u8be5\u5df2\u7ecf\u4e3a\u540c\u5b66\u4eec\u8bb2\u89e3\u4e86 C \u8bed\u8a00\u7684\u57fa\u7840\u8bed\u6cd5\u7b49\u77e5\u8bc6\u3002\u4f46\u662f\u540c\u5b66\u4eec\u6216\u8bb8\u4f1a\u6709\u4e0b\u9762\u8fd9\u4e9b\u7591\u95ee\uff1a

  • \u8ba1\u7b97\u673a\u662f\u5982\u4f55\u8bfb\u61c2\u6211\u5199\u7684\u4ee3\u7801\u7684\uff1f
  • \u6211\u7684\u7a0b\u5e8f\u603b\u662f\u51fa\u95ee\u9898\uff0c\u6211\u8be5\u5982\u4f55\u5feb\u901f\u627e\u5230\u9519\u8bef\u7684\u6839\u6e90\uff1f

\u8f85\u5b66\u8bfe\u7a0b\u7684\u76ee\u7684\u5c31\u662f\u5e2e\u52a9\u540c\u5b66\u4eec\u89e3\u51b3\u8fd9\u4e9b\u8fdb\u4e00\u6b65\u7684\u95ee\u9898\u3002\u5b9e\u8d28\u4e0a C \u8bed\u8a00\u662f\u4e00\u95e8\u5f88\u96be\u7684\u7f16\u7a0b\u8bed\u8a00\uff0c\u4e0d\u61c2\u7f16\u8bd1\u539f\u7406\u3001\u64cd\u4f5c\u7cfb\u7edf\u548c\u8ba1\u7b97\u673a\u4f53\u7cfb\u7ed3\u6784\u65e0\u6cd5\u83b7\u5f97\u6df1\u5165\u7684\u7406\u89e3\u3002\u6211\u4eec\u5e0c\u671b\u901a\u8fc7\u7ebf\u4e0b\u6388\u8bfe\uff0c\u4e3a\u540c\u5b66\u4eec\u63d0\u4f9b\u8bed\u8a00\u4e4b\u5916\u7684\u8fdb\u4e00\u6b65\u7684\u77e5\u8bc6\u6269\u5c55\u548c\u6280\u80fd\u8bad\u7ec3\u3002\u8ba9\u540c\u5b66\u4eec\u5728\u8ba1\u7b97\u673a\uff08\u800c\u975e\u7b97\u6cd5\u9898\uff09\u7684\u8bed\u5883\u4e0b\u7406\u89e3 C \u8bed\u8a00\uff0c\u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u3002

\u90a3\u4e48\u5728\u672c\u8282\u8bfe\uff0c\u6211\u4eec\u5c06\u4e3a\u5927\u5bb6\u7cfb\u7edf\u8bb2\u89e3\u7a0b\u5e8f\u7f16\u8bd1\u8fc7\u7a0b\u4e0e\u8c03\u8bd5\u6280\u672f\uff0c\u4e3a\u540e\u7eed\u7684\u8bfe\u7a0b\u505a\u94fa\u57ab\u3002\u63a5\u4e0b\u6765\uff0c\u8ba9\u6211\u4eec\u4e00\u8d77\u8fdb\u5165\u8ba1\u7b97\u673a\u7684\u4e16\u754c\u5427\uff01

"},{"location":"programming_lecture/lecture1/lecture1/#_3","title":"\u57fa\u7840\u77e5\u8bc6","text":"

\u9996\u5148\uff0c\u6211\u4eec\u6765\u4e86\u89e3\u4e00\u4e0b\u6211\u4eec\u5b66\u4e60\u7684\u5bf9\u8c61\u2014\u2014\u8ba1\u7b97\u673a\u7684\u57fa\u672c\u77e5\u8bc6\u3002\u5b83\u662f\u5982\u4f55\u5de5\u4f5c\u7684\uff1f\u6211\u4eec\u5982\u4f55\u4e0e\u5b83\u4ea4\u6d41\uff1f

"},{"location":"programming_lecture/lecture1/lecture1/#_4","title":"\u8ba1\u7b97\u673a\u80fd\u505a\u4ec0\u4e48\uff1f","text":"

\u73b0\u4ee3\u8ba1\u7b97\u673a\u7531\u591a\u79cd\u90e8\u4ef6\u6784\u6210\uff0c\u6bd4\u5982\u4e2d\u592e\u5904\u7406\u5355\u5143\uff08Central Processing Unit\uff0cCPU\uff09\u3001\u968f\u673a\u5b58\u53d6\u5185\u5b58\uff08Random Access Memory\uff0cRAM\uff09\u3001\u786c\u76d8\uff08Hard Disk\uff09\u7b49\u3002\u5176\u4e2d CPU \u8d1f\u8d23\u5904\u7406\u7a0b\u5e8f\u3002

RISC CPU

\u8fd9\u662f\u4e00\u4e2a\u975e\u5e38\u7b80\u5355\u7684 CPU \u7684\u7535\u8def\uff0c\u5b83\u80fd\u591f\u6267\u884c\u4f60\u7528 0 \u548c 1 \u7f16\u5199\u7684\u673a\u5668\u6307\u4ee4\u3002

CPU \u57fa\u672c\u7ed3\u6784

CPU \u4e3b\u8981\u7531\u63a7\u5236\u5355\u5143\u3001\u7b97\u672f\u903b\u8f91\u5355\u5143\u548c\u5bc4\u5b58\u5668\u7ec4\u6210\u3002\u63a7\u5236\u5355\u5143\u4e2d\u6709\u7a0b\u5e8f\u8ba1\u6570\u5668\u548c\u6307\u4ee4\u5bc4\u5b58\u5668\u3002

  • CPU \u80fd\u8bfb\u61c2\u4ec0\u4e48\uff1f

CPU \u65e0\u6cd5\u76f4\u63a5\u8bfb\u61c2\u4f60\u5199\u7684 C \u8bed\u8a00\u4ee3\u7801\uff0c\u5b83\u662f\u7531\u6570\u5b57\u7535\u8def\u6784\u6210\u7684\u3002\u6570\u5b57\u7535\u8def\u53ea\u80fd\u5904\u7406 0 \u548c 1\uff0c\u56e0\u6b64\u8ba1\u7b97\u673a\u4e2d\u7684\u4efb\u4f55\u6570\u636e\u90fd\u5fc5\u987b\u4f7f\u7528\u4e8c\u8fdb\u5236\u8868\u793a\uff0c\u7a0b\u5e8f\u4e5f\u662f\u5982\u6b64\u3002

\u5728\u8ba1\u7b97\u673a\u521a\u521a\u8bde\u751f\u7684\u9636\u6bb5\uff0c\u5de5\u7a0b\u5e08\u4eec\u4e0d\u5f97\u4e0d\u4f7f\u7528 0 \u548c 1 \u6784\u6210\u7684\u6307\u4ee4\u5e8f\u5217\u548c\u8ba1\u7b97\u673a\u6253\u4ea4\u9053\uff0c\u8fd9\u5c31\u662f\u673a\u5668\u8bed\u8a00\u3002\u56e0\u4e3a\u5177\u4f53\u7535\u8def\u8bbe\u8ba1\u4e0d\u540c\uff0c\u6bcf\u79cd CPU \u6240\u80fd\u7406\u89e3\u7684\u6307\u4ee4\u6709\u9650\uff0c\u8fd9\u4e9b\u6307\u4ee4\u7684\u96c6\u5408\u53eb\u505a\u6307\u4ee4\u96c6\u3002

  • CPU \u90fd\u505a\u4e9b\u4ec0\u4e48\uff1f

CPU \u7684\u5de5\u4f5c\u975e\u5e38\u7b80\u5355\uff1a\u4ece\u5185\u5b58\u4e2d\u8bfb\u53d6\u5e76\u6267\u884c\u4e00\u6761\u6307\u4ee4\uff0c\u518d\u4ece\u5185\u5b58\u4e2d\u8bfb\u53d6\u5e76\u6267\u884c\u4e0b\u4e00\u6761\u6307\u4ee4\u2026\u20261 GHz \u7684 CPU \u6bcf\u79d2\u80fd\u91cd\u590d\u8fd9\u4e00\u64cd\u4f5c\u7ea6\u5341\u4ebf\u6b21\u3002

\u8fd9\u4e9b\u6307\u4ee4\u90fd\u76f8\u5f53\u5177\u4f53\uff0c\u6bd4\u5982\u628a\u4e00\u4e2a\u6570\u5b57\u4ece\u4e00\u4e2a\u4f4d\u7f6e\u79fb\u52a8\u5230\u53e6\u4e00\u4e2a\u4f4d\u7f6e\uff0c\u628a\u4e24\u4e2a\u6570\u5b57\u76f8\u52a0\u5e76\u628a\u7ed3\u679c\u5b58\u50a8\u518d\u67d0\u4e2a\u5730\u65b9\u3002\u662f\u7684\uff0c\u4f60\u7684 CPU \u4e5f\u5728\u75af\u72c2\u505a\u7740\u8fd9\u4e9b\u4e8b\u60c5\u3002\u4f46\u662f\u901a\u8fc7\u7cbe\u5de7\u7684\u8bbe\u8ba1\uff0c\u8fd9\u4e9b\u7b80\u5355\u7684\u6307\u4ee4\u5c31\u80fd\u6784\u5efa\u8d77\u7a0b\u5e8f\u7684\u63a7\u5236\u903b\u8f91\uff0c\u5b9e\u73b0\u590d\u6742\u7684\u529f\u80fd\u3002

CPU \u8fd8\u6709\u81ea\u5df1\u7684\u5c0f\u5de5\u4f5c\u533a\u2014\u2014\u7531\u82e5\u5e72\u5bc4\u5b58\u5668\uff08Register\uff09\u7ec4\u6210\u7684\u5bc4\u5b58\u5668\u7ec4\u3002\u6bcf\u4e2a\u5bc4\u5b58\u5668\u80fd\u5b58\u50a8\u4e00\u4e2a\u6570\u5b57\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_5","title":"\u4ece\u673a\u5668\u8bed\u8a00\u3001\u6c47\u7f16\u8bed\u8a00\u5230\u9ad8\u7ea7\u8bed\u8a00","text":"

\u73b0\u4ee3\u8ba1\u7b97\u673a\u7684\u7ed3\u6784\u4e0e 70 \u5e74\u524d\u5e76\u6ca1\u6709\u672c\u8d28\u4e0a\u7684\u4e0d\u540c\uff0c\u4f46\u662f\u7a0b\u5e8f\u8bbe\u8ba1\u8bed\u8a00\u53d6\u5f97\u4e86\u5f88\u5927\u7684\u53d1\u5c55\uff0c\u4ea7\u751f\u4e86\u6c47\u7f16\u8bed\u8a00\u548c\u9ad8\u7ea7\u8bed\u8a00\u3002\u6211\u4eec\u4ecd\u7136\u4e0d\u80fd\u76f4\u63a5\u5bf9 CPU \u8bf4\uff1a\u4e3a\u6211\u8ba1\u7b97 \\(1 + 1\\)\uff0c\u4f46\u6211\u4eec\u53ef\u4ee5\u7528\u9ad8\u7ea7\u8bed\u8a00\u7b80\u6d01\u7684\u8868\u8fbe\u5b83\uff0c\u8ba9\u7f16\u8bd1\u5668\uff08compiler\uff09\u548c\u6c47\u7f16\u5668\uff08assembler\uff09\u5c06\u5176\u7ffb\u8bd1\u6210 0101 \u7684\u673a\u5668\u8bed\u8a00\u3002\u4e0b\u56fe\u5c55\u793a\u4e86\u7a0b\u5e8f\u8bbe\u8ba1\u8bed\u8a00\u7684\u53d1\u5c55\u5386\u53f2\uff0c\u7f16\u8bd1\u8fc7\u7a0b\u5176\u5b9e\u5c31\u662f\u8fd9\u4e00\u5386\u53f2\u7684\u53cd\u5411\u3002

\u673a\u5668\u8bed\u8a00 Machine Code

\u8fd9\u662f\u7b2c\u4e00\u4ee3\u7f16\u7a0b\u8bed\u8a00\uff0c\u4e5f\u662f\u8ba1\u7b97\u673a\u552f\u4e00\u80fd\u8bc6\u522b\u7684\u8bed\u8a00\u3002\u4e0a\u56fe\u5c55\u793a\u4e86\u4e16\u754c\u4e0a\u7b2c\u4e00\u4e2a\u8ba1\u7b97\u673a\u7a0b\u5e8f\uff0c\u5b83\u7528\u6765\u627e\u51fa\u4e00\u4e2a\u6570\u6700\u5927\u7684\u56e0\u6570\u3002

\u6c47\u7f16\u8bed\u8a00 Assembly Language

\u8fd9\u662f\u7b2c\u4e8c\u4ee3\u7f16\u7a0b\u8bed\u8a00\uff0c\u5176\u5b9e\u5c31\u662f\u673a\u5668\u8bed\u8a00\u7684\u52a9\u8bb0\u7b26\u3002\u5b83\u4f7f\u5f97\u7a0b\u5e8f\u5458\u4e0d\u7528\u518d\u76f4\u63a5\u4e0e 0 \u548c 1 \u6253\u4ea4\u9053\uff0c\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u4e5f\u66f4\u5f3a\u4e86\u3002\u4e0a\u56fe\u663e\u793a\u4e86\u5c06\u4e24\u4e2a\u6574\u6570\u76f8\u52a0\u7684\u6c47\u7f16\u4ee3\u7801\u3002

\u9ad8\u7ea7\u8bed\u8a00 High-level Language

\u8fd9\u662f\u7b2c\u4e09\u4ee3\u7f16\u7a0b\u8bed\u8a00\uff0c\u5b83\u8ba9\u7a0b\u5e8f\u5458\u4eec\u4e0d\u7528\u518d\u5173\u6ce8\u8ba1\u7b97\u673a\u7ed3\u6784\u4e0a\u7684\u7ec6\u8282\uff0c\u800c\u662f\u5c06\u6ce8\u610f\u529b\u8f6c\u79fb\u5230\u8981\u89e3\u51b3\u7684\u95ee\u9898\u4e0a\u6765\u3002

\u4e0b\u9762\u4e09\u884c\u4ee3\u7801\u5206\u522b\u662f\u7528 C \u8bed\u8a00\u3001\u6c47\u7f16\u8bed\u8a00\u548c\u673a\u5668\u8bed\u8a00\uff08\u5341\u516d\u8fdb\u5236\uff09\u63cf\u8ff0\u7684\u540c\u4e00\u4ef6\u4e8b\uff1a

\u7b80\u5355\u7684\u4f8b\u5b50\u590d\u6742\u7684\u4f8b\u5b50
c = a + b;\n
add $t0, $t1, $t2\n
01 2a 40 20\n
void multstore(long x, long y, long *dest) {\n    long t = mult2(x, y);\n    *dest = t;\n}\n
multstore:\n    pushq   %rbx\n    movq    %rdx, %rbx\n    call    mult2\n    movq    %rax, (%rbx)\n    popq    %rbx\n    ret\n
53 48 89 d3 48 83 ec 08 e8 00 00 00 00 48 89 03 5b c3\n
\u4e3a\u4ec0\u4e48\u9700\u8981\u9ad8\u7ea7\u8bed\u8a00\uff1f
  1. \u673a\u5668\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u90fd\u662f\u975e\u5e38\u5e95\u5c42\u7684\u8bed\u8a00\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u5173\u6ce8\u8ba1\u7b97\u673a\u7684\u7ec6\u8282\uff0c\u8fd9\u4f7f\u5f97\u7a0b\u5e8f\u7684\u53ef\u8bfb\u6027\u5f88\u5dee\u3002\u4f7f\u7528\u9ad8\u7ea7\u8bed\u8a00\uff0c\u7a0b\u5e8f\u5458\u80fd\u5c06\u6ce8\u610f\u529b\u8f6c\u79fb\u5230\u8981\u89e3\u51b3\u7684\u95ee\u9898\u4e0a\u6765\u3002
  2. \u673a\u5668\u8bed\u8a00\u548c\u6c47\u7f16\u8bed\u8a00\u90fd\u662f\u4e0e\u5177\u4f53 CPU \u76f8\u5173\u7684\uff0c\u7a0b\u5e8f\u5458\u9700\u8981\u4e3a\u4e0d\u540c\u7684 CPU \u7f16\u5199\u4e0d\u540c\u7684\u7a0b\u5e8f\uff0c\u53ef\u79fb\u690d\u6027\u5dee\u3002\u4f7f\u7528\u9ad8\u7ea7\u8bed\u8a00\uff0c\u7a0b\u5e8f\u5458\u53ea\u9700\u8981\u5199\u4e00\u6b21\u7a0b\u5e8f\uff0c\u518d\u4f7f\u7528\u7f16\u8bd1\u5668\u5c31\u80fd\u5c06\u5176\u7ffb\u8bd1\u6210\u80fd\u5728\u7279\u5b9a CPU \u7684\u673a\u5668\u8bed\u8a00\u3002
\u524d\u77bb\uff1a\u7b2c\u56db\u4ee3\u548c\u7b2c\u4e94\u4ee3\u7f16\u7a0b\u8bed\u8a00

\u7f16\u7a0b\u8bed\u8a00\u4ecd\u5728\u53d1\u5c55\u6f14\u5316\u3002\u76ee\u524d\u5df2\u7ecf\u6709\u4e86\u7b2c\u56db\u4ee3\u548c\u7b2c\u4e94\u4ee3\u7f16\u7a0b\u8bed\u8a00\u7684\u6982\u5ff5\u3002\u7b2c\u4e09\u4ee3\u7684\u7f16\u7a0b\u8bed\u8a00\u867d\u7136\u662f\u7528\u8bed\u53e5\u7f16\u7a0b\u800c\u4e0d\u76f4\u63a5\u7528\u6307\u4ee4\u7f16\u7a0b\uff0c\u4f46\u8bed\u53e5\u4e5f\u5206\u4e3a\u8f93\u5165\u3001\u8f93\u51fa\u3001\u57fa\u672c\u8fd0\u7b97\u3001\u6d4b\u8bd5\u5206\u652f\u548c\u5faa\u73af\u7b49\u51e0\u79cd\uff0c\u548c\u6307\u4ee4\u6709\u76f4\u63a5\u7684\u5bf9\u5e94\u5173\u7cfb\u3002\u800c\u7b2c\u56db\u4ee3\u4ee5\u540e\u7684\u7f16\u7a0b\u8bed\u8a00\u66f4\u591a\u662f\u63cf\u8ff0\u8981\u505a\u4ec0\u4e48\uff08Declarative\uff09\u800c\u4e0d\u63cf\u8ff0\u5177\u4f53\u4e00\u6b65\u4e00\u6b65\u600e\u4e48\u505a\uff08Imperative\uff09\uff0c\u5177\u4f53\u4e00\u6b65\u4e00\u6b65\u600e\u4e48\u505a\u5b8c\u5168\u7531\u7f16\u8bd1\u5668\u6216\u89e3\u91ca\u5668\u51b3\u5b9a\uff0c\u4f8b\u5982SQL\u8bed\u8a00\uff08SQL\uff0cStructured Query Language\uff0c\u7ed3\u6784\u5316\u67e5\u8be2\u8bed\u8a00\uff09\u5c31\u662f\u8fd9\u6837\u7684\u4f8b\u5b50\u3002

\u5bf9\u673a\u5668\u8bed\u8a00\u6709\u5174\u8da3\uff1f

\u8fd9\u91cc\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5c06\u6c47\u7f16\u8bed\u8a00\u8f6c\u6362\u4e3a MIPS \u6307\u4ee4\u96c6\u673a\u5668\u8bed\u8a00\u7684\u57fa\u7840\u4f8b\u5b50\uff0c\u6709\u5174\u8da3\u53ef\u4ee5\u4e86\u89e3\u4e00\u4e0b\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_6","title":"\u7a0b\u5e8f\u7684\u57fa\u672c\u8bed\u6cd5\u7ed3\u6784","text":"

\u7ecf\u8fc7\u4e86 2-3 \u5468\u8bfe\u7a0b\u7684\u5b66\u4e60\uff0c\u76f8\u4fe1\u540c\u5b66\u4eec\u591a\u5c11\u90fd\u5199\u8fc7\u4e86\u4e00\u4e9b\u4ee3\u7801\uff0c\u5bf9\u8bed\u8a00\u6709\u4e86\u4e00\u4e9b\u57fa\u672c\u8ba4\u8bc6\u3002\u672c\u8282\u5c06\u7cfb\u7edf\u5730\u68b3\u7406\u7a0b\u5e8f\u7684\u8bed\u6cd5\u548c\u7ed3\u6784\u77e5\u8bc6\uff0c\u5e2e\u52a9\u5927\u5bb6\u7406\u6e05\u601d\u8def\uff0c\u4e3a\u540e\u7eed\u7406\u89e3\u7a0b\u5e8f\u7f16\u8bd1\u8fc7\u7a0b\u548c\u8c03\u8bd5\u6280\u672f\u4f5c\u94fa\u57ab\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_7","title":"\u5199\u7a0b\u5e8f\u7684\u76ee\u6807\u662f\u4ec0\u4e48\uff1f","text":"

\u4ece\u6839\u672c\u4e0a\u8bf4\uff0c\u8ba1\u7b97\u673a\u662f\u7531\u6570\u5b57\u7535\u8def\u7ec4\u6210\u7684\u8fd0\u7b97\u673a\u5668\uff0c\u53ea\u80fd\u5bf9\u6570\u5b57\u505a\u8fd0\u7b97\uff0c\u7a0b\u5e8f\u4e4b\u6240\u4ee5\u80fd\u505a\u7b26\u53f7\u8fd0\u7b97\uff0c\u662f\u56e0\u4e3a\u7b26\u53f7\u5728\u8ba1\u7b97\u673a\u5185\u90e8\u4e5f\u662f\u7528\u6570\u5b57\u8868\u793a\u7684\u3002\u6b64\u5916\uff0c\u7a0b\u5e8f\u8fd8\u53ef\u4ee5\u5904\u7406\u58f0\u97f3\u548c\u56fe\u50cf\uff0c\u58f0\u97f3\u548c\u56fe\u50cf\u5728\u8ba1\u7b97\u673a\u5185\u90e8\u5fc5\u7136\u4e5f\u662f\u7528\u6570\u5b57\u8868\u793a\u7684\uff0c\u8fd9\u4e9b\u6570\u5b57\u7ecf\u8fc7\u4e13\u95e8\u7684\u786c\u4ef6\u8bbe\u5907\u8f6c\u6362\u6210\u4eba\u53ef\u4ee5\u542c\u5230\u3001\u770b\u5230\u7684\u58f0\u97f3\u548c\u56fe\u50cf\u3002

\u7a0b\u5e8f\u7531\u4e00\u7cfb\u5217\u6307\u4ee4\uff08Instruction\uff09\u7ec4\u6210\uff0c\u6307\u4ee4\u662f\u6307\u793a\u8ba1\u7b97\u673a\u505a\u67d0\u79cd\u8fd0\u7b97\u7684\u547d\u4ee4\uff0c\u901a\u5e38\u5305\u62ec\u4ee5\u4e0b\u51e0\u7c7b\uff1a

  • \u8f93\u5165\uff08Input\uff09\uff1a\u4ece\u952e\u76d8\u3001\u6587\u4ef6\u6216\u8005\u5176\u5b83\u8bbe\u5907\u83b7\u53d6\u6570\u636e\u3002
  • \u8f93\u51fa\uff08Output\uff09\uff1a\u628a\u6570\u636e\u663e\u793a\u5230\u5c4f\u5e55\uff0c\u6216\u8005\u5b58\u5165\u4e00\u4e2a\u6587\u4ef6\uff0c\u6216\u8005\u53d1\u9001\u5230\u5176\u5b83\u8bbe\u5907\u3002
  • \u57fa\u672c\u8fd0\u7b97\uff1a\u6267\u884c\u6700\u57fa\u672c\u7684\u6570\u5b66\u8fd0\u7b97\uff08\u52a0\u51cf\u4e58\u9664\uff09\u548c\u6570\u636e\u5b58\u53d6\u3002
  • \u6d4b\u8bd5\u548c\u5206\u652f\uff1a\u6d4b\u8bd5\u67d0\u4e2a\u6761\u4ef6\uff0c\u7136\u540e\u6839\u636e\u4e0d\u540c\u7684\u6d4b\u8bd5\u7ed3\u679c\u6267\u884c\u4e0d\u540c\u7684\u540e\u7eed\u6307\u4ee4\u3002
  • \u5faa\u73af\uff1a\u91cd\u590d\u6267\u884c\u4e00\u7cfb\u5217\u64cd\u4f5c\u3002

\u5bf9\u4e8e\u7a0b\u5e8f\u6765\u8bf4\uff0c\u6709\u4e0a\u9762\u8fd9\u51e0\u7c7b\u6307\u4ee4\u5c31\u8db3\u591f\u4e86\u3002\u4f60\u66fe\u7528\u8fc7\u7684\u4efb\u4f55\u4e00\u4e2a\u7a0b\u5e8f\uff0c\u4e0d\u7ba1\u5b83\u6709\u591a\u4e48\u590d\u6742\uff0c\u90fd\u662f\u7531\u8fd9\u51e0\u7c7b\u6307\u4ee4\u7ec4\u6210\u7684\u3002\u7a0b\u5e8f\u662f\u90a3\u4e48\u7684\u590d\u6742\uff0c\u800c\u7f16\u5199\u7a0b\u5e8f\u53ef\u4ee5\u7528\u7684\u6307\u4ee4\u5374\u53ea\u6709\u8fd9\u4e48\u7b80\u5355\u7684\u51e0\u79cd\uff0c\u8fd9\u4e2d\u95f4\u5de8\u5927\u7684\u843d\u5dee\u5c31\u8981\u7531\u7a0b\u5e8f\u5458\u53bb\u586b\u4e86\uff0c\u6240\u4ee5\u7f16\u5199\u7a0b\u5e8f\u7406\u5e94\u662f\u4e00\u4ef6\u76f8\u5f53\u590d\u6742\u7684\u5de5\u4f5c\u3002\u7f16\u5199\u7a0b\u5e8f\u53ef\u4ee5\u8bf4\u5c31\u662f\u8fd9\u6837\u4e00\u4e2a\u8fc7\u7a0b\uff1a\u628a\u590d\u6742\u7684\u4efb\u52a1\u5206\u89e3\u6210\u5b50\u4efb\u52a1\uff0c\u628a\u5b50\u4efb\u52a1\u518d\u5206\u89e3\u6210\u66f4\u7b80\u5355\u7684\u4efb\u52a1\uff0c\u5c42\u5c42\u5206\u89e3\uff0c\u76f4\u5230\u6700\u540e\u7b80\u5355\u5f97\u53ef\u4ee5\u7528\u4ee5\u4e0a\u6307\u4ee4\u6765\u5b8c\u6210\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_8","title":"\u8bcd\u6cd5\u548c\u8bed\u6cd5\u89c4\u5219","text":"

\u8bcd\u6cd5\uff08Lexical\uff09\u548c\u8bed\u6cd5\uff08Syntax\uff09\u662f\u7f16\u7a0b\u8bed\u8a00\u7684\u4e24\u4e2a\u57fa\u672c\u6982\u5ff5\u3002\u8bcd\u6cd5\u89c4\u5219\u5b9a\u4e49\u4e86\u7f16\u7a0b\u8bed\u8a00\u4e2d\u7684\u57fa\u672c\u7b26\u53f7\uff0c\u8bed\u6cd5\u89c4\u5219\u5b9a\u4e49\u4e86\u8fd9\u4e9b\u7b26\u53f7\u5982\u4f55\u7ec4\u6210\u5408\u6cd5\u7684\u8868\u8fbe\u5f0f\u3001\u8bed\u53e5\u548c\u7a0b\u5e8f\u3002

C \u7684\u8bcd\u6cd5\u89c4\u5219\uff1a\u8d2a\u5fc3\u6cd5

\u672f\u8bed token \uff08\u7b26\u53f7\uff09\u662f\u8bed\u8a00\u7684\u57fa\u672c\u8868\u610f\u5355\u5143\u3002\u5b57\u7b26\u7ec4\u6210\u7b26\u53f7\u3002\u4f8b\u5b50: ->\u3001file \u90fd\u662f\u7b26\u53f7\u3002\u540c\u4e00\u7ec4\u5b57\u7b26\u5e8f\u5217\u5728\u4e0d\u540c\u4e0a\u4e0b\u6587\u4e2d\u53ef\u80fd\u5c5e\u4e8e\u4e0d\u540c\u7b26\u53f7\u3002

\u5982\u679c\u8be5\u5b57\u7b26\u53ef\u80fd\u7ec4\u6210\u7b26\u53f7\uff0c\u90a3\u4e48\u518d\u8bfb\u5165\u4e0b\u4e00\u4e2a\u5b57\u7b26\uff0c\u76f4\u5230\u8bfb\u5165\u7684\u5b57\u7b26\u4e32\u5df2\u7ecf\u4e0d\u53ef\u80fd\u518d\u7ec4\u6210\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u7b26\u53f7\u3002

\u8bcd\u6cd5\u7ec3\u4e60\uff1a\u8bf7\u601d\u8003\u4e0b\u9762\u8fd9\u4e9b\u8868\u8fbe\u5f0f\u7684\u884c\u4e3a

\u70b9\u51fb\u300c+\u300d\u53f7\u5c55\u5f00\u7b54\u6848\u3002

a---b /*(1)!*/\na -- - b /*(2)!*/\na - -- b /*(3)!*/\n\n//\u4e0b\u9762\u7684 p \u6307\u5411\u9664\u6570\u3002\ny = x/*p     \n/*(4)!*/\ny = x / *p /*(5)!*/\n\nn-->0 /*(6)!*/\nn-- >0 /*(7)!*/\nn- -> 0 /*(8)!*/\n\na+++++b /*(9)!*/\n
  1. \u7b49\u4ef7\u4e8e (a--) - b\u3002\u6309\u7167\u8d2a\u5fc3\u6cd5\uff0c\u7f16\u8bd1\u5668\u8bfb\u5165\u4e24\u4e2a\u8fde\u7eed\u7684 - \u53f7\u540e\uff0c\u5df2\u7ecf\u4e0d\u53ef\u80fd\u518d\u7ec4\u6210\u4e00\u4e2a\u6709\u610f\u4e49\u7684\u7b26\u53f7\uff0c\u56e0\u6b64\u8fd9\u4e2a\u7b26\u53f7\u88ab\u786e\u5b9a\u4e3a\u540e\u7f00\u9012\u51cf\u8fd0\u7b97\u7b26\u3002\u63a5\u7740\u8bfb\u53d6\u4e0b\u4e00\u4e2a\u7b26\u53f7\u3002
  2. \u7b49\u4ef7\u4e8e (a--) - b
  3. \u7b49\u4ef7\u4e8e a - (--b)
  4. \u7b49\u4ef7\u4e8e y = x\u3002/* \u88ab\u8d2a\u5fc3\u6cd5\u89e3\u91ca\u4e3a\u6ce8\u91ca\u7684\u5f00\u5934\u3002
  5. \u7b49\u4ef7\u4e8e y = x / (*p)
  6. \u7b49\u4ef7\u4e8e (n--) > 0
  7. \u7b49\u4ef7\u4e8e (n--) > 0
  8. \u7b49\u4ef7\u4e8e (n-) -> 0\u3002\u8fd9\u662f\u4e00\u4e2a\u65e0\u6548\u7684\u8bed\u53e5\uff0cn- \u672c\u8eab\u4e0d\u662f\u4e00\u4e2a\u5408\u6cd5\u7684\u8868\u8fbe\u5f0f\uff0c\u4e5f\u65e0\u6cd5\u7528\u4f5c -> \u7684\u64cd\u4f5c\u6570\u3002
  9. \u7b49\u4ef7\u4e8e ((a++)++) + b\u3002\u8bf7\u601d\u8003\u4e00\u4e0b\uff0c\u8fd9\u4e2a\u8bed\u53e5\u6709\u6548\u5417\uff1f
\u8bed\u6cd5\uff1a\u6807\u8bc6\u7b26\u3001\u8868\u8fbe\u5f0f\u548c\u8bed\u53e5

\u4e3a\u4e86\u4fbf\u4e8e\u521d\u5b66\u8005\u7406\u89e3\uff0c\u6211\u4eec\u91c7\u7528\u4e00\u5957\u7b80\u5316\u7684\u8bed\u6cd5\u89c4\u5219\uff1a

  • \u6807\u8bc6\u7b26\uff08Identifier\uff09\uff1a\u5c31\u662f\u300c\u540d\u5b57\u300d\uff0c\u7528\u4e8e\u6307\u4ee3\u5404\u79cd\u5b9e\u4f53\uff0c\u6bd4\u5982\uff1a\u5bf9\u8c61\u3001\u7c7b\u578b\u3001\u51fd\u6570\u3001\u6807\u7b7e\u3001\u5b8f\u7b49\u7b49\u3002
\u5bf9\u8c61\u7684\u4e0d\u540c\u542b\u4e49

\u5728\u8fd9\u91cc\uff0c\u5bf9\u8c61\uff08Object\uff09\u7684\u542b\u4e49\u4e0e C++ \u4e2d\u4e0d\u540c\u3002\u8fd9\u91cc\u7684\u5bf9\u8c61\u6307\u6570\u636e\u5b58\u50a8\u7684\u4e00\u4e2a\u533a\u57df\uff0c\u5176\u5185\u5bb9\u53ef\u4ee5\u8868\u793a\u503c\u3002\u6bd4\u5982\u4e0b\u9762\u7684\u8bed\u53e5\u521b\u5efa\u4e86\u4e00\u4e2a\u5bf9\u8c61\uff1a

int a;\n

\u521b\u5efa\u4e00\u4e2a\u5bf9\u8c61\u7684\u610f\u601d\u5c31\u662f\u5206\u914d\u4e86\u4e00\u5757\u5b58\u50a8\u7a7a\u95f4\u3002\u6807\u8bc6\u7b26 a \u7528\u4e8e\u6307\u4ee3\u8fd9\u4e2a\u5bf9\u8c61\u3002\u6bcf\u4e2a\u5bf9\u8c61\u90fd\u6709\u5927\u5c0f\u3001\u751f\u5b58\u671f\u3001\u5b58\u50a8\u5668\u3001\u503c\u7b49\u5c5e\u6027\uff0c\u6211\u4eec\u5c06\u5728\u4e0b\u8282\u8bfe\u8be6\u7ec6\u5c55\u5f00\u3002

  • \u8868\u8fbe\u5f0f\uff08Expression\uff09\uff1a\u7531\u8fd0\u7b97\u7b26\uff08+-*/% \u7b49\u7b49\uff09\u548c\u64cd\u4f5c\u6570\uff08\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u51fd\u6570\u8fd4\u56de\u503c......\uff09\u7ec4\u6210\u7684\u5f0f\u5b50\uff0c\u53ef\u4ee5\u8ba1\u7b97\u51fa\u4e00\u4e2a\u503c\u3002
  • \u8bed\u53e5\uff08Statement\uff09\uff1aC \u6807\u51c6\u786e\u5b9a\u4e86\u4e94\u79cd\u8bed\u53e5\u7c7b\u578b\u3002\u9664\u4e86\u590d\u5408\u8bed\u53e5\uff0c\u5176\u5b83\u8bed\u53e5\u90fd\u4ee5\u5206\u53f7 ; \u7ed3\u5c3e\u3002\u4e0b\u9762\u662f\u8bed\u53e5\u7684\u5b9a\u4e49\uff0c\u4f60\u53ef\u4ee5\u53d1\u73b0\u8bed\u53e5\u662f\u9012\u5f52\u5b9a\u4e49\u7684\u3002

    • \u590d\u5408\u8bed\u53e5\uff1a\u7531\u82b1\u62ec\u53f7\u5305\u56f4\u7684\u4e00\u7ec4\u8bed\u53e5\u3002

      { \u8bed\u53e5\u6216\u58f0\u660e }\n
    • \u8868\u8fbe\u5f0f\u8bed\u53e5\uff1a\u8868\u8fbe\u5f0f\u52a0\u4e0a\u5206\u53f7\u5c31\u662f\u8868\u8fbe\u5f0f\u8bed\u53e5\u3002C \u7a0b\u5e8f\u4e2d\u5927\u90e8\u5206\u8bed\u53e5\u90fd\u662f\u8868\u8fbe\u5f0f\u8bed\u53e5\u3002\u7a7a\u8bed\u53e5\u4e5f\u7b97\u4f5c\u8868\u8fbe\u5f0f\u8bed\u53e5\u3002

      \u8868\u8fbe\u5f0f;\n

      \u4f8b\u5b50\uff1a

      puts(\"hello\"); // \u8868\u8fbe\u5f0f\u8bed\u53e5\nchar *s;\nwhile (*s++ != '\\0')\n  ; // \u7a7a\u8bed\u53e5\n
    • \u9009\u62e9\u8bed\u53e5\uff1a

      if(\u8868\u8fbe\u5f0f) \u8bed\u53e5\nif(\u8868\u8fbe\u5f0f) \u8bed\u53e5 else \u8bed\u53e5\nswitch(\u8868\u8fbe\u5f0f) \u8bed\u53e5\n
    • \u5faa\u73af\u8bed\u53e5\uff1a

      while(\u8868\u8fbe\u5f0f) \u8bed\u53e5\ndo \u8bed\u53e5 while(\u8868\u8fbe\u5f0f);\nfor(\u521d\u59cb\u5316\u5b50\u53e5;\u8868\u8fbe\u5f0f;\u8868\u8fbe\u5f0f) \u8bed\u53e5\n
    • \u8df3\u8f6c\u8bed\u53e5\uff1a

      goto \u6807\u8bc6\u7b26;\ncontinue;\nbreak;\nreturn \u8868\u8fbe\u5f0f;\n

\u5b8c\u6574\u7684C\u8bed\u6cd5\u89c4\u5219\u8bf7\u53c2\u8003\uff1a

  • CPPReference\uff1a\u6807\u8bc6\u7b26
  • CPPReference\uff1a\u8868\u8fbe\u5f0f
  • CPPReference: \u8bed\u53e5

\u8bed\u6cd5\u5c06\u5728\u540e\u7eed\u8bfe\u7a0b\u4e2d\u4f5c\u6df1\u5165\u8bb2\u89e3\uff08\u7b2c 2 \u8bb2\u6d89\u53ca\u7c7b\u578b\u76f8\u5173\u7684\u8bed\u6cd5\uff0c\u7b2c 4 \u8bb2\u6d89\u53ca\u51fd\u6570\u6307\u9488\uff09\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#c","title":"\u51fd\u6570\uff1aC \u7a0b\u5e8f\u7684\u57fa\u672c\u6a21\u5757","text":"

\u300c\u6307\u4ee4\u300d\u662f\u7b2c\u4e00\u3001\u4e8c\u4ee3\u7f16\u7a0b\u8bed\u8a00\u7684\u57fa\u672c\u7ed3\u6784\u3002C \u8bed\u8a00\u662f\u9762\u5411\u8fc7\u7a0b\u7684\u9ad8\u7ea7\u8bed\u8a00\uff0c\u5b83\u7684\u57fa\u672c\u6a21\u5757\u662f\u51fd\u6570\uff08Function\uff09\u3002

\u5173\u952e\u6982\u5ff5\uff1a\u51fd\u6570

\u4ece\u5916\u9762\u770b\uff0c\u51fd\u6570\u5c31\u50cf\u4e00\u4e2a\u9ed1\u76d2\u5b50\uff0c\u53ea\u80fd\u770b\u5230\u51fd\u6570\u7684\u4e09\u5927\u8981\u7d20\uff1a

  • \u51fd\u6570\u540d\uff1a\u51fd\u6570\u7684\u540d\u5b57\uff0c\u7528\u6765\u8c03\u7528\u51fd\u6570\u3002
    • \u51fd\u6570\u540d\u4e0e\u53d8\u91cf\u540d\u7684\u547d\u540d\u89c4\u5219\u76f8\u540c\u3002
  • \u53c2\u6570\uff1a\u51fd\u6570\u7684\u8f93\u5165\uff0c\u53ef\u4ee5\u6709\u591a\u4e2a\u3002
  • \u8fd4\u56de\u503c\uff1a\u51fd\u6570\u7684\u8f93\u51fa\uff0c\u53ea\u80fd\u6709\u4e00\u4e2a\u3002

\u4e0b\u9762\u8fd9\u884c\u8bed\u53e5\u88ab\u79f0\u4e3a\u51fd\u6570\u7b7e\u540d\uff08Function Signature\uff09\u6216\u51fd\u6570\u539f\u578b\uff08Function Prototype\uff09\u3002\u5b83\u7ed9\u51fa\u4e86\u51fd\u6570\u5bf9\u5916\u7684\u4e00\u5207\u4fe1\u606f\uff1a

int MyFunc(int a, int b);\n

\u4ece\u91cc\u9762\u770b\uff0c\u51fd\u6570\u662f\u4e00\u7ec4\u6307\u4ee4\u7684\u96c6\u5408\uff0c\u5b83\u4eec\u6309\u7167\u4e00\u5b9a\u7684\u987a\u5e8f\u6267\u884c\uff0c\u5b8c\u6210\u67d0\u4e2a\u7279\u5b9a\u7684\u529f\u80fd\u3002

\u5f53\u6211\u4eec\u8c03\u7528\u4e00\u4e2a\u51fd\u6570\u65f6\uff0c\u6211\u4eec\u5e94\u5f53\u6309\u7167\u51fd\u6570\u7b7e\u540d\u4e2d\u7684\u8981\u6c42\u4f20\u5165\u53c2\u6570\uff0c\u5e76\u53ef\u4ee5\u83b7\u5f97\u5b83\u7684\u8fd4\u56de\u503c\u3002\u5728\u51fd\u6570\u7b7e\u540d\u7684\u8bed\u5883\u4e0b\uff0cvoid \u8868\u793a\u7a7a\uff0c\u5373\u4e0d\u5b58\u5728\u3002\u4e0b\u9762\u7684\u8fd9\u4e2a\u51fd\u6570\u6ca1\u6709\u53c2\u6570\uff0c\u4e5f\u6ca1\u6709\u8fd4\u56de\u503c\u3002

void MyFunc(void);\n

\u56e0\u4e3a\u6211\u4eec\u6bd4\u8f83\u5173\u5fc3\u51fd\u6570\u8fd4\u56de\u503c\u7684\u7c7b\u578b\uff0c\u6709\u65f6\u4f1a\u628a\u51fd\u6570\u7684\u8fd4\u56de\u503c\u7c7b\u578b\u79f0\u4e3a\u8fd9\u4e2a\u51fd\u6570\u7684\u201c\u7c7b\u578b\u201d\uff0c\u6bd4\u5982\u4f1a\u8bf4 MyFunc \u8fd9\u4e2a\u51fd\u6570\u662f\u4e00\u4e2a void \u51fd\u6570\u3002

\u5173\u4e8e void

Q\uff1avoid \u5230\u5e95\u6709\u54ea\u4e9b\u542b\u4e49\uff1f

A: \u4e0b\u9762\u662f void \u7684\u4e00\u822c\u7528\u6cd5

  • void \u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\uff0c\u8868\u793a\u51fd\u6570\u4e0d\u63a5\u53d7\u53c2\u6570\u3002
  • void \u4f5c\u4e3a\u51fd\u6570\u8fd4\u56de\u503c\uff0c\u8868\u793a\u51fd\u6570\u4e0d\u8fd4\u56de\u503c\u3002
  • void* \u662f\u4e00\u79cd\u6307\u9488\u7c7b\u578b\uff0c\u8868\u793a\u4e0d\u77e5\u9053\u6307\u5411\u7684\u7c7b\u578b\u662f\u4ec0\u4e48\u3002

\u4ece\u8fd9\u4e9b\u7528\u6cd5\u6765\u770b\uff0c\u4f3c\u4e4e void \u662f\u4e00\u79cd\u7c7b\u578b\uff0c\u4f46\u8fd9\u4f1a\u5f15\u8d77\u4e0b\u9762\u95ee\u9898\u4e2d\u7684\u77db\u76fe\u3002\u53e6\u4e00\u79cd\u770b\u5f85\u65b9\u5f0f\u662f\uff1a\u4e0a\u9762\u7684\u7528\u6cd5\u90fd\u662f\u7279\u6b8a\u7684\u8bed\u6cd5\uff0c\u4e0d\u8fc7\u662f\u6070\u597d\u7528\u4e86\u540c\u4e00\u4e2a\u5173\u952e\u5b57 void \u7f62\u4e86\u3002

Q\uff1a\u6240\u4ee5 void \u662f\u4e00\u79cd\u7c7b\u578b\u5417\uff1f

A\uff1aC \u6807\u51c6\u4ece\u6982\u5ff5\u4e0a\u5c06 void \u4f5c\u4e3a\u4e00\u79cd\u7c7b\u578b\u3002\u4f46\u662f void \u7c7b\u578b\u7684\u53d8\u91cf\u662f\u4e0d\u5b58\u5728\u7684\uff0c\u56e0\u4e3a\u5b83\u6ca1\u6709\u5927\u5c0f\uff0c\u7f16\u8bd1\u5668\u4e5f\u4e0d\u5141\u8bb8\u4f60\u5199\u4e0b void a;\u3002\u8fd9\u4f1a\u5f15\u8d77\u4e00\u4e9b\u56f0\u60d1\u3002

\u51fd\u6570\u6709\u4e24\u4e2a\u529f\u80fd\uff1a

  • \u8fd4\u56de\u503c\uff1a\u51fd\u6570\u8c03\u7528\u672c\u8eab\u5c31\u662f\u4e00\u4e2a\u8868\u8fbe\u5f0f\uff0c\u5b83\u7684\u503c\u5c31\u662f\u51fd\u6570\u7684\u8fd4\u56de\u503c\u3002
  • \u526f\u4f5c\u7528\uff1a\u9664\u4e86\u8fd4\u56de\u503c\u4ee5\u5916\u7684\u529f\u80fd\u7edf\u79f0\u4e3a\u526f\u4f5c\u7528\u3002

\u4e00\u4e9b\u4f8b\u5b50\uff1a

\u51fd\u6570\u7b7e\u540d \u8fd4\u56de\u503c\u7684\u542b\u4e49 \u526f\u4f5c\u7528 int printf(const char *format, ...); \u6253\u5370\u7684\u5b57\u7b26\u6570 \u6253\u5370\u5b57\u7b26\u4e32\u5230\u6807\u51c6\u8f93\u51fa int scanf(const char *format, ...); \u8bfb\u53d6\u7684\u5b57\u7b26\u6570 \u4ece\u6807\u51c6\u8f93\u5165\u8bfb\u53d6\u5b57\u7b26\u4e32 int rand(void); \u751f\u6210\u7684\u968f\u673a\u6570 \u65e0 void exit(int status); \u65e0 \u9000\u51fa\u7a0b\u5e8f

\u6bcf\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u90fd\u5fc5\u987b\u5305\u542b\u4e00\u4e2a main \u51fd\u6570\uff0c\u5b83\u662f\u7a0b\u5e8f\u7684\u5165\u53e3\u3002main \u7684\u51fd\u6570\u7b7e\u540d\u4e00\u822c\u662f\u8fd9\u6837\u7684\uff1a

int main(void);\nint main(int argc, char *argv[]); //\u4ee5\u540e\u5b66\u547d\u4ee4\u884c\u53c2\u6570\u5c31\u4f1a\u7528\u5230\u8fd9\u79cd\u5f62\u5f0f\n

main \u7684\u8c03\u7528\u8005\u662f\u64cd\u4f5c\u7cfb\u7edf\u3002\u64cd\u4f5c\u7cfb\u7edf\u770b\u5230 main \u7684\u7b7e\u540d\u4e2d\u8bf4\u8fd4\u56de\u503c\u4e3a int\uff0c\u56e0\u6b64\u7cfb\u7edf\u4f1a\u7b49\u5f85 main \u8fd4\u56de\u4e00\u4e2a\u6574\u6570\u3002\u8fd9\u4e2a\u6574\u6570\u4e00\u822c\u88ab\u7528\u4e8e\u544a\u77e5\u64cd\u4f5c\u7cfb\u7edf\u7a0b\u5e8f\u7684\u6267\u884c\u72b6\u6001\uff0c0 \u8868\u793a\u6b63\u5e38\u7ed3\u675f\uff0c\u5176\u4ed6\u503c\u53ef\u4ee5\u4f20\u9012\u5176\u4ed6\u4fe1\u606f\u3002\u8fd9\u5c31\u662f\u4e3a\u4ec0\u4e48 main \u7684\u672b\u5c3e\u5e94\u5f53\u5199 return 0\u3002\u5982\u679c main \u51fd\u6570\u4e2d\u6ca1\u6709 return \u8bed\u53e5\uff0c\u6709\u4e9b\u7f16\u8bd1\u5668\u4f1a\u4e3a\u4f60\u8865\u5168\uff08\u5176\u4ed6\u51fd\u6570\u4e0d\u4f1a\uff09\u3002\u4f46\u8bf7\u8bb0\u5f97\u5199\u4e0a\uff0c\u8fd9\u662f\u4f60\u7684\u8d23\u4efb\u3002

\u6ca1\u6709\u8fd4\u56de\u503c\u7684\u51fd\u6570\u4e5f\u53ef\u4ee5\u4f7f\u7528 return \u8bed\u53e5\uff0c\u6b64\u65f6\u5b83\u6ca1\u6709\u8fd4\u56de\u503c\u7684\u4f5c\u7528\uff0c\u800c\u662f\u7ed3\u675f\u5f53\u524d\u51fd\u6570\u7684\u6267\u884c\u5e76\u8fd4\u56de\u3002\u4f8b\u5b50\uff1a

void print_logarithm(double x)\n{\n    if (x <= 0.0) {\n        printf(\"Positive numbers only, please.\\n\");\n        return;\n    }\n    printf(\"The log of x is %f\", log(x));\n}\n
\u5176\u4ed6\u5efa\u8bae

\u6bcf\u4e2a\u51fd\u6570\u90fd\u5e94\u8be5\u8bbe\u8ba1\u5f97\u5c3d\u53ef\u80fd\u7b80\u5355\uff0c\u7b80\u5355\u7684\u51fd\u6570\u624d\u5bb9\u6613\u7ef4\u62a4\u3002\u5e94\u9075\u5faa\u4ee5\u4e0b\u539f\u5219\uff1a

  1. \u5b9e\u73b0\u4e00\u4e2a\u51fd\u6570\u53ea\u662f\u4e3a\u4e86\u505a\u597d\u4e00\u4ef6\u4e8b\u60c5\uff0c\u4e0d\u8981\u628a\u51fd\u6570\u8bbe\u8ba1\u6210\u7528\u9014\u5e7f\u6cdb\u3001\u9762\u9762\u4ff1\u5230\u7684\uff0c\u8fd9\u6837\u7684\u51fd\u6570\u80af\u5b9a\u4f1a\u8d85\u957f\uff0c\u800c\u4e14\u5f80\u5f80\u4e0d\u53ef\u91cd\u7528\uff0c\u7ef4\u62a4\u56f0\u96be\u3002

  2. \u51fd\u6570\u5185\u90e8\u7684\u7f29\u8fdb\u5c42\u6b21\u4e0d\u5b9c\u8fc7\u591a\uff0c\u4e00\u822c\u4ee5\u5c11\u4e8e 4 \u5c42\u4e3a\u5b9c\u3002\u5982\u679c\u7f29\u8fdb\u5c42\u6b21\u592a\u591a\u5c31\u8bf4\u660e\u8bbe\u8ba1\u5f97\u592a\u590d\u6742\u4e86\uff0c\u5e94\u8003\u8651\u5206\u5272\u6210\u66f4\u5c0f\u7684\u51fd\u6570\uff08Helper Function\uff09\u6765\u8c03\u7528\u3002

  3. \u51fd\u6570\u4e0d\u8981\u5199\u5f97\u592a\u957f\uff0c\u5efa\u8bae\u572824\u884c\u7684\u6807\u51c6\u7ec8\u7aef\u4e0a\u4e0d\u8d85\u8fc7\u4e24\u5c4f\uff0c\u592a\u957f\u4f1a\u9020\u6210\u9605\u8bfb\u56f0\u96be\uff0c\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u8d85\u8fc7\u4e24\u5c4f\u5c31\u5e94\u8be5\u8003\u8651\u5206\u5272\u51fd\u6570\u4e86\u3002[CodingStyle]\u4e2d\u7279\u522b\u8bf4\u660e\uff0c\u5982\u679c\u4e00\u4e2a\u51fd\u6570\u5728\u6982\u5ff5\u4e0a\u662f\u7b80\u5355\u7684\uff0c\u53ea\u662f\u957f\u5ea6\u5f88\u957f\uff0c\u8fd9\u5012\u6ca1\u5173\u7cfb\u3002\u4f8b\u5982\u51fd\u6570\u7531\u4e00\u4e2a\u5927\u7684 switch \u7ec4\u6210\uff0c\u5176\u4e2d\u6709\u975e\u5e38\u591a\u7684 case\uff0c\u8fd9\u662f\u53ef\u4ee5\u7684\uff0c\u56e0\u4e3a\u5404 case \u5206\u652f\u4e92\u4e0d\u5f71\u54cd\uff0c\u6574\u4e2a\u51fd\u6570\u7684\u590d\u6742\u5ea6\u53ea\u7b49\u4e8e\u5176\u4e2d\u4e00\u4e2a case \u7684\u590d\u6742\u5ea6\uff0c\u8fd9\u79cd\u60c5\u51b5\u5f88\u5e38\u89c1\uff0c\u4f8b\u5982 TCP \u534f\u8bae\u7684\u72b6\u6001\u673a\u5b9e\u73b0\u3002

  4. \u6267\u884c\u51fd\u6570\u5c31\u662f\u6267\u884c\u4e00\u4e2a\u52a8\u4f5c\uff0c\u51fd\u6570\u540d\u901a\u5e38\u5e94\u5305\u542b\u52a8\u8bcd\uff0c\u4f8b\u5982 get_current\u3001radix_tree_insert\u3002

  5. \u6bd4\u8f83\u91cd\u8981\u7684\u51fd\u6570\u5b9a\u4e49\u4e0a\u4fa7\u5fc5\u987b\u52a0\u6ce8\u91ca\uff0c\u8bf4\u660e\u6b64\u51fd\u6570\u7684\u529f\u80fd\u3001\u53c2\u6570\u3001\u8fd4\u56de\u503c\u3001\u9519\u8bef\u7801\u7b49\u3002

  6. \u53e6\u4e00\u79cd\u5ea6\u91cf\u51fd\u6570\u590d\u6742\u5ea6\u7684\u529e\u6cd5\u662f\u770b\u6709\u591a\u5c11\u4e2a\u5c40\u90e8\u53d8\u91cf\uff0c5 \u5230 10 \u4e2a\u5c40\u90e8\u53d8\u91cf\u5df2\u7ecf\u5f88\u591a\u4e86\uff0c\u518d\u591a\u5c31\u5f88\u96be\u7ef4\u62a4\u4e86\uff0c\u5e94\u8be5\u8003\u8651\u5206\u5272\u6210\u591a\u4e2a\u51fd\u6570\u3002

\u6269\u5c55\uff1a\u7f16\u8bd1\u548c\u89e3\u91ca

\u7b80\u5355\u4e86\u89e3\u4e00\u4e0b\u5c31\u597d\u3002

\u5c06\u9ad8\u7ea7\u8bed\u8a00\u7f16\u5199\u7684\u6e90\u4ee3\u7801\u8f6c\u5316\u6210\u673a\u5668\u8bed\u8a00\u7684\u76ee\u6807\u7a0b\u5e8f\u7684\u8fc7\u7a0b\u7edf\u79f0\u4e3a\u7ffb\u8bd1\uff08Translation\uff09\u3002\u7ffb\u8bd1\u7684\u65b9\u5f0f\u6709\u4e24\u79cd\uff1a\u7f16\u8bd1\uff08Compile\uff09\u548c\u89e3\u91ca\uff08Interpret\uff09\u3002\u7f16\u8bd1\u5c06\u6574\u4e2a\u7a0b\u5e8f\u7ffb\u8bd1\u6210\u673a\u5668\u8bed\u8a00\uff0c\u89e3\u91ca\u5219\u662f\u8fb9\u7ffb\u8bd1\u8fb9\u6267\u884c\u3002

C \u8bed\u8a00\u662f\u5178\u578b\u7684\u7f16\u8bd1\u578b\u8bed\u8a00\uff0c\u6e90\u4ee3\u7801\u9700\u8981\u7ecf\u8fc7\u7f16\u8bd1\u540e\u624d\u80fd\u8fd0\u884c\uff0c\u800c\u7f16\u8bd1\u9636\u6bb5\u5e76\u4e0d\u4f1a\u6267\u884c\u7a0b\u5e8f\u3002Python \u5219\u662f\u5178\u578b\u7684\u89e3\u91ca\u578b\u8bed\u8a00\uff0c\u9010\u53e5\u6267\u884c\u6e90\u4ee3\u7801\uff0c\u4e0d\u9700\u8981\u4ea7\u751f\u53ef\u6267\u884c\u6587\u4ef6\u3002

\u8fd9\u4e9b\u63cf\u8ff0\u7684\u90fd\u662f\u4e00\u79cd\u8bed\u8a00\u7684\u5178\u578b\u7528\u6cd5\u3002\u4e8b\u5b9e\u4e0a C \u8bed\u8a00\u4e5f\u5f00\u53d1\u51fa\u4e86\u76f8\u5e94\u7684\u89e3\u91ca\u5668\uff0cPython \u4e5f\u5f00\u53d1\u51fa\u4e86\u76f8\u5e94\u7684\u7f16\u8bd1\u5668\u3002\u4e24\u79cd\u7ffb\u8bd1\u65b9\u5f0f\u5404\u6709\u4f18\u52a3\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_9","title":"\u73b0\u5728\u4f60\u662f\u7f16\u8bd1\u5668","text":"

\u63a5\u4e0b\u6765\u6211\u4eec\u5c06\u5316\u8eab C \u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u89e3\u8bfb\u4e00\u4e9b\u4ee3\u7801\u3002\u76f8\u4fe1\u7ecf\u8fc7\u4e0b\u9762\u7684\u8bad\u7ec3\uff0c\u4f60\u5bf9\u4ee3\u7801\u548c\u7a0b\u5e8f\u6267\u884c\u7684\u7406\u89e3\u4f1a\u66f4\u52a0\u6df1\u5165\u3002

\u4f8b\u5b50\uff1a\u8bed\u6cd5\u6811
printf(\"%d:%d is %d minutes after 00:00\\n\", hour, minute, hour * 60 + minute);\n

\u7f16\u8bd1\u5668\u5728\u7ffb\u8bd1\u8fd9\u6761\u8bed\u53e5\u65f6\uff0c\u9996\u5148\u6839\u636e\u4e0a\u8ff0\u8bed\u6cd5\u89c4\u5219\u628a\u8fd9\u4e2a\u8bed\u53e5\u89e3\u6790\u6210\u4e0b\u56fe\u6240\u793a\u7684\u8bed\u6cd5\u6811\uff0c\u7136\u540e\u518d\u6839\u636e\u8bed\u6cd5\u6811\u751f\u6210\u76f8\u5e94\u7684\u6307\u4ee4\u3002\u8bed\u6cd5\u6811\u7684\u672b\u7aef\u7684\u662f\u4e00\u4e2a\u4e2aToken\uff0c\u6bcf\u4e00\u6b65\u5c55\u5f00\u5229\u7528\u4e00\u6761\u8bed\u6cd5\u89c4\u5219\u3002

\u7406\u89e3\u7ec4\u5408\uff08Composition\uff09\u89c4\u5219\u662f\u7406\u89e3\u8bed\u6cd5\u89c4\u5219\u7684\u5173\u952e\u6240\u5728\uff0c\u6b63\u56e0\u4e3a\u53ef\u4ee5\u6839\u636e\u8bed\u6cd5\u89c4\u5219\u4efb\u610f\u7ec4\u5408\uff0c\u6211\u4eec\u624d\u53ef\u4ee5\u7528\u7b80\u5355\u7684\u5e38\u91cf\u3001\u53d8\u91cf\u3001\u8868\u8fbe\u5f0f\u3001\u8bed\u53e5\u642d\u5efa\u51fa\u4efb\u610f\u590d\u6742\u7684\u7a0b\u5e8f\uff0c\u4ee5\u540e\u6211\u4eec\u5b66\u4e60\u65b0\u7684\u8bed\u6cd5\u89c4\u5219\u65f6\u4f1a\u8fdb\u4e00\u6b65\u4f53\u4f1a\u5230\u8fd9\u4e00\u70b9\u3002\u4ece\u4e0a\u9762\u7684\u4f8b\u5b50\u53ef\u4ee5\u770b\u51fa\uff0c\u8868\u8fbe\u5f0f\u4e0d\u5b9c\u8fc7\u5ea6\u7ec4\u5408\uff0c\u5426\u5219\u4f1a\u7ed9\u9605\u8bfb\u548c\u8c03\u8bd5\u5e26\u6765\u56f0\u96be\u3002

\u8868\u8fbe\u5f0f\u4e0d\u5b9c\u8fc7\u5ea6\u7ec4\u5408

\u8fd9\u6d89\u53ca\u4ee3\u7801\u53ef\u8bfb\u6027\u95ee\u9898\u3002\u770b\u770b\u4e0b\u9762\u8fd9\u6bb5\u4ee3\u7801\uff1a

double distance(double x1, double y1, double x2, double y2)\n{\n     return sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));\n}\n

\u8fd9\u6837\u5199\u5f88\u7b80\u6d01\uff0c\u4f46\u5982\u679c\u5199\u9519\u4e86\u5462\uff1f\u53ea\u77e5\u9053\u662f\u8fd9\u4e00\u957f\u4e32\u8868\u8fbe\u5f0f\u6709\u9519\uff0c\u6839\u672c\u4e0d\u77e5\u9053\u9519\u5728\u54ea\uff0c\u800c\u4e14\u6574\u4e2a\u51fd\u6570\u5c31\u4e00\u4e2a\u8bed\u53e5\uff0c\u63d2printf\u90fd\u6ca1\u5730\u65b9\u63d2\u3002\u6240\u4ee5\u7528\u4e34\u65f6\u53d8\u91cf\u6709\u5b83\u7684\u597d\u5904\uff0c\u4f7f\u7a0b\u5e8f\u66f4\u6e05\u6670\uff0c\u8c03\u8bd5\u66f4\u65b9\u4fbf\uff0c\u800c\u4e14\u6709\u65f6\u5019\u53ef\u4ee5\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u8ba1\u7b97\uff0c\u4f8b\u5982\u4e0a\u9762\u8fd9\u4e00\u884c\u8868\u8fbe\u5f0f\u8981\u628a(x2-x1)\u8ba1\u7b97\u4e24\u904d\uff0c\u5982\u679c\u7b97\u5b8c(x2-x1)\u628a\u7ed3\u679c\u5b58\u5728\u4e00\u4e2a\u4e34\u65f6\u53d8\u91cfdx\u91cc\uff0c\u5c31\u4e0d\u9700\u8981\u518d\u7b97\u7b2c\u4e8c\u904d\u4e86\uff08\u867d\u7136\u8fd9\u4e9b\u4f18\u5316\u73b0\u4ee3\u7f16\u8bd1\u5668\u90fd\u4f1a\u66ff\u4f60\u81ea\u52a8\u5b8c\u6210\uff09\u3002\u4e0b\u9762\u8fd9\u4e2a\u7248\u672c\u662f\u53ef\u8bfb\u6027\u9ad8\u7684\u4ee3\u7801\uff1a

double distance(double x1, double y1, double x2, double y2)\n{\n    double dx = x2 - x1;\n    double dy = y2 - y1;\n    double dsquared = dx * dx + dy * dy;\n    double result = sqrt(dsquared);\n\n    return result;\n}\n

\u7801\u98ce\u4e0d\u662f\u6b7b\u7684\uff0c\u8bf7\u540c\u5b66\u4eec\u89c6\u60c5\u51b5\u5207\u6362\u7801\u98ce\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#lap","title":"Lap\uff1a\u5173\u4e8e\u505a\u9898\u76ee","text":"

\u5982\u679c\u60f3\u505a\u9898\u7684\u8bdd\uff0c\u6709\u57fa\u7840\u7684\u540c\u5b66\u53ef\u4ee5\u65e9\u70b9\u5f00\u59cb\u505a\u5386\u5e74\u5377\uff0c\u4e86\u89e3\u4e00\u4e0b\u7a0b\u8bbe\u8003\u8bd5\u90fd\u8003\u4e9b\u5565\u3002

\u7b80\u5355\u63d0\u4e00\u4e9b Tips\uff1a

  • \u8003\u8bd5\u662f\u5168\u82f1\u6587\u3002\u5982\u679c\u5e73\u5e38\u4e0d\u592a\u770b\u82f1\u6587\u6587\u6863/\u6ca1\u600e\u4e48\u5b66/\u82f1\u8bed\u5f88\u5dee\u7684\u540c\u5b66\uff0c\u81f3\u5c11\u4f60\u8003\u524d\u505a\u5386\u5e74\u5377\u7684\u65f6\u5019\u8981\u628a\u751f\u8bcd\u5168\u90e8\u6284\u4e0b\u6765\u8bb0\u4e00\u904d\u3002
  • \u4e00\u5b9a\u4e00\u5b9a\u4e00\u5b9a\u8981\u505a\u5386\u5e74\u5377\u3002\u4e0d\u8981\u4ee5\u4e3a\u81ea\u5df1\u4f1a\u5199\u70b9\u4ee3\u7801\u5c31\u80fd\u5e94\u4ed8\u8003\u8bd5\u4e86\uff0c\u5176\u5b9e\u8003\u8bd5\u548c\u4f60\u5199\u4ee3\u7801\u6c34\u5e73\u5e76\u4e0d\u5448\u6b63\u76f8\u5173\u3002\u8003\u8bd5\u7684\u9898\u76ee\u90fd\u662f\u5f88\u7ec6\u8282\u7684\uff0c\u5f88\u591a\u90fd\u662f\u4f60\u5e73\u5e38\u4e0d\u4f1a\u6ce8\u610f\u5230\u7684\uff0c\u6240\u4ee5\u4e00\u5b9a\u8981\u505a\u5386\u5e74\u5377\uff0c\u505a\u5b8c\u4e86\u8fd8\u8981\u770b\u770b\u7b54\u6848\uff0c\u770b\u770b\u81ea\u5df1\u54ea\u91cc\u505a\u9519\u4e86\uff0c\u54ea\u91cc\u6ca1\u6ce8\u610f\u5230\u3002\u8fd9\u91cc\u5c55\u793a\u4e00\u4e2a\u53bb\u5e74 C \u5c0f\u8003\u8bd5\u5e72\u788e\u4e00\u7247\u4eba\u7684\u9009\u62e9\u9898\uff1a
\u5e72\u788e\u4e00\u7247\u4eba\u7684\u9009\u62e9\u9898

Suppose T is a type name and t is a variable of type T. Which of the following is NOT a valid expression?

A. sizeof(T) B. sizeof(t) C. sizeof T D. sizeof t

\u7b54\u6848

\u7b54\u6848\u662f C\uff0c\u4e0d\u77e5\u9053\u4f60\u731c\u5bf9\u4e86\u5417\uff1f

\u5927\u5bb6\u4e00\u822c\u5199\u4ee3\u7801 sizeof \u540e\u9762\u90fd\u4f1a\u52a0\u62ec\u53f7\u7684\u5bf9\u5427\uff0c\u4f46\u4f60\u77e5\u9053\u4e3a\u4ec0\u4e48\u5417\uff1f\u60f3\u8981\u77e5\u9053\u4e3a\u4ec0\u4e48\uff0c\u9700\u8981\u56de\u987e\u524d\u9762\u5b66\u4e60\u7684\u8bed\u6cd5\u77e5\u8bc6\u3002

sizeof \u662f\u4e00\u4e2a\u8fd0\u7b97\u7b26\uff0c\u5b83\u6709\u4e24\u79cd\u4f7f\u7528\u65b9\u5f0f\uff1a

sizeof(\u7c7b\u578b)\nsizeof \u8868\u8fbe\u5f0f\n

\u6211\u4eec\u77e5\u9053\uff0ct \u662f\u8868\u8fbe\u5f0f\uff0c(t) \u4e5f\u662f\u8868\u8fbe\u5f0f\u3002sizeof(T) \u7684\u4f7f\u7528\u7b26\u5408\u89c4\u8303\u3002\u56e0\u6b64 A\u3001B\u3001D \u90fd\u662f\u6b63\u786e\u7684\u3002\u4e3a\u4ec0\u4e48\u4e0d\u89c4\u5b9a sizeof \u7c7b\u578b \u7684\u7528\u6cd5\u5462\uff1f\u56e0\u4e3a\u8fd9\u53ef\u80fd\u5f15\u8d77\u6b67\u4e49\uff0c\u6709\u4e9b\u7c7b\u578b\u540d\u5c31\u643a\u5e26\u7a7a\u683c\uff0c\u6bd4\u5982\uff1ashort int\u3001struct node \u7b49\u7b49\u3002\u4e86\u89e3\u4e86\u8fd9\u4e9b\u77e5\u8bc6\uff0c\u4f60\u80fd\u8bf4\u8bf4\u4e0b\u9762\u7684\u8bed\u53e5\u662f\u5426\u5408\u6cd5\u5417\uff1f\u5982\u679c\u5408\u6cd5\uff0c\u4f60\u80fd\u89e3\u91ca\u5b83\u7684\u542b\u4e49\u5417\uff1f\u5982\u679c\u4e0d\u89c4\u5b9a\u7c7b\u578b\u5fc5\u987b\u5e26\u62ec\u53f7\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u54ea\u4e9b\u4e8c\u4e49\u6027\uff1f

sizeof int***p\nsizeof(int)*p\nsizeof int * + 1\n

\u5982\u679c\u4f60\u60f3\u7684\u8bdd\uff0c\u53ef\u4ee5\u518d\u6765\u4e24\u9053\uff1a

C \u5927 16 \u5e74\u9009\u62e9\u9898

In the following notations, _____ can express a character constant( \u5b57\u7b26\u5e38\u91cf ) correctly.

A. '\\x100' B. 125 C. '\\08' D. '\\'

\u7b54\u6848

B

"},{"location":"programming_lecture/lecture1/lecture1/#_10","title":"\u7a0b\u5e8f\u7684\u7f16\u8bd1\u8fc7\u7a0b","text":"

\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u5c06\u4e86\u89e3\u7f16\u8bd1\u5668\u548c\u6c47\u7f16\u5668\u662f\u5982\u4f55\u4e00\u6b65\u6b65\u628a\u4f60\u7684\u7a0b\u5e8f\u7f16\u8bd1\u6210\u673a\u5668\u7801\u7684\u3002\u6211\u4eec\u4ee5\u6700\u7ecf\u5178\u7684 C \u8bed\u8a00\u7f16\u8bd1\u7cfb\u7edf GCC \u4e3a\u4f8b\u3002

\u4ec0\u4e48\u662f GCC\uff1f

\u7b80\u5355\u5730\u8bf4\uff0cGNU \u9879\u76ee\u65e8\u5728\u5f00\u53d1\u4e00\u4e2a\u5b8c\u5168\u81ea\u7531\u7684\u64cd\u4f5c\u7cfb\u7edf\u4ee5\u53ca\u914d\u5957\u7684\u8f6f\u4ef6\u3002GCC \u6700\u65e9\u662f GNU C Compiler \u7684\u7b80\u79f0\uff0c\u73b0\u5728\u4ee3\u8868 GNU Compiler Collection\u3002\u8fd9\u8868\u660e\u5b83\u4e0d\u662f\u5355\u4e2a\u7a0b\u5e8f\uff0c\u800c\u662f\u4e00\u7cfb\u5217\u7f16\u8bd1\u5de5\u5177\u7684\u96c6\u5408\uff0c\u5305\u62ec\u4e86 C\u3001C++\u3001Objective-C\u3001Fortran\u3001Ada\u3001Go\u3001D \u7b49\u8bed\u8a00\u7684\u524d\u7aef\uff0c\u4ee5\u53ca\u6c47\u7f16\u5668\u3001\u94fe\u63a5\u5668\u7b49\u540e\u7aef\uff0c\u548c\u8fd9\u4e9b\u8bed\u8a00\u7684\u5e93\u6587\u4ef6\u3002

\u5f53\u6211\u4eec\u4f7f\u7528\u547d\u4ee4 gcc -o test test.c \u7f16\u8bd1\u4e00\u4e2a C \u8bed\u8a00\u7a0b\u5e8f\u65f6\uff0cGCC \u4f1a\u8c03\u7528\u4e00\u7cfb\u5217\u7684\u7a0b\u5e8f\u5c06\u6e90\u4ee3\u7801\u7ffb\u8bd1\u6210\u6c47\u7f16\u8bed\u8a00\u3001\u518d\u7ffb\u8bd1\u6210\u673a\u5668\u8bed\u8a00\uff0c\u6700\u540e\u7ecf\u8fc7\u94fe\u63a5\u4ea7\u751f\u53ef\u6267\u884c\u6587\u4ef6\u3002\u4e0b\u56fe\u5c55\u793a\u4e86\u8fd9\u4e2a\u8fc7\u7a0b\u3002

  1. \u9884\u5904\u7406\uff1a\u7531 C \u9884\u5904\u7406\u5668\uff08C Preprocessor\uff09\u5b8c\u6210\uff0c\u5b83\u5c06\u6e90\u4ee3\u7801\u4e2d\u7684\u5b8f\u5b9a\u4e49\u5c55\u5f00\uff0c\u5c06\u5934\u6587\u4ef6\u4e2d\u7684\u5185\u5bb9\u63d2\u5165\u5230\u6e90\u4ee3\u7801\u4e2d\uff0c\u5220\u9664\u6ce8\u91ca\u7b49\u3002\u9884\u5904\u7406\u540e\u7684\u4ee3\u7801\u6587\u4ef6\u4ee5 .i \u4e3a\u540e\u7f00\u3002
  2. \u7f16\u8bd1\uff1a\u7531 C \u7f16\u8bd1\u5668\uff08C Compiler\uff09\u5b8c\u6210\uff0c\u5b83\u5c06\u9884\u5904\u7406\u540e\u7684\u6587\u4ef6\u7ffb\u8bd1\u6210\u6c47\u7f16\u8bed\u8a00\u3002\u7f16\u8bd1\u540e\u5f97\u5230\u7684\u6c47\u7f16\u4ee3\u7801\u6587\u4ef6\u4ee5 .s \u4e3a\u540e\u7f00\u3002
  3. \u6c47\u7f16\uff1a\u7531\u6c47\u7f16\u5668\uff08Assembler\uff09\u5b8c\u6210\uff0c\u5b83\u5c06\u6c47\u7f16\u4ee3\u7801\u7ffb\u8bd1\u6210\u673a\u5668\u8bed\u8a00\u3002\u6c47\u7f16\u540e\u5f97\u5230\u7684\u673a\u5668\u4ee3\u7801\u6587\u4ef6\u4ee5 .o \u4e3a\u540e\u7f00\u3002
  4. \u94fe\u63a5\uff1a\u7531\u94fe\u63a5\u5668\uff08Linker\uff09\u5b8c\u6210\uff0c\u5b83\u5c06\u591a\u4e2a\u76ee\u6807\u6587\u4ef6\u94fe\u63a5\u6210\u4e00\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\u3002\u94fe\u63a5\u540e\u5f97\u5230\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4ee5 .exe \u4e3a\u540e\u7f00\u3002
"},{"location":"programming_lecture/lecture1/lecture1/#gcc","title":"\u89e3\u8bfb gcc \u663e\u793a\u7684\u8be6\u7ec6\u4fe1\u606f","text":"

\u4e0b\u9762\u8fd9\u4e9b\u6587\u672c\u662f gcc -v -o prog main.c sum.c \u547d\u4ee4\u7684\u8f93\u51fa\u7ed3\u679c\u3002

gcc \u7684\u8f93\u51fa\u4fe1\u606f

\u70b9\u51fb\u6587\u672c\u4e2d\u5e26\u5706\u5708\u7684 + \u53f7\u53ef\u4ee5\u5c55\u5f00\u8be6\u7ec6\u4fe1\u606f\uff0c\u9ad8\u4eae\u7684\u884c\u662f\u8fd0\u884c\u67d0\u4e2a\u7f16\u8bd1\u5de5\u5177\u7684\u5177\u4f53\u547d\u4ee4\u3002

<!--(1)!-->Using built-in specs.\nCOLLECT_GCC=gcc\nCOLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper\nOFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa\nOFFLOAD_TARGET_DEFAULT=1\nTarget: x86_64-linux-gnu\nConfigured with: ../src/configure -v --with-pkgversion='Ubuntu 12.3.0-1ubuntu1~23.04' --with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-12 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-DAPbBt/gcc-12-12.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu\nThread model: posix\nSupported LTO compression algorithms: zlib zstd\ngcc version 12.3.0 (Ubuntu 12.3.0-1ubuntu1~23.04) \nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'\n<!--(2)!--> /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpdir prog- -dumpbase main.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s\nGNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)\n    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP\n\nGGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072\nignoring nonexistent directory \"/usr/local/include/x86_64-linux-gnu\"\nignoring nonexistent directory \"/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed\"\nignoring nonexistent directory \"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include\"\n<!--(3)!-->#include \"...\" search starts here:\n#include <...> search starts here:\n /usr/lib/gcc/x86_64-linux-gnu/12/include\n /usr/local/include\n /usr/include/x86_64-linux-gnu\n /usr/include\nEnd of search list.\nGNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)\n    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP\n\nGGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072\nCompiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024\nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'\n<!--(4)!--> as -v --64 -o /tmp/ccEgqpgY.o /tmp/ccClT5M4.s\nGNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40\nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'\n<!--(5)!--> /usr/lib/gcc/x86_64-linux-gnu/12/cc1 -quiet -v -imultiarch x86_64-linux-gnu sum.c -quiet -dumpdir prog- -dumpbase sum.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccClT5M4.s\nGNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)\n    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP\n\nGGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072\nignoring nonexistent directory \"/usr/local/include/x86_64-linux-gnu\"\nignoring nonexistent directory \"/usr/lib/gcc/x86_64-linux-gnu/12/include-fixed\"\nignoring nonexistent directory \"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include\"\n#include \"...\" search starts here:\n#include <...> search starts here:\n /usr/lib/gcc/x86_64-linux-gnu/12/include\n /usr/local/include\n /usr/include/x86_64-linux-gnu\n /usr/include\nEnd of search list.\nGNU C17 (Ubuntu 12.3.0-1ubuntu1~23.04) version 12.3.0 (x86_64-linux-gnu)\n    compiled by GNU C version 12.3.0, GMP version 6.2.1, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.25-GMP\n\nGGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072\nCompiler executable checksum: d9353c3f0a32d3e91a16ba312e2a9024\nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog-'\n as -v --64 -o /tmp/ccxMA26W.o /tmp/ccClT5M4.s\nGNU assembler version 2.40 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.40\nCOMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/\nLIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/12/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/12/../../../:/lib/:/usr/lib/\nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.'\n<!--(6)!--> /usr/lib/gcc/x86_64-linux-gnu/12/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/12/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper -plugin-opt=-fresolution=/tmp/ccyzC2ZB.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o prog /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/12/../../.. /tmp/ccEgqpgY.o /tmp/ccxMA26W.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o\nCOLLECT_GCC_OPTIONS='-v' '-o' 'prog' '-mtune=generic' '-march=x86-64' '-dumpdir' 'prog.'\n
  1. \u6700\u5f00\u5934\u662f gcc \u7684\u76f8\u5173\u4fe1\u606f\uff0c\u5305\u62ec\u5b83\u8fd0\u884c\u7684\u5e73\u53f0\u3001\u914d\u7f6e\u7684\u9009\u9879\u7b49\u3002
  2. \u8fd9\u91cc\u8c03\u7528\u4e86 cc1 \u5b8c\u6210\u9884\u5904\u7406\u548c\u7f16\u8bd1\u9636\u6bb5\uff0c\u5c06\u6e90\u4ee3\u7801\u6587\u4ef6 main.c \u7f16\u8bd1\u6210\u4e86 ASCII \u7f16\u7801\u7684\u6c47\u7f16\u6587\u4ef6 /tmp/ccCWi0p2.s\u3002
  3. \u8fd9\u91cc\u663e\u793a\u4e86\u5934\u6587\u4ef6\u641c\u7d22\u8def\u5f84\uff0c\u5982\u679c\u4f60\u7f16\u8bd1\u65f6\u62a5\u9519\u7f3a\u5c11\u5934\u6587\u4ef6\uff0c\u53ef\u4ee5\u68c0\u67e5\u4e00\u4e0b\u8fd9\u91cc\u6709\u6ca1\u6709\u5305\u542b\u5bf9\u5e94\u7684\u8def\u5f84\u3002
  4. \u8fd9\u91cc\u8c03\u7528\u4e86 as \u5b8c\u6210\u6c47\u7f16\u9636\u6bb5\uff0c\u5c06\u6c47\u7f16\u6587\u4ef6 /tmp/ccCWi0p2.s \u7ffb\u8bd1\u6210\u4e86\u673a\u5668\u8bed\u8a00\u6587\u4ef6 /tmp/ccAnKDEo.o\u3002
  5. \u63a5\u4e0b\u6765\u53c8\u5bf9 sum.c \u91cd\u590d\u9884\u5904\u7406\u3001\u7f16\u8bd1\u548c\u6c47\u7f16\u7684\u8fc7\u7a0b\uff0c\u5f97\u5230\u4e86 /tmp/ccgMFTqK.o\u3002
  6. \u6700\u540e\u8c03\u7528 collect2 \uff08\u8fd9\u662f ld \u7684\u5305\u88c5\u7a0b\u5e8f\uff09\u5b8c\u6210\u94fe\u63a5\u9636\u6bb5\uff0c\u5c06\u4e24\u4e2a\u6e90\u4ee3\u7801\u751f\u6210\u7684\u76ee\u6807\u6587\u4ef6 /tmp/ccAnKDEo.o \u548c /tmp/ccgMFTqK.o \u4e0e\u5176\u4ed6\u5f88\u591a\u76ee\u6807\u6587\u4ef6\u94fe\u63a5\u6210\u4e86\u53ef\u6267\u884c\u6587\u4ef6 prog\u3002\u8fd9\u5c31\u662f\u4f60\u80fd\u5728\u64cd\u4f5c\u7cfb\u7edf\u4e0a\u8fd0\u884c\u7684\u7a0b\u5e8f\u3002
\u4e3a\u4ec0\u4e48\u6ca1\u6709\u770b\u89c1\u9884\u5904\u7406\u5668 cpp \u7684\u6267\u884c\u5462\uff1f

\u67d0\u4e9b\u7248\u672c\u7684 gcc \u4f1a\u5c06\u9884\u5904\u7406\u5668 cpp \u548c\u7f16\u8bd1\u5668 gcc \u5408\u5e76\u6210\u4e00\u4e2a\u6307\u4ee4\uff0c\u6bd4\u5982\u4e0a\u9762\u7684 cc1\uff0c\u8fd9\u6837\u5c31\u4e0d\u7528\u5355\u72ec\u8c03\u7528 cpp \u4e86\u3002

\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u8be6\u89e3\u5176\u4e2d\u7684\u6bcf\u4e00\u4e2a\u9636\u6bb5\u4ee5\u53ca\u53ef\u80fd\u4f1a\u53d1\u751f\u7684\u95ee\u9898\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_11","title":"\u9884\u5904\u7406","text":"

\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u67e5\u770b\u9884\u5904\u7406\u540e\u7684\u6587\u4ef6 hello.i\uff1a

cpp hello.c > hello.i\n

\u4f60\u4f1a\u53d1\u73b0\uff0c\u539f\u6765 hello.c \u4e2d #include \u9884\u5904\u7406\u6307\u4ee4\u7684\u5730\u65b9\u88ab\u66ff\u6362\u4e3a\u5b8c\u6574\u7684 stdio.h \u6587\u4ef6\u5185\u5bb9\uff0c\u8fd9\u4e9b\u5185\u5bb9\u5305\u62ec printf \u7b49\u51fd\u6570\u7684\u539f\u578b\u3002\u5176\u4ed6\u9884\u5904\u7406\u6307\u4ee4\uff08\u5728\u540e\u7eed\u8bfe\u7a0b\u4f1a\u5b66\u4e60\u5230\uff09\u6bd4\u5982 #define \u4e5f\u4f1a\u5728\u8fd9\u4e00\u9636\u6bb5\u751f\u6548\u3002\u81f3\u4e8e\u4e3a\u4ec0\u4e48\u53ea\u63d2\u5165\u4e86\u51fd\u6570\u539f\u578b\u800c\u6ca1\u6709\u5b9a\u4e49\uff0c\u63a5\u4e0b\u6765\u7684\u94fe\u63a5\u9636\u6bb5\u4f1a\u89e3\u7b54\u3002

\u9884\u5904\u7406\u9636\u6bb5\u6700\u7ecf\u5e38\u4ea7\u751f\u7684\u95ee\u9898\u662f\u627e\u4e0d\u5230\u5934\u6587\u4ef6\u3002C \u8bed\u8a00\u5934\u6587\u4ef6\u641c\u7d22\u89c4\u5219\u5982\u4e0b\uff1a

  • \u7528\u53cc\u5f15\u53f7 #include \"...\" \u5305\u542b\u7684\u5934\u6587\u4ef6\uff0c\u7f16\u8bd1\u5668\u4f1a\u5148\u5728\u5f53\u524d\u76ee\u5f55\u4e0b\u67e5\u627e\uff0c\u518d\u5728\u7cfb\u7edf\u76ee\u5f55\u4e0b\u67e5\u627e\u3002
  • \u7528\u5c16\u62ec\u53f7 #include <...> \u5305\u542b\u7684\u5934\u6587\u4ef6\uff0c\u7f16\u8bd1\u5668\u53ea\u4f1a\u5728\u7cfb\u7edf\u76ee\u5f55\u4e0b\u67e5\u627e\u3002

\u5982\u679c\u4f60\u7684\u5934\u6587\u4ef6\u4e0d\u5728\u5f53\u524d\u76ee\u5f55\u4e0b\uff0c\u90a3\u4e48\u4f60\u9700\u8981\u4f7f\u7528 -I \u9009\u9879\u544a\u8bc9\u7f16\u8bd1\u5668\u5934\u6587\u4ef6\u7684\u4f4d\u7f6e\u3002\u6bd4\u5982\u4f60\u7684\u5934\u6587\u4ef6\u5728 include \u76ee\u5f55\u4e0b\uff1a

.\n\u251c\u2500\u2500 hello.c\n\u2514\u2500\u2500 include\n \u00a0\u00a0 \u2514\u2500\u2500 header.h\n

\u4f60\u53ef\u4ee5\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u7f16\u8bd1\uff1a

gcc -Iinclude -o hello hello.c\n

\u8def\u5f84\u53ef\u4ee5\u662f\u76f8\u5bf9\u8def\u5f84\u6216\u7edd\u5bf9\u8def\u5f84\uff0c\u6bd4\u5982\uff1a

gcc -I../include -o hello hello.c\ngcc -I/home/user/include -o hello hello.c\n

\u53e6\u4e00\u79cd\u65b9\u5f0f\u662f\u8bbe\u7f6e\u73af\u5883\u53d8\u91cf CPATH \u6307\u5b9a\u641c\u7d22\u8def\u5f84\u3002

export CPATH=\"$HOME/.local:$CPATH\"\n

\u8bbe\u7f6e\u540e\uff0c\u4f60\u5e94\u5f53\u80fd\u5728\u7f16\u8bd1\u5668\u7684\u8f93\u51fa\u4fe1\u606f\u4e2d\u770b\u5230\u65b0\u589e\u7684\u8def\u5f84\u3002

#include <...> search starts here:\n /home/bowling/.local\n
"},{"location":"programming_lecture/lecture1/lecture1/#_12","title":"\u7f16\u8bd1","text":"

\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u67e5\u770b\u7f16\u8bd1\u540e\u7684\u6587\u4ef6 hello.s\uff1a

gcc -S hello.i\n

\u6240\u6709\u9ad8\u7ea7\u8bed\u8a00\u5c42\u9762\u7684\u7c7b\u578b\u3001\u63a7\u5236\u7ed3\u6784\u7b49\uff0c\u90fd\u88ab\u4e0e\u7279\u5b9a CPU \u6307\u4ee4\u96c6\u76f8\u5173\u7684\u6c47\u7f16\u6307\u4ee4\u4ee3\u66ff\u3002\u5728\u6c47\u7f16\u8bed\u8a00\u4e2d\uff0c\u6240\u6709\u6570\u636e\u90fd\u662f\u5b57\u8282\u5757\uff0c\u6ca1\u6709\u7c7b\u578b\u7684\u6982\u5ff5\u3002

\u5728\u8fd9\u4e2a\u9636\u6bb5\uff0c\u7f16\u8bd1\u5668\u4f1a\u68c0\u67e5\u4e00\u4e9b\u95ee\u9898\uff0c\u5e76\u629b\u51fa\u4e0d\u540c\u7b49\u7ea7\u7684\u4fe1\u606f\uff1a

  • \u9519\u8bef\uff08Error\uff09\uff1a\u7f16\u8bd1\u5668\u65e0\u6cd5\u7ee7\u7eed\u8fdb\u884c\u7f16\u8bd1\u3002\u6bd4\u5982\uff1a\u63d0\u4f9b\u7684\u53c2\u6570\u5217\u8868\u4e0d\u5339\u914d\u3001\u4f7f\u7528\u4e86\u672a\u5b9a\u4e49\u7684\u53d8\u91cf\u3001\u51fd\u6570\u7b49\u3002
error.c: In function \u2018main\u2019:\nerror.c:9:5: error: too many arguments to function \u2018my_print\u2019\n    9 |     my_print(1);\n      |     ^~~~~~~~\nerror.c:4:6: note: declared here\n    4 | void my_print(void)\n      |      ^~~~~~~~\n
  • \u8b66\u544a\uff08Warning\uff09\uff1a\u8fdd\u53cd\u4e86\u8bed\u6cd5\uff0c\u4f46\u80fd\u591f\u7ee7\u7eed\u7f16\u8bd1\uff0c\u7f16\u8bd1\u51fa\u6765\u7684\u7a0b\u5e8f\u8fd0\u884c\u7ed3\u679c\u5f88\u53ef\u80fd\u4e0e\u4f60\u60f3\u8c61\u7684\u4e0d\u4e00\u6837\u3002\u6bd4\u5982\uff1a\u8f6c\u4e49\u5b57\u7b26\u4e0e\u6570\u636e\u7c7b\u578b\u4e0d\u5339\u914d\u3001\u53d1\u751f\u4e86\u9690\u5f0f\u8f6c\u6362\u7b49\u3002
warning.c: In function \u2018main\u2019:\nwarning.c:8:18: warning: format \u2018%d\u2019 expects argument of type \u2018int\u2019, but argument 2 has type \u2018double\u2019 [-Wformat=]\n    8 |     printf(\"a = %d\\n\", a);\n      |                 ~^     ~\n      |                  |     |\n      |                  int   double\n      |                 %f\n

\u5927\u90e8\u5206\u8b66\u544a\u4fe1\u606f\u9ed8\u8ba4\u4e0d\u4f1a\u8f93\u51fa\uff0c\u4f7f\u7528 -Wall \u548c -Wextra \u9009\u9879\u53ef\u4ee5\u6253\u5f00\u66f4\u591a\u7684\u8b66\u544a\u4fe1\u606f\u3002\u4f60\u4e5f\u53ef\u4ee5\u4f7f\u7528 -Werror \u9009\u9879\u5c06\u8b66\u544a\u4fe1\u606f\u89c6\u4e3a\u9519\u8bef\uff0c\u8fd9\u6837\u7f16\u8bd1\u5668\u5c31\u4f1a\u505c\u6b62\u7f16\u8bd1\u3002\u5728\u7f16\u8bd1\u65f6\u5e26\u4e0a\u8fd9\u4e9b\u53c2\u6570\u662f\u4e00\u4e2a\u597d\u4e60\u60ef\u3002

gcc -Wall -Wextra -Werror -o hello hello.c\n
"},{"location":"programming_lecture/lecture1/lecture1/#_13","title":"\u6c47\u7f16","text":"

\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff0c\u6c47\u7f16\u5668\u5c06\u6c47\u7f16\u6307\u4ee4\u7ffb\u8bd1\u4e3a\u673a\u5668\u7801\uff0c\u4ea7\u751f\u53ef\u91cd\u5b9a\u4f4d\u76ee\u6807\u6587\u4ef6 hello.o\uff1a

as -o hello.o hello.s\n
\u76ee\u6807\u6587\u4ef6

\u76ee\u6807\u6587\u4ef6\u4e2d\u5305\u542b\u8ba1\u7b97\u673a\u80fd\u8bfb\u61c2\u7684\u673a\u5668\u4ee3\u7801\u548c\u6570\u636e\uff0c\u6709\u4e09\u79cd\u5f62\u5f0f\uff1a

\u5f62\u5f0f \u7531\u8c01\u4ea7\u751f \u6709\u4ec0\u4e48\u7528 \u53ef\u91cd\u5b9a\u4f4d\u76ee\u6807\u6587\u4ef6 \u7f16\u8bd1\u5668\u6216\u6c47\u7f16\u5668 \u53ea\u5305\u542b\u7f16\u8bd1\u5668\u4e3a\u4f60\u7f16\u5199\u7684\u4ee3\u7801\u7ffb\u8bd1\u7684\u673a\u5668\u8bed\u8a00\u4ee3\u7801\uff0c\u9700\u8981\u4e0e\u5176\u4ed6\u76ee\u6807\u6587\u4ef6\u94fe\u63a5\u5408\u5e76\u4e3a\u53ef\u6267\u884c\u76ee\u6807\u6587\u4ef6 \u53ef\u6267\u884c\u76ee\u6807\u6587\u4ef6 \u94fe\u63a5\u5668 \u5305\u542b\u4f60\u7f16\u5199\u7684\u7a0b\u5e8f\u4e2d\u4f7f\u7528\u7684\u5e93\u51fd\u6570\u548c\u542f\u52a8\u4ee3\u7801\u7684\u673a\u5668\u4ee3\u7801\uff0c\u80fd\u591f\u88ab\u64cd\u4f5c\u7cfb\u7edf\u6b63\u786e\u8fd0\u884c \u5171\u4eab\u76ee\u6807\u6587\u4ef6 \u7f16\u8bd1\u5668\u6216\u6c47\u7f16\u5668 \u7ed9\u5176\u4ed6\u7a0b\u5e8f\u7528\u7684\u4ee3\u7801\uff0c\u53ef\u4ee5\u5728\u7a0b\u5e8f\u52a0\u8f7d\u6216\u8fd0\u884c\u65f6\u94fe\u63a5

hello.o \u4e2d\u5305\u542b\u4e86 hello.c \u4e2d\u7684 C \u8bed\u8a00\u4ee3\u7801\u7ffb\u8bd1\u6210\u7684\u4e8c\u8fdb\u5236\u4ee3\u7801\u4ee5\u53ca\u4e00\u4e9b\u6570\u636e\uff0c\u6bd4\u5982\u5b57\u7b26\u4e32 Hello, world.\\n\u3002\u5982\u679c\u4f7f\u7528\u6587\u672c\u7f16\u8f91\u5668\u6253\u5f00 hello.o\uff0c\u4f60\u4f1a\u770b\u89c1\u4e00\u5806\u4e71\u7801\uff0c\u5176\u4e2d\u5939\u6742\u7740\u4e00\u4e9b\u5b57\u7b26\u3002\u56e0\u4e3a\u5b57\u7b26\u5728\u6e90\u6587\u4ef6\u548c\u5185\u5b58\u4e2d\u90fd\u662f\u7528 ASCII \u7f16\u7801\u7684\uff0c\u6240\u4ee5 ASCII \u5b57\u7b26\u4ecd\u80fd\u88ab\u6587\u672c\u7f16\u8f91\u5668\u8bc6\u522b\uff0c\u4f46\u5176\u4ed6\u7684\u673a\u5668\u6307\u4ee4\u548c\u6570\u636e\u53ea\u4f1a\u88ab\u89e3\u8bfb\u4e3a\u4e71\u7801\u3002

\u5982\u679c\u8fd0\u884c ./hello.o\uff0c\u7ec8\u7aef\u4f1a\u544a\u8bc9\u4f60\u8fd9\u4e2a\u6587\u4ef6\u4e0d\u80fd\u88ab\u64cd\u4f5c\u7cfb\u7edf\u6267\u884c\u3002

exec: Failed to execute process: './hello.o' the file could not be run by the operating system.\n

\u5b83\u8fd8\u7f3a\u5c11\u4e00\u4e9b\u4e1c\u897f\uff0c\u5982\uff1a

  • \u542f\u52a8\u4ee3\u7801\uff1a\u542f\u52a8\u7a0b\u5e8f\u65f6\uff0c\u64cd\u4f5c\u7cfb\u7edf\u4f1a\u5c06\u63a7\u5236\u6743\u4ea4\u7ed9\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\uff0c\u4f46\u8fd9\u4e2a\u5165\u53e3\u70b9\u4e0d\u662f main \u51fd\u6570\uff0c\u800c\u662f\u4e00\u4e9b\u542f\u52a8\u4ee3\u7801\u3002\u542f\u52a8\u4ee3\u7801\u5728\u6267\u884c main \u524d\u8fdb\u884c\u4e00\u4e9b\u521d\u59cb\u5316\u5de5\u4f5c\uff0c\u5e76\u5728\u9000\u51fa main \u540e\u505a\u4e00\u4e9b\u626b\u5c3e\u5de5\u4f5c\u3002
\u4e00\u4e2a\u4e0d\u5e26\u542f\u52a8\u4ee3\u7801\u7684\u4f8b\u5b50

Linux \u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u4e00\u822c\u662f _start\uff0c\u5b83\u5b8c\u6210\u4e00\u4e9b\u5185\u5b58\u521d\u59cb\u5316\u7684\u5de5\u4f5c\uff0c\u7136\u540e\u8df3\u8f6c\u5230 main \u51fd\u6570\u3002\u6211\u4eec\u5728\u94fe\u63a5\u9636\u6bb5\u4e0d\u5e26\u4e0a\u542b\u6709\u542f\u52a8\u4ee3\u7801\u7684\u76ee\u6807\u6587\u4ef6\uff0c\u770b\u770b\u5728\u7f3a\u5c11 _start \u7684\u60c5\u51b5\u4e0b\u4f1a\u53d1\u751f\u4ec0\u4e48\u3002

$ ld hello.o -o hello -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2\nld: warning: cannot find entry symbol _start; defaulting to 0000000000401030\n$ ./hello\nHello World.\nfish: Job 1, './hello' terminated by signal SIGSEGV (Address boundary error)\n

\u8fd9\u4e2a\u7a0b\u5e8f\u6e90\u4ee3\u7801\u6b63\u5e38\uff0c\u4e3a\u4ec0\u4e48\u4f1a\u51fa\u73b0\u6bb5\u9519\u8bef\u5462\uff1f

\u5728\u94fe\u63a5\u9636\u6bb5\uff0cld \u7684\u8f93\u51fa\u8868\u660e\u627e\u4e0d\u5230\u5165\u53e3\u70b9 _start\uff0c\u56e0\u6b64\u628a\u5165\u53e3\u70b9\u9ed8\u8ba4\u653e\u5728\u4e86 0000000000401030 \u5904\u7684\u51fd\u6570\u3002\u8fd9\u4e2a\u51fd\u6570\u662f main \u51fd\u6570\u3002\u56e0\u6b64\uff0c\u5f53\u7a0b\u5e8f\u6267\u884c\u5230 main \u51fd\u6570\u7684\u6700\u540e\u4e00\u6761\u6307\u4ee4\u65f6\uff0c\u4f1a\u7ee7\u7eed\u5f80\u4e0b\u6267\u884c\uff0c\u4f46\u6b64\u65f6\u6808\u5df2\u7ecf\u88ab\u6e05\u7a7a\uff0c\u56e0\u6b64\u4f1a\u53d1\u751f\u6bb5\u9519\u8bef\u3002

\u4f7f\u7528 gdb \u67e5\u770b\u9519\u8bef\u4f4d\u7f6e\uff1a

Program received signal SIGSEGV, Segmentation fault.\n0x0000000000000001 in ?? ()\n

\u8bc1\u5b9e\u4e86\u4e0a\u9762\u7684\u5206\u6790\u3002

crt \u662f C Runtime \u7684\u7f29\u5199\u3002C \u8bed\u8a00\u76f8\u5173\u542f\u52a8\u4ee3\u7801\u5728\u8fd9\u4e9b\u76ee\u6807\u6587\u4ef6\u4e2d\uff1a

  • crt1.o\uff1a\u8d1f\u8d23\u542f\u52a8\uff0c\u5305\u542b _start \u548c\u672a\u5b9a\u4e49\u7684 __libc_start_main \u548c main\u3002
  • crti.o\uff1a\u521d\u59cb\u5316
  • crtbegin.o\uff1a\u6784\u9020\uff08C++\u4f9d\u8d56\uff09
  • crtend.o\uff1a\u6790\u6784\uff08C++\u4f9d\u8d56\uff09
  • crtn.o\uff1a\u7ed3\u675f

Linux \u5e73\u53f0\u4e0b\uff0c\u5b83\u4eec\u7684\u94fe\u63a5\u987a\u5e8f\u4e3a\uff1a

ld crt1.o crti.o [user_objects] [system_libraries] crtn.o\n
  • \u5e93\u51fd\u6570\uff1a\u51e0\u4e4e\u6240\u6709 C \u7a0b\u5e8f\u90fd\u4f1a\u7528\u5230\u6807\u51c6\u5e93\u4e2d\u7684\u51fd\u6570\uff0c\u6bd4\u5982 printf\u3002\u6807\u51c6\u5e93\u4e2d\u7684\u4ee3\u7801\u5df2\u7ecf\u88ab\u9884\u7f16\u8bd1\u6210\u76ee\u6807\u6587\u4ef6\uff0c\u9644\u5728\u7f16\u8bd1\u5668\u7684\u5b89\u88c5\u76ee\u5f55\u4e0b\u3002

\u5728\u63a5\u4e0b\u6765\u7684\u94fe\u63a5\u6b65\u9aa4\uff0c\u6211\u4eec\u5c06\u8fd9\u4e9b\u76ee\u6807\u6587\u4ef6\u94fe\u63a5\u5230\u6211\u4eec\u7684\u7a0b\u5e8f\u4e2d\uff0c\u751f\u6210\u53ef\u4ee5\u6267\u884c\u7684\u7a0b\u5e8f\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_14","title":"\u94fe\u63a5","text":"

\u94fe\u63a5\u6709\u4e24\u79cd\u7c7b\u578b\uff1a\u9759\u6001\u94fe\u63a5\u548c\u52a8\u6001\u94fe\u63a5\u3002

\u9759\u6001\u94fe\u63a5

\u5982\u679c\u4f60\u7684\u7a0b\u5e8f\u4e0e\u9759\u6001\u5e93\u94fe\u63a5\uff0c\u90a3\u4e48\u94fe\u63a5\u5668\u4f1a\u5c06\u9759\u6001\u5e93\u4e2d\u7684\u4ee3\u7801\u590d\u5236\u5230\u4f60\u7684\u7a0b\u5e8f\u4e2d\u3002\u8fd9\u6837\uff0c\u4f60\u7684\u7a0b\u5e8f\u5c31\u4e0d\u518d\u4f9d\u8d56\u9759\u6001\u5e93\u4e86\uff0c\u53ef\u4ee5\u5728\u4efb\u4f55\u5730\u65b9\u8fd0\u884c\u3002\u4f46\u662f\uff0c\u5982\u679c\u9759\u6001\u5e93\u4e2d\u7684\u4ee3\u7801\u53d1\u751f\u4e86\u53d8\u5316\uff0c\u4f60\u7684\u7a0b\u5e8f\u5e76\u4e0d\u4f1a\u81ea\u52a8\u66f4\u65b0\uff0c\u4f60\u9700\u8981\u91cd\u65b0\u7f16\u8bd1\u4f60\u7684\u7a0b\u5e8f\u3002

\u5728 Linux \u7cfb\u7edf\u4e0a\uff0c\u9759\u6001\u5e93\u7684\u6587\u4ef6\u540d\u4ee5 .a \u7ed3\u5c3e\uff0c\u6bd4\u5982 libm.a\u3002\u5728 Window \u4e0a\uff0c\u9759\u6001\u5e93\u7684\u6587\u4ef6\u540d\u4ee5 .lib \u7ed3\u5c3e\uff0c\u6bd4\u5982 libm.lib\u3002\u9759\u6001\u5e93\u53ef\u4ee5\u4f7f\u7528 ar \uff08archive program\uff09\u5de5\u5177\u521b\u5efa\u3002

\u52a8\u6001\u94fe\u63a5

\u5f53\u4f60\u7684\u7a0b\u5e8f\u4e0e\u52a8\u6001\u5e93\u94fe\u63a5\u65f6\uff0c\u7a0b\u5e8f\u4e2d\u521b\u5efa\u4e86\u4e00\u4e2a\u8868\u3002\u5728\u7a0b\u5e8f\u8fd0\u884c\u524d\uff0c\u64cd\u4f5c\u7cfb\u7edf\u5c06\u9700\u8981\u7684\u5916\u90e8\u51fd\u6570\u7684\u673a\u5668\u7801\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u8fd9\u5c31\u662f\u52a8\u6001\u94fe\u63a5\u8fc7\u7a0b\u3002

\u4e0e\u9759\u6001\u94fe\u63a5\u76f8\u6bd4\uff0c\u52a8\u6001\u94fe\u63a5\u4f7f\u7a0b\u5e8f\u6587\u4ef6\u66f4\u5c0f\uff0c\u56e0\u4e3a\u4e00\u4e2a\u52a8\u6001\u5e93\u53ef\u4ee5\u88ab\u591a\u4e2a\u7a0b\u5e8f\u5171\u4eab\uff0c\u8282\u7701\u78c1\u76d8\u7a7a\u95f4\u3002\u90e8\u5206\u64cd\u4f5c\u7cfb\u7edf\u8fd8\u5141\u8bb8\u52a8\u6001\u5e93\u4ee3\u7801\u5728\u5185\u5b58\u4e2d\u7684\u5171\u4eab\uff0c\u8fd8\u80fd\u591f\u8282\u7701\u5185\u5b58\u3002\u52a8\u6001\u5e93\u5347\u7ea7\u65f6\uff0c\u4e5f\u4e0d\u9700\u8981\u91cd\u5199\u7f16\u8bd1\u4f60\u7684\u7a0b\u5e8f\u3002

\u5728 Linux \u7cfb\u7edf\u4e0a\uff0c\u52a8\u6001\u5e93\u7684\u6587\u4ef6\u540d\u4ee5 .so \u7ed3\u5c3e\uff0c\u6bd4\u5982 libm.so\u3002\u5728 Window \u4e0a\uff0c\u52a8\u6001\u5e93\u7684\u6587\u4ef6\u540d\u4ee5 .dll \u7ed3\u5c3e\uff0c\u6bd4\u5982 libm.dll\u3002

\u52a8\u6001\u94fe\u63a5\u5177\u6709\u4e0a\u9762\u63cf\u8ff0\u7684\u4f18\u70b9\uff0c\u56e0\u6b64 GCC \u5c3d\u53ef\u80fd\u5730\u6267\u884c\u52a8\u6001\u94fe\u63a5\u3002

\u94fe\u63a5\u76f8\u5173\u7684\u95ee\u9898\u53ef\u80fd\u51fa\u73b0\u5728\u94fe\u63a5\u65f6\uff08\u9759\u6001\u94fe\u63a5\uff09\u3001\u7a0b\u5e8f\u8fd0\u884c\u524d\u548c\u8fd0\u884c\u4e2d\uff08\u52a8\u6001\u94fe\u63a5\uff09\u3002\u4e0b\u9762\u65f6\u4e00\u4e9b\u5e38\u89c1\u7684\u95ee\u9898\u3002

\u672a\u5b9a\u4e49\u7684\u5f15\u7528

\u5f53\u540c\u5b66\u4eec\u5f00\u59cb\u4f7f\u7528\u5176\u4ed6\u5e93\u6784\u5efa\u5927\u578b\u9879\u76ee\u65f6\uff0c\u8fd9\u6216\u8bb8\u4f1a\u6210\u4e3a\u6700\u5934\u75bc\u7684\u95ee\u9898\u3002\u9996\u5148\u5e94\u5f53\u9605\u8bfb\u5e93\u7684\u4f7f\u7528\u8bf4\u660e\uff0c\u63a5\u4e0b\u6765\u641c\u7d22\u7f3a\u5931\u7684\u7b26\u53f7\u53ef\u80fd\u4f4d\u4e8e\u54ea\u4e9b\u5e93\u6587\u4ef6\u4e2d\u3002

\u7f3a\u5931 .dll

\u5e38\u7528 Windows \u7684\u540c\u5b66\u591a\u591a\u5c11\u5c11\u89c1\u8fc7\u8fd9\u4e2a\u62a5\u9519\uff0c\u53ef\u4ee5\u53bb\u7f51\u4e0a\u641c\u7d22\u76f8\u5e94 .dll \u6587\u4ef6\u653e\u7f6e\u5230\u6b63\u786e\u7684\u76ee\u5f55\u3002

\u7f3a\u5931 .so

Linux \u4e0a\u7684\u52a8\u6001\u5e93\u4e00\u822c\u901a\u8fc7 apt \u7ba1\u7406\uff0c\u641c\u7d22\u76f8\u5e94\u7684\u5305\u5e76\u5b89\u88c5\u5373\u53ef\u3002

\u4e0b\u9762\u8fd9\u884c\u547d\u4ee4\u5728\u6211\u7684\u7cfb\u7edf\u4e0a\u5b8c\u6210\u4e86 hello \u7a0b\u5e8f\u7684\u6b63\u786e\u94fe\u63a5\uff0c\u4e0d\u4e00\u5b9a\u80fd\u5728\u4f60\u7684\u7cfb\u7edf\u4e0a\u8fd0\u884c\u3002\u4f60\u53ef\u4ee5\u5c1d\u8bd5\u67e5\u627e\u5e93\u6587\u4ef6\u7684\u8def\u5f84\uff0c\u8ba9\u5b83\u6210\u529f\u8fd0\u884c\u3002

ld --output hello --dynamic-linker /lib64/ld-linux-x86-64.so.2  /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crti.o -lc hello.o /usr/lib/gcc/x86_64-linux-gnu/12/../../../x86_64-linux-gnu/crtn.o\n
"},{"location":"programming_lecture/lecture1/lecture1/#_15","title":"\u52a8\u6001\u94fe\u63a5\u8fc7\u7a0b","text":"

\u5982\u679c\u4e00\u4e2a\u53ef\u6267\u884c\u6587\u4ef6\u4f9d\u8d56\u4e8e\u52a8\u6001\u5e93\uff0c\u90a3\u4e48\u7a0b\u5e8f\u8fd0\u884c\u524d\uff0c\u52a8\u6001\u94fe\u63a5\u5668\uff08interpreter\uff09\u4f1a\u88ab\u5148\u52a0\u8f7d\u8fd0\u884c\u3002\u5b83\u5c06\u5bfb\u627e\u9700\u8981\u7684\u52a8\u6001\u5e93\uff0c\u52a0\u8f7d\u5230\u5185\u5b58\u4e2d\uff0c\u7136\u540e\u5c06\u63a7\u5236\u6743\u4ea4\u7ed9\u7a0b\u5e8f\u7684\u5165\u53e3\u70b9\u3002

ld \u7684\u9009\u9879 --dynamic-linker \u5c31\u6307\u5b9a\u4e86\u52a8\u6001\u94fe\u63a5\u5668\u7684\u8def\u5f84\u3002\u76ee\u524d Linux \u7cfb\u7edf\u4f7f\u7528\u7684\u52a8\u6001\u94fe\u63a5\u5668\u4e00\u822c\u662f /lib64/ld-linux-x86-64.so.2\u3002\u5b83\u4e5f\u662f\u4e00\u4e2a\u53ef\u4ee5\u76f4\u63a5\u8fd0\u884c\u7684\u7a0b\u5e8f\uff0c\u4f60\u53ef\u4ee5\u8bd5\u8bd5\u8fd0\u884c\u5b83\uff1a

$ /lib64/ld-linux-x86-64.so.2 --help\nYou have invoked 'ld.so', the program interpreter for dynamically-linked ELF programs.  Usually, the program interpreter is invoked automatically when a dynamically-linked executable is started.\n\nYou may invoke the program interpreter program directly from the command line to load and run an ELF executable file; this is like executing that file itself, but always uses the program interpreter you invoked, instead of the program interpreter specified in the executable file you run.  Invoking the program interpreter directly provides access to additional diagnostics, and changing the dynamic linker behavior without setting environment variables (which would be inherited by subprocesses).\n

\u8be5\u9009\u9879\u5c06\u4f1a\u5728\u53ef\u6267\u884c\u76ee\u6807\u6587\u4ef6\u524d\u9762\u52a0\u4e0a\u5bf9\u52a8\u6001\u94fe\u63a5\u5668\u7684\u8bf7\u6c42\u3002\u4f7f\u7528 readelf \u53ef\u4ee5\u67e5\u770b ELF \u683c\u5f0f\u53ef\u6267\u884c\u76ee\u6807\u6587\u4ef6\u7684\u5934\u90e8\u4fe1\u606f\u3002

$ readelf -l /usr/bin/ls | head -20\n\nElf file type is DYN (Shared object file)\nEntry point 0x6b10\nThere are 13 program headers, starting at offset 64\n\nProgram Headers:\n  Type           Offset             VirtAddr           PhysAddr\n                 FileSiz            MemSiz              Flags  Align\n  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040\n                 0x00000000000002d8 0x00000000000002d8  R      0x8\n  INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318\n                 0x000000000000001c 0x000000000000001c  R      0x1\n      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]\n  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000\n                 0x0000000000003510 0x0000000000003510  R      0x1000\n  LOAD           0x0000000000004000 0x0000000000004000 0x0000000000004000\n                 0x0000000000013111 0x0000000000013111  R E    0x1000\n  LOAD           0x0000000000018000 0x0000000000018000 0x0000000000018000\n                 0x0000000000007530 0x0000000000007530  R      0x1000\n  LOAD           0x000000000001ff70 0x0000000000020f70 0x0000000000020f70\n
"},{"location":"programming_lecture/lecture1/lecture1/#_16","title":"\u9759\u6001\u94fe\u63a5\u8fc7\u7a0b","text":"

\u8fdb\u884c\u9759\u6001\u94fe\u63a5\u65f6\u9700\u8981\u6ce8\u610f\u547d\u4ee4\u884c\u4e2d\u6587\u4ef6\u7684\u987a\u5e8f\u3002

  • \u5982\u679c\u662f\u76ee\u6807\u6587\u4ef6\uff0c\u94fe\u63a5\u5668\u5c06\u8bb0\u5f55\u5176\u4e2d\u7684\u7b26\u53f7\u5b9a\u4e49\u548c\u5f15\u7528\u3002
  • \u5982\u679c\u662f\u5e93\u6587\u4ef6\uff0c\u94fe\u63a5\u5668\u5c06\u5c1d\u8bd5\u5339\u914d\u524d\u9762\u8bb0\u5f55\u7684\u672a\u89e3\u6790\u7684\u7b26\u53f7\u5b9a\u4e49\u548c\u5f15\u7528\u3002\u89e3\u6790\u5b8c\u6210\u540e\uff0c\u8be5\u5e93\u4e2d\u6ca1\u6709\u88ab\u4f7f\u7528\u7684\u7b26\u53f7\u5c06\u88ab\u4e22\u5f03\u3002

\u770b\u770b\u4e0b\u9762\u7684\u547d\u4ee4\u884c\u53d1\u751f\u4e86\u4ec0\u4e48\uff1f

$ gcc -static ./libvector.a main2.c\n/tmp/cc9XH6Rp.o: In function `main':\nmain2.c:(.text+0x1a): undefined reference to `vector_add'\n

\u94fe\u63a5\u5668\u68c0\u67e5 libvector.a \u5e93\u6587\u4ef6\u65f6\uff0c\u8fd8\u6ca1\u6709\u8bb0\u5f55\u4efb\u4f55\u7b26\u53f7\u5b9a\u4e49\u548c\u5f15\u7528\uff0c\u56e0\u6b64\u5b83\u88ab\u6574\u4e2a\u4e22\u5f03\u4e86\u3002\u5f53\u94fe\u63a5\u5668\u5f00\u59cb\u68c0\u67e5 main2.c \u65f6\uff0c\u4e0d\u4f1a\u518d\u56de\u53bb\u627e libvector.a \u4e86\u3002

\u603b\u800c\u8a00\u4e4b\uff0c\u9759\u6001\u94fe\u63a5\u65f6\uff0c\u5e93\u6587\u4ef6\u4e00\u822c\u653e\u5728\u672b\u5c3e\u3002\u5982\u679c\u5e93\u6587\u4ef6\u4e4b\u95f4\u6709\u76f8\u4e92\u4f9d\u8d56\uff0c\u4e5f\u9700\u8981\u5bf9\u5b83\u4eec\u8fdb\u884c\u6392\u5e8f\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_17","title":"\u7a0b\u5e8f\u8c03\u8bd5\u6280\u672f","text":"\u6742\u8c08\uff1aBug \u7684\u5178\u6545

\u7f16\u7a0b\u662f\u4e00\u4ef6\u590d\u6742\u7684\u5de5\u4f5c\uff0c\u56e0\u4e3a\u662f\u4eba\u505a\u7684\u4e8b\u60c5\uff0c\u6240\u4ee5\u96be\u514d\u7ecf\u5e38\u51fa\u9519\u3002\u636e\u8bf4\u6709\u8fd9\u6837\u4e00\u4e2a\u5178\u6545\uff1a\u65e9\u671f\u7684\u8ba1\u7b97\u673a\u4f53\u79ef\u90fd\u5f88\u5927\uff0c\u6709\u4e00\u6b21\u4e00\u53f0\u8ba1\u7b97\u673a\u4e0d\u80fd\u6b63\u5e38\u5de5\u4f5c\uff0c\u5de5\u7a0b\u5e08\u4eec\u627e\u4e86\u534a\u5929\u539f\u56e0\u6700\u540e\u53d1\u73b0\u662f\u4e00\u53ea\u81ed\u866b\u94bb\u8fdb\u8ba1\u7b97\u673a\u4e2d\u9020\u6210\u7684\u3002\u4ece\u6b64\u4ee5\u540e\uff0c\u7a0b\u5e8f\u4e2d\u7684\u9519\u8bef\u88ab\u53eb\u505a\u81ed\u866b\uff08Bug\uff09\uff0c\u800c\u627e\u5230\u8fd9\u4e9bBug\u5e76\u52a0\u4ee5\u7ea0\u6b63\u7684\u8fc7\u7a0b\u5c31\u53eb\u505a\u8c03\u8bd5\uff08Debug\uff09\u3002\u6709\u65f6\u5019\u8c03\u8bd5\u662f\u4e00\u4ef6\u975e\u5e38\u590d\u6742\u7684\u5de5\u4f5c\uff0c\u8981\u6c42\u7a0b\u5e8f\u5458\u6982\u5ff5\u660e\u786e\u3001\u903b\u8f91\u6e05\u6670\u3001\u6027\u683c\u6c89\u7a33\uff0c\u8fd8\u9700\u8981\u4e00\u70b9\u8fd0\u6c14\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#bug","title":"Bug \u7684\u7c7b\u578b","text":"

\u8c03\u8bd5\u7684\u6280\u80fd\u6211\u4eec\u5728\u540e\u7eed\u7684\u5b66\u4e60\u4e2d\u6162\u6162\u57f9\u517b\uff0c\u4f46\u9996\u5148\u6211\u4eec\u8981\u533a\u5206\u6e05\u695a\u7a0b\u5e8f\u4e2d\u7684 Bug \u5206\u4e3a\u54ea\u51e0\u7c7b\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_18","title":"\u7f16\u8bd1\u65f6\u9519\u8bef","text":"

\u7f16\u8bd1\u5668\u53ea\u80fd\u7ffb\u8bd1\u8bed\u6cd5\u6b63\u786e\u7684\u7a0b\u5e8f\uff0c\u5426\u5219\u5c06\u5bfc\u81f4\u7f16\u8bd1\u5931\u8d25\uff0c\u65e0\u6cd5\u751f\u6210\u53ef\u6267\u884c\u6587\u4ef6\u3002\u5bf9\u4e8e\u81ea\u7136\u8bed\u8a00\u6765\u8bf4\uff0c\u4e00\u70b9\u8bed\u6cd5\u9519\u8bef\u4e0d\u662f\u5f88\u4e25\u91cd\u7684\u95ee\u9898\uff0c\u56e0\u4e3a\u6211\u4eec\u4ecd\u7136\u53ef\u4ee5\u8bfb\u61c2\u53e5\u5b50\u3002\u800c\u7f16\u8bd1\u5668\u5c31\u6ca1\u90a3\u4e48\u5bbd\u5bb9\u4e86\uff0c\u53ea\u8981\u6709\u54ea\u6015\u4e00\u4e2a\u5f88\u5c0f\u7684\u8bed\u6cd5\u9519\u8bef\uff0c\u7f16\u8bd1\u5668\u5c31\u4f1a\u8f93\u51fa\u4e00\u6761\u9519\u8bef\u63d0\u793a\u4fe1\u606f\u7136\u540e\u7f62\u5de5\uff0c\u4f60\u5c31\u5f97\u4e0d\u5230\u4f60\u60f3\u8981\u7684\u7ed3\u679c\u3002\u867d\u7136\u5927\u90e8\u5206\u60c5\u51b5\u4e0b\u7f16\u8bd1\u5668\u7ed9\u51fa\u7684\u9519\u8bef\u63d0\u793a\u4fe1\u606f\u5c31\u662f\u4f60\u51fa\u9519\u7684\u4ee3\u7801\u884c\uff0c\u4f46\u4e5f\u6709\u4e2a\u522b\u65f6\u5019\u7f16\u8bd1\u5668\u7ed9\u51fa\u7684\u9519\u8bef\u63d0\u793a\u4fe1\u606f\u5e2e\u52a9\u4e0d\u5927\uff0c\u751a\u81f3\u4f1a\u8bef\u5bfc\u4f60\u3002\u5728\u5f00\u59cb\u5b66\u4e60\u7f16\u7a0b\u7684\u524d\u51e0\u4e2a\u661f\u671f\uff0c\u4f60\u53ef\u80fd\u4f1a\u82b1\u5927\u91cf\u7684\u65f6\u95f4\u6765\u7ea0\u6b63\u8bed\u6cd5\u9519\u8bef\u3002\u7b49\u5230\u6709\u4e86\u4e00\u4e9b\u7ecf\u9a8c\u4e4b\u540e\uff0c\u8fd8\u662f\u4f1a\u72af\u8fd9\u6837\u7684\u9519\u8bef\uff0c\u4e0d\u8fc7\u4f1a\u5c11\u5f97\u591a\uff0c\u800c\u4e14\u4f60\u80fd\u66f4\u5feb\u5730\u53d1\u73b0\u9519\u8bef\u539f\u56e0\u3002\u7b49\u5230\u7ecf\u9a8c\u66f4\u4e30\u5bcc\u4e4b\u540e\u4f60\u5c31\u4f1a\u89c9\u5f97\uff0c\u8bed\u6cd5\u9519\u8bef\u662f\u6700\u7b80\u5355\u6700\u4f4e\u7ea7\u7684\u9519\u8bef\uff0c\u7f16\u8bd1\u5668\u7684\u9519\u8bef\u63d0\u793a\u4e5f\u5c31\u90a3\u4e48\u51e0\u79cd\uff0c\u5373\u4f7f\u9519\u8bef\u63d0\u793a\u662f\u6709\u8bef\u5bfc\u7684\u4e5f\u80fd\u591f\u7acb\u523b\u627e\u51fa\u771f\u6b63\u7684\u9519\u8bef\u539f\u56e0\u662f\u4ec0\u4e48\u3002\u76f8\u6bd4\u4e0b\u9762\u4e24\u79cd\u9519\u8bef\uff0c\u8bed\u6cd5\u9519\u8bef\u89e3\u51b3\u8d77\u6765\u8981\u5bb9\u6613\u5f97\u591a\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_19","title":"\u8fd0\u884c\u65f6\u9519\u8bef","text":"

\u7f16\u8bd1\u5668\u68c0\u67e5\u4e0d\u51fa\u8fd9\u7c7b\u9519\u8bef\uff0c\u4ecd\u7136\u53ef\u4ee5\u751f\u6210\u53ef\u6267\u884c\u6587\u4ef6\uff0c\u4f46\u5728\u8fd0\u884c\u65f6\u4f1a\u51fa\u9519\u800c\u5bfc\u81f4\u7a0b\u5e8f\u5d29\u6e83\u3002\u5bf9\u4e8e\u6211\u4eec\u63a5\u4e0b\u6765\u7684\u51e0\u7ae0\u5c06\u7f16\u5199\u7684\u7b80\u5355\u7a0b\u5e8f\u6765\u8bf4\uff0c\u8fd0\u884c\u65f6\u9519\u8bef\u5f88\u5c11\u89c1\uff0c\u5230\u4e86\u540e\u9762\u7684\u7ae0\u8282\u4f60\u4f1a\u9047\u5230\u8d8a\u6765\u8d8a\u591a\u7684\u8fd0\u884c\u65f6\u9519\u8bef\u3002\u8bfb\u8005\u5728\u4ee5\u540e\u7684\u5b66\u4e60\u4e2d\u8981\u65f6\u523b\u6ce8\u610f\u533a\u5206\u7f16\u8bd1\u65f6\u548c\u8fd0\u884c\u65f6\uff08Run-time\uff09\u8fd9\u4e24\u4e2a\u6982\u5ff5\uff0c\u4e0d\u4ec5\u5728\u8c03\u8bd5\u65f6\u9700\u8981\u533a\u5206\u8fd9\u4e24\u4e2a\u6982\u5ff5\uff0c\u5728\u5b66\u4e60 C \u8bed\u8a00\u7684\u5f88\u591a\u8bed\u6cd5\u65f6\u90fd\u9700\u8981\u533a\u5206\u8fd9\u4e24\u4e2a\u6982\u5ff5\uff0c\u6709\u4e9b\u4e8b\u60c5\u5728\u7f16\u8bd1\u65f6\u505a\uff0c\u6709\u4e9b\u4e8b\u60c5\u5219\u5728\u8fd0\u884c\u65f6\u505a\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_20","title":"\u903b\u8f91\u9519\u8bef\u548c\u8bed\u4e49\u9519\u8bef","text":"

\u7b2c\u4e09\u7c7b\u9519\u8bef\u662f\u903b\u8f91\u9519\u8bef\u548c\u8bed\u4e49\u9519\u8bef\u3002\u5982\u679c\u7a0b\u5e8f\u91cc\u6709\u903b\u8f91\u9519\u8bef\uff0c\u7f16\u8bd1\u548c\u8fd0\u884c\u90fd\u4f1a\u5f88\u987a\u5229\uff0c\u770b\u4e0a\u53bb\u4e5f\u4e0d\u4ea7\u751f\u4efb\u4f55\u9519\u8bef\u4fe1\u606f\uff0c\u4f46\u662f\u7a0b\u5e8f\u6ca1\u6709\u5e72\u5b83\u8be5\u5e72\u7684\u4e8b\u60c5\uff0c\u800c\u662f\u5e72\u4e86\u522b\u7684\u4e8b\u60c5\u3002\u5f53\u7136\u4e0d\u7ba1\u600e\u4e48\u6837\uff0c\u8ba1\u7b97\u673a\u53ea\u4f1a\u6309\u4f60\u5199\u7684\u7a0b\u5e8f\u53bb\u505a\uff0c\u95ee\u9898\u5728\u4e8e\u4f60\u5199\u7684\u7a0b\u5e8f\u4e0d\u662f\u4f60\u771f\u6b63\u60f3\u8981\u7684\uff0c\u8fd9\u610f\u5473\u7740\u7a0b\u5e8f\u7684\u610f\u601d\uff08\u5373\u8bed\u4e49\uff09\u662f\u9519\u7684\u3002\u627e\u5230\u903b\u8f91\u9519\u8bef\u5728\u54ea\u9700\u8981\u5341\u5206\u6e05\u9192\u7684\u5934\u8111\uff0c\u8981\u901a\u8fc7\u89c2\u5bdf\u7a0b\u5e8f\u7684\u8f93\u51fa\u56de\u8fc7\u5934\u6765\u5224\u65ad\u5b83\u5230\u5e95\u5728\u505a\u4ec0\u4e48\u3002

\u901a\u8fc7\u672c\u8282\u4f60\u5c06\u638c\u63e1\u7684\u6700\u91cd\u8981\u7684\u6280\u5de7\u5c31\u662f\u8c03\u8bd5\u3002\u8c03\u8bd5\u7684\u8fc7\u7a0b\u53ef\u80fd\u4f1a\u8ba9\u4f60\u611f\u5230\u4e00\u4e9b\u6cae\u4e27\uff0c\u4f46\u8c03\u8bd5\u4e5f\u662f\u7f16\u7a0b\u4e2d\u6700\u9700\u8981\u52a8\u8111\u7684\u3001\u6700\u6709\u6311\u6218\u548c\u4e50\u8da3\u7684\u90e8\u5206\u3002\u4ece\u67d0\u79cd\u89d2\u5ea6\u770b\u8c03\u8bd5\u5c31\u50cf\u4fa6\u63a2\u5de5\u4f5c\uff0c\u6839\u636e\u638c\u63e1\u7684\u7ebf\u7d22\u6765\u63a8\u65ad\u662f\u4ec0\u4e48\u539f\u56e0\u548c\u8fc7\u7a0b\u5bfc\u81f4\u4e86\u4f60\u6240\u770b\u5230\u7684\u7ed3\u679c\u3002\u8c03\u8bd5\u4e5f\u50cf\u662f\u4e00\u95e8\u5b9e\u9a8c\u79d1\u5b66\uff0c\u6bcf\u6b21\u60f3\u5230\u54ea\u91cc\u53ef\u80fd\u6709\u9519\uff0c\u5c31\u4fee\u6539\u7a0b\u5e8f\u7136\u540e\u518d\u8bd5\u4e00\u6b21\u3002\u5982\u679c\u5047\u8bbe\u662f\u5bf9\u7684\uff0c\u5c31\u80fd\u5f97\u5230\u9884\u671f\u7684\u6b63\u786e\u7ed3\u679c\uff0c\u5c31\u53ef\u4ee5\u63a5\u7740\u8c03\u8bd5\u4e0b\u4e00\u4e2a Bug\uff0c\u4e00\u6b65\u4e00\u6b65\u903c\u8fd1\u6b63\u786e\u7684\u7a0b\u5e8f\uff1b\u5982\u679c\u5047\u8bbe\u9519\u8bef\uff0c\u53ea\u597d\u53e6\u5916\u518d\u627e\u601d\u8def\u518d\u505a\u5047\u8bbe\u3002\u201c\u5f53\u4f60\u628a\u4e0d\u53ef\u80fd\u7684\u5168\u90e8\u5254\u9664\uff0c\u5269\u4e0b\u7684\u2014\u2014\u5373\u4f7f\u770b\u8d77\u6765\u518d\u600e\u4e48\u4e0d\u53ef\u80fd\u2014\u2014\u5c31\u4e00\u5b9a\u662f\u4e8b\u5b9e\u3002\u201d\uff08\u5373\u4f7f\u4f60\u6ca1\u770b\u8fc7\u798f\u5c14\u6469\u65af\u4e5f\u8be5\u770b\u8fc7\u67ef\u5357\u5427\uff09\u3002

\u4e5f\u6709\u4e00\u79cd\u89c2\u70b9\u8ba4\u4e3a\uff0c\u7f16\u7a0b\u548c\u8c03\u8bd5\u662f\u4e00\u56de\u4e8b\uff0c\u7f16\u7a0b\u7684\u8fc7\u7a0b\u5c31\u662f\u9010\u6b65\u8c03\u8bd5\u76f4\u5230\u83b7\u5f97\u671f\u671b\u7684\u7ed3\u679c\u4e3a\u6b62\u3002\u4f60\u5e94\u8be5\u603b\u662f\u4ece\u4e00\u4e2a\u80fd\u6b63\u786e\u8fd0\u884c\u7684\u5c0f\u89c4\u6a21\u7a0b\u5e8f\u5f00\u59cb\uff0c\u6bcf\u505a\u4e00\u6b65\u5c0f\u7684\u6539\u52a8\u5c31\u7acb\u523b\u8fdb\u884c\u8c03\u8bd5\uff0c\u8fd9\u6837\u7684\u597d\u5904\u662f\u603b\u6709\u4e00\u4e2a\u6b63\u786e\u7684\u7a0b\u5e8f\u505a\u53c2\u8003\uff1a\u5982\u679c\u6b63\u786e\u5c31\u7ee7\u7eed\u7f16\u7a0b\uff0c\u5982\u679c\u4e0d\u6b63\u786e\uff0c\u90a3\u4e48\u4e00\u5b9a\u662f\u521a\u624d\u7684\u5c0f\u6539\u52a8\u51fa\u4e86\u95ee\u9898\u3002\u4f8b\u5982\uff0cLinux \u64cd\u4f5c\u7cfb\u7edf\u5305\u542b\u4e86\u6210\u5343\u4e0a\u4e07\u884c\u4ee3\u7801\uff0c\u4f46\u5b83\u4e5f\u4e0d\u662f\u4e00\u5f00\u59cb\u5c31\u89c4\u5212\u597d\u4e86\u5185\u5b58\u7ba1\u7406\u3001\u8bbe\u5907\u7ba1\u7406\u3001\u6587\u4ef6\u7cfb\u7edf\u3001\u7f51\u7edc\u7b49\u7b49\u5927\u7684\u6a21\u5757\uff0c\u4e00\u5f00\u59cb\u5b83\u4ec5\u4ec5\u662f Linus Torvalds \u7528\u6765\u7422\u78e8 Intel 80386 \u82af\u7247\u800c\u5199\u7684\u5c0f\u7a0b\u5e8f\u3002\u636e Larry Greenfield \u8bf4\uff0c\u201cLinus \u7684\u65e9\u671f\u5de5\u7a0b\u4e4b\u4e00\u662f\u7f16\u5199\u4e00\u4e2a\u4ea4\u66ff\u6253\u5370 AAAA \u548c BBBB \u7684\u7a0b\u5e8f\uff0c\u8fd9\u73a9\u610f\u513f\u540e\u6765\u8fdb\u5316\u6210\u4e86 Linux\u3002\u201d\uff08\u5f15\u81ea The Linux User's Guide Beta1 \u7248\uff09\u5728\u540e\u7eed\u7684\u8bfe\u7a0b\u4e2d\u4f1a\u7ed9\u51fa\u66f4\u591a\u5173\u4e8e\u8c03\u8bd5\u548c\u7f16\u7a0b\u5b9e\u8df5\u7684\u5efa\u8bae\u3002

\u6742\u8c08\uff1a\u4e3a\u4ec0\u4e48\u5f88\u591a\u540c\u5b66\u611f\u89c9\u8c03\u8bd5\u7684\u8fc7\u7a0b\u5341\u5206\u714e\u71ac\uff1f

\u6216\u8bb8\u4f60\u4e5f\u4f1a\u5728\u540e\u7eed\u7684\u5b66\u4e60\u4e2d\u4eb2\u8eab\u4f53\u4f1a\u6216\u770b\u5230\uff0c\u540c\u5b66\u4eec\u88ab\u7a0b\u5e8f\u7684 Bug\uff08\u6700\u5178\u578b\u7684\u662f\u6bb5\u9519\u8bef\uff09\u6298\u78e8\u5f97\u7126\u5934\u70c2\u989d\u3002\u8fd9\u53ef\u80fd\u6709\u4ee5\u4e0b\u539f\u56e0\uff1a

  • C \u8bed\u8a00\u57fa\u7840\u77e5\u8bc6\u4e0d\u7262\uff1a\u7f16\u8bd1\u90fd\u8fc7\u4e0d\u4e86\uff0c\u4e0d\u5f00 -Wall \u548c -Werror\uff0c\u7f16\u8bd1\u51fa\u6765\u7684\u7a0b\u5e8f\u4e2d\u6709\u5f88\u591a\u5751\uff0c\u6bd4\u5982\u9690\u5f0f\u7c7b\u578b\u8f6c\u6362\u3002
  • \u6ca1\u6709\u4e8b\u5148\u60f3\u597d\u7a0b\u5e8f\u7684\u903b\u8f91\uff1a\u5efa\u8bae\u5728\u52a8\u624b\u5199\u4ee3\u7801\u524d\uff0c\u5148\u60f3\u597d\u81ea\u5df1\u7a0b\u5e8f\u7684\u903b\u8f91\u548c\u6b65\u9aa4\u3002\u8fb9\u5199\u8fb9\u60f3\u7684\u540e\u679c\u5927\u6982\u7387\u662f\u4ee3\u7801\u5199\u5f97\u4e00\u5768\uff08\u9664\u975e\u4f60\u975e\u5e38\u719f\u7ec3\uff09\u3002
  • \u4e0d\u4e86\u89e3\u57fa\u672c\u7684\u8c03\u8bd5\u6280\u672f\uff0c\u4e0d\u4f1a\u4f7f\u7528\u8c03\u8bd5\u5de5\u5177\uff1a\u672c\u8282\u8bfe\u6211\u4eec\u5c06\u4e3a\u5927\u5bb6\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\u3002
"},{"location":"programming_lecture/lecture1/lecture1/#fprintfstderr","title":"fprintf(stderr) \u662f\u4f60\u6700\u597d\u7684\u670b\u53cb","text":"

\u867d\u7136\u63a5\u4e0b\u6765\u8981\u4ecb\u7ecd\u7684 gdb \u529f\u80fd\u5f3a\u5927\uff0c\u4f46\u5927\u591a\u6570\u60c5\u51b5\u4e0b\u7b80\u5355\u5730\u6253\u5370\u53d8\u91cf\u5c31\u80fd\u5e2e\u4f60\u5b9a\u4f4d\u95ee\u9898\u6240\u5728\u3002

\u5728\u7a0b\u5e8f\u4e2d\u4f7f\u7528 fprintf(stderr, ...) \u6253\u5370\u8c03\u8bd5\u4fe1\u606f\uff0c\u53ef\u4ee5\u5e2e\u52a9\u4f60\u5b9a\u4f4d\u5230\u7a0b\u5e8f\u4e2d\u7684\u9519\u8bef\u3002fprintf \u5411\u6307\u5b9a\u7684\u6d41\u8f93\u51fa\u683c\u5f0f\u5316\u5b57\u7b26\u4e32\uff0cstderr \u662f\u6807\u51c6\u9519\u8bef\u6d41\uff0c\u5b83\u4e0d\u4f1a\u88ab\u7f13\u51b2\uff0c\u56e0\u6b64\u4f60\u53ef\u4ee5\u5728\u7a0b\u5e8f\u5d29\u6e83\u65f6\u770b\u5230\u6700\u540e\u7684\u8c03\u8bd5\u4fe1\u606f\uff08\u8fd9\u4e9b\u8f93\u5165\u8f93\u51fa\u7684\u77e5\u8bc6\u4f1a\u5728\u540e\u9762\u7684\u8bfe\u7a0b\u4e2d\u5b66\u5230\uff09\u3002

\u4ee5\u4e00\u4e2a\u5f02\u5e38\u7ec8\u6b62\u7684\u7a0b\u5e8f\u4e3a\u4f8b\uff1a

#include <stdio.h>\n#include <stdlib.h>\n\nint main(void)\n{\n    printf(\"printf \");\n    fprintf(stderr, \"fprintf \");\n    abort();\n}\n

\u8fd0\u884c\u7ed3\u679c\u5982\u4e0b\uff1a

$ ./debug\nfprintf fish: Job 1, './debug' terminated by signal SIGABRT (Abort)\n

\u53ef\u4ee5\u770b\u5230\u53ea\u6709 fprintf \u51fd\u6570\u7684\u8f93\u51fa\u3002\u5982\u679c\u5728 printf \u8bed\u53e5\u540e\u9762\u52a0\u4e0a\u6362\u884c\u7b26\uff0c\u4f60\u4f1a\u53d1\u73b0 printf \u7684\u8f93\u51fa\u4e5f\u88ab\u6253\u5370\u51fa\u6765\u4e86\u3002\u56e0\u4e3a\u5f53\u8f93\u51fa\u7f13\u51b2\u533a\u9047\u5230 \\n \u65f6\u4e5f\u4f1a\u7acb\u5373\u8f93\u51fa\u3002

\u6b64\u5916\uff0c\u5c06\u9519\u8bef\u4fe1\u606f\u5bfc\u5411\u6807\u51c6\u9519\u8bef\u6d41\u8fd8\u6709\u53e6\u4e00\u4e2a\u597d\u5904\uff0c\u5c31\u662f\u4f60\u53ef\u4ee5\u5206\u522b\u6536\u96c6\u8c03\u8bd5\u4fe1\u606f\u548c\u6b63\u5e38\u8f93\u51fa\u3002\u6bd4\u5982\u4f60\u53ef\u4ee5\u5c06\u8c03\u8bd5\u4fe1\u606f\u91cd\u5b9a\u5411\u5230\u4e00\u4e2a\u6587\u4ef6\uff0c\u800c\u5c06\u6b63\u5e38\u8f93\u51fa\u91cd\u5b9a\u5411\u5230\u53e6\u4e00\u4e2a\u6587\u4ef6\u3002

$ ./debug 2> debug.log 1> output.log\n
"},{"location":"programming_lecture/lecture1/lecture1/#gdb","title":"\u4f7f\u7528 gdb \u8c03\u8bd5\u7a0b\u5e8f","text":"

\u63a5\u4e0b\u6765\uff0c\u6211\u4eec\u4ee5\u88ab C \u6807\u51c6\u5f03\u7528\u7684\u5e93\u51fd\u6570 gets \u4e3a\u4f8b\uff0c\u7528 gdb \u5bf9\u5176\u8fdb\u884c\u8c03\u8bd5\uff1a

gets.c
char *gets(char *s)\n{\n    int c;\n    char *dest = s;\n    while((c = getchar()) != '\\n' && c != EOF)\n        *dest++ = c;\n    if(c == EOF && dest == s)\n        return NULL;\n    *dest++ = '\\0';\n    return s;\n}\n\nvoid echo()\n{\n    char buf[8];\n    gets(buf);\n    puts(buf);\n}\n
"},{"location":"programming_lecture/lecture1/lecture1/#_21","title":"\u7f16\u8bd1\u65f6\u5f00\u542f\u8c03\u8bd5\u4fe1\u606f","text":"

\u5728\u7f16\u8bd1\u65f6\uff0c\u4f7f\u7528 -g \u9009\u9879\u5728\u53ef\u6267\u884c\u6587\u4ef6\u4e2d\u52a0\u5165\u6e90\u4ee3\u7801\u7684\u4fe1\u606f\uff0c\u6bd4\u5982\u53ef\u6267\u884c\u6587\u4ef6\u4e2d\u7b2c\u51e0\u6761\u673a\u5668\u6307\u4ee4\u5bf9\u5e94\u6e90\u4ee3\u7801\u7684\u7b2c\u51e0\u884c\uff0c\u4f46\u5e76\u4e0d\u662f\u628a\u6574\u4e2a\u6e90\u6587\u4ef6\u5d4c\u5165\u5230\u53ef\u6267\u884c\u6587\u4ef6\u4e2d\uff0c\u6240\u4ee5\u5728\u8c03\u8bd5\u65f6\u5fc5\u987b\u4fdd\u8bc1gdb\u80fd\u627e\u5230\u6e90\u6587\u4ef6\u3002\u8fd9\u4e9b\u4fe1\u606f\u53ef\u4ee5\u5e2e\u52a9\u8c03\u8bd5\u5668\u5b9a\u4f4d\u5230\u6e90\u4ee3\u7801\u7684\u4f4d\u7f6e\u3002

gcc -g -o gets gets.c\n

\u6709\u65f6\uff0c\u56e0\u4e3a GCC \u7684\u7279\u6027\uff0c\u53ef\u80fd\u5bfc\u81f4\u5141\u8bb8\u67d0\u4e9b\u4e0d\u7b26\u5408 C \u6807\u51c6\u7684\u4e8b\u60c5\u53d1\u751f\u3002\u8fd9\u65f6\u4f60\u53ef\u4ee5\u4f7f\u7528 -ansi -pedantic-errors \u6765\u5173\u95ed GCC \u7279\u6027\uff0c\u4e25\u683c\u9075\u5b88 ANSI C\u3002\u8fd9\u6784\u6210\u4e86\u5e38\u7528\u7684\u7f16\u8bd1\u9009\u9879\u3002

gcc -Wall -Werror -ansi -pedantic-errors -g prog1.c -o prog1\n
"},{"location":"programming_lecture/lecture1/lecture1/#gdb_1","title":"gdb \u7684\u57fa\u672c\u4f7f\u7528","text":"

\u542f\u52a8 gdb \u7a0b\u5e8f\uff1a

GNU gdb (Ubuntu 10.2-6ubuntu1) 10.2\n...\nReading symbols from ./hello...\n(gdb)\n

\u547d\u4ee4\u884c\u7684\u63d0\u793a\u7b26\u4ece $ \u53d8\u6210\u4e86 (gdb)\uff0c\u8fd9\u610f\u5473\u7740\u4f60\u5df2\u7ecf\u8fdb\u5165\u4e86 gdb \u7684\u4ea4\u4e92\u754c\u9762\u3002gdb \u4e2d\u5e38\u7528\u7684\u547d\u4ee4\u5982\u4e0b\uff1a

  • file <filename>\uff1a\u52a0\u8f7d\u53ef\u6267\u884c\u6587\u4ef6\u3002
  • r \u6216 run [args]\uff1a\u8fd0\u884c\u7a0b\u5e8f\u3002[args] \u662f\u53ef\u9009\u7684\u547d\u4ee4\u884c\u53c2\u6570\u3002
  • b \u6216 break <line>\uff1a\u5728\u6307\u5b9a\u884c\u8bbe\u7f6e\u65ad\u70b9\u3002
  • b \u6216 break <function>\uff1a\u5728\u6307\u5b9a\u51fd\u6570\u8bbe\u7f6e\u65ad\u70b9\u3002
  • b \u6216 break *<address>\uff1a\u5728\u6307\u5b9a\u5730\u5740\u8bbe\u7f6e\u65ad\u70b9\u3002
  • info breakpoints\uff1a\u67e5\u770b\u65ad\u70b9\u4fe1\u606f\u3002
  • delete breakpoints <number>\uff1a\u5220\u9664\u6307\u5b9a\u7f16\u53f7\u7684\u65ad\u70b9\u3002
  • continue\uff1a\u7ee7\u7eed\u6267\u884c\u7a0b\u5e8f\u3002
  • next\uff1a\u6267\u884c\u4e0b\u4e00\u884c\u3002
  • step\uff1a\u6267\u884c\u4e0b\u4e00\u884c\uff0c\u5982\u679c\u9047\u5230\u51fd\u6570\u8c03\u7528\uff0c\u8fdb\u5165\u51fd\u6570\u5185\u90e8\u3002
  • print <variable>\uff1a\u6253\u5370\u53d8\u91cf\u7684\u503c\u3002
  • print <expression>\uff1a\u6253\u5370\u8868\u8fbe\u5f0f\u7684\u503c\u3002
  • watch <expression>\uff1a\u76d1\u89c6\u8868\u8fbe\u5f0f\u7684\u503c\uff0c\u5f53\u503c\u53d1\u751f\u53d8\u5316\u65f6\uff0c\u7a0b\u5e8f\u4f1a\u505c\u4e0b\u6765\u3002
  • backtrace\uff1a\u67e5\u770b\u51fd\u6570\u8c03\u7528\u6808\u3002
  • finish\uff1a\u6267\u884c\u5b8c\u5f53\u524d\u51fd\u6570\u540e\u505c\u4e0b\u6765\u3002
  • q \u6216 quit\uff1a\u9000\u51fa gdb\u3002
  • help\uff1a\u67e5\u770b\u5e2e\u52a9\u4fe1\u606f\u3002
"},{"location":"programming_lecture/lecture1/lecture1/#_22","title":"\u68c0\u67e5\u7a0b\u5e8f\u60c5\u51b5","text":"

Linux \u7cfb\u7edf\u6709\u4e00\u4e2a\u7279\u6b8a\u7684\u8bbe\u5907\u6587\u4ef6 /dev/zero\uff0c\u5b83\u80fd\u591f\u4f5c\u4e3a\u8f93\u5165\uff0c\u63d0\u4f9b\u65e0\u7a77\u65e0\u5c3d\u7684 0 \u5b57\u8282\u3002\u6211\u4eec\u5c06\u5b83\u4f5c\u4e3a\u8f93\u5165\uff0c\u770b\u770b\u7a0b\u5e8f\u4f1a\u53d1\u751f\u4ec0\u4e48\u3002

(gdb) file gets\nReading symbols from gets...\n(gdb) run < /dev/zero\nStarting program: /mnt/f/Code/_repo/study-assist/docs/programming_lecture/lecture1/code/gets < /dev/zero\n[Thread debugging using libthread_db enabled]\nUsing host libthread_db library \"/lib/x86_64-linux-gnu/libthread_db.so.1\".\n\nProgram received signal SIGSEGV, Segmentation fault.\n0x00005555555551b2 in gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n

\u56e0\u4e3a\u7a0b\u5e8f\u8bbf\u95ee\u4e86\u975e\u6cd5\u7684\u5730\u5740\u7a7a\u95f4\uff0c\u7cfb\u7edf\u5411\u7a0b\u5e8f\u53d1\u9001\u4fe1\u53f7 SIGSEGV\uff0c\u7a0b\u5e8f\u7ec8\u6b62\u8fd0\u884c\u3002gdb \u4f1a\u81ea\u52a8\u505c\u5728\u53d1\u751f\u9519\u8bef\u7684\u4f4d\u7f6e\uff0c\u8fd9\u91cc\u662f gets.c \u7684\u7b2c 8 \u884c\u3002\u4f60\u53ef\u4ee5\u4f7f\u7528 backtrace \u547d\u4ee4\u67e5\u770b\u51fd\u6570\u8c03\u7528\u6808\u3002

(gdb) backtrace\n#0  0x00005555555551b2 in gets (s=0x7fffffffd760 \"\") at gets.c:8\n#1  0x000055555555521b in echo () at gets.c:18\n#2  0x0000000000000000 in ?? ()\n

\u4f7f\u7528 print \u547d\u4ee4\u67e5\u770b\u5404\u4e2a\u53d8\u91cf\u7684\u503c\u3002print/x \u80fd\u591f\u6307\u5b9a\u4ee5\u5341\u516d\u8fdb\u5236\u7684\u5f62\u5f0f\u6253\u5370\u53d8\u91cf\u7684\u503c\u3002

(gdb) print dest\n$1 = 0x7ffffffff001 <error: Cannot access memory at address 0x7ffffffff001>\n(gdb) print s\n$2 = 0x7fffffffd760 \"\"\n(gdb) print dest - s\n$3 = 6305\n(gdb) print c\n$4 = 0\n

gdb \u4e3a\u4f60\u505a\u4e86\u4e00\u4e9b\u63d0\u793a\uff0c\u6bd4\u5982 dest \u73b0\u5728\u6240\u6307\u5411\u7684\u5730\u5740 0x7ffffffff001 \u662f\u7a0b\u5e8f\u65e0\u6cd5\u8bbf\u95ee\u7684\u3002\u68c0\u67e5 dest - s \u7684\u503c\u6211\u4eec\u77e5\u9053\u6b64\u65f6 dest \u6307\u5411\u7684\u5730\u5740\u5df2\u7ecf\u662f s \u540e 6305 \u4e2a\u5b57\u8282\uff0c\u8fdc\u8fdc\u8d85\u51fa\u4e86\u6570\u7ec4 s \u7684\u7a7a\u95f4\u3002\u6211\u4eec\u4e5f\u53ef\u4ee5\u68c0\u67e5\u5f53\u524d\u8f93\u5165\u7684\u5b57\u7b26 c\uff0c\u5b83\u663e\u7136\u662f 0\u3002

"},{"location":"programming_lecture/lecture1/lecture1/#_23","title":"\u65ad\u70b9\u8c03\u8bd5","text":"

\u4f7f\u7528 break <filename>:<line> \u53ef\u4ee5\u5728\u6307\u5b9a\u6587\u4ef6\u6307\u5b9a\u884c\u8bbe\u7f6e\u65ad\u70b9\u3002\u5bf9\u4e8e\u5355\u6587\u4ef6\u7a0b\u5e8f\uff0c\u53ef\u4ee5\u7701\u7565\u6e90\u4ee3\u7801\u6587\u4ef6\u540d\u3002break \u8fd8\u53ef\u4ee5\u63a5\u6536\u51fd\u6570\u540d\u548c\u5730\u5740\u4f5c\u4e3a\u53c2\u6570\uff0c\u8fd8\u53ef\u4ee5\u4f7f\u7528\u6761\u4ef6\u8868\u8fbe\u5f0f\uff0c\u8bf7\u4f7f\u7528 help break \u67e5\u770b\u8be6\u7ec6\u7528\u6cd5\u3002

\u6211\u4eec\u5728\u7a0b\u5e8f\u7b2c 8 \u884c *dest++=c \u5904\u8bbe\u7f6e\u4e00\u4e2a\u65ad\u70b9\uff0c\u7136\u540e\u8fd0\u884c\u7a0b\u5e8f\u3002

(gdb) b 8\nBreakpoint 1 at 0x11a3: file gets.c, line 8.\n(gdb) r < /dev/zero\nStarting program: /mnt/f/Code/_repo/study-assist/docs/programming_lecture/lecture1/code/gets < /dev/zero\n\nBreakpoint 1, gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n(gdb) print dest - s\n$1 = 0\n

next \u547d\u4ee4\u5c06\u4f1a\u5355\u884c\u6267\u884c\u7a0b\u5e8f\uff0c\u4e14\u4e0d\u4f1a\u8fdb\u5165\u51fd\u6570\u5185\u90e8\uff08\u5373\u628a\u6574\u4e2a\u51fd\u6570\u5f53\u4f5c\u4e00\u884c\uff09\u3002step \u4f1a\u8fdb\u5165\u51fd\u6570\u5185\u90e8\u4e00\u884c\u4e00\u884c\u6267\u884c\u3002continue \u547d\u4ee4\u5c06\u7ee7\u7eed\u6267\u884c\u7a0b\u5e8f\uff0c\u76f4\u5230\u4e0b\u4e00\u4e2a\u65ad\u70b9\u3002

(gdb) next\n7               while((c = getchar()) != '\\n' && c != EOF)\n(gdb) next\nBreakpoint 1,gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n(gdb) print dest - s\n$2 =1\n(gdb) continue\nContinuing.\nBreakpoint 1, gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n(gdb) print dest - s\n$3 = 2\n

next \u548c step \u547d\u4ee4\u90fd\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u8868\u793a\u6267\u884c\u591a\u5c11\u884c\uff0c\u4e14\u4f1a\u5728\u65ad\u70b9\u5904\u505c\u4e0b\u3002continue \u547d\u4ee4\u4e5f\u53ef\u4ee5\u63a5\u53d7\u4e00\u4e2a\u53c2\u6570\uff0c\u8868\u793a\u5ffd\u7565\u63a5\u4e0b\u6765\u5730\u591a\u5c11\u4e2a\u65ad\u70b9\u3002

(gdb) next 20\n\nBreakpoint 1, gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n(gdb) print dest - s\n$4 = 3\n(gdb) continue 20\nWill ignore next 19 crossings of breakpoint 1.  Continuing.\n\nBreakpoint 1, gets (s=0x7fffffffd760 \"\") at gets.c:8\n8               *dest++ = c;\n(gdb) print dest - s\n$5 = 23\n
\u8c03\u8bd5\u6280\u5de7

\u76f4\u63a5\u6309 Enter \u952e\uff0cgdb \u4f1a\u91cd\u590d\u4e0a\u4e00\u6761\u547d\u4ee4\u3002\u8fd9\u6837\u5c31\u4e0d\u7528\u4e00\u76f4\u8f93\u5165 next \u6216 step \u4e86\u3002

\u5728\u4e00\u4e9b\u66f4\u4e3a\u590d\u6742\u7684\u7a0b\u5e8f\u4e2d\uff0c\u4f7f\u7528 gdb \u8c03\u8bd5\u7684\u4f18\u8d8a\u6027\u5c31\u9010\u6e10\u663e\u73b0\u51fa\u6765\u4e86\u3002\u4f60\u4e0d\u7528\u9891\u7e41\u66f4\u6539\u6e90\u4ee3\u7801\u63d2\u5165 printf \u8bed\u53e5\uff0c\u53ea\u9700\u8981\u5728 gdb \u4e2d\u8bbe\u7f6e\u65ad\u70b9\uff0c\u7136\u540e\u9010\u6b65\u6267\u884c\u7a0b\u5e8f\uff0c\u67e5\u770b\u53d8\u91cf\u7684\u503c\uff0c\u5c31\u80fd\u627e\u5230\u9519\u8bef\u6240\u5728\u3002

\u8fdb\u4e00\u6b65\u5b66\u4e60

\u7531\u4e8e\u4e2a\u4eba\u6c34\u5e73\u4e0d\u8db3\u4ee5\u53ca\u65f6\u95f4\u6709\u9650\uff0c\u6ca1\u80fd\u5199\u51fa\u4e00\u4e2a\u4f53\u9a8c\u8f83\u597d\u7684 GDB \u8c03\u8bd5\u5b9e\u9a8c\u3002\u5341\u5206\u5e0c\u671b\u540c\u5b66\u4eec\u5728\u8bfe\u540e\u53bb\u770b\u770b\u8fd9\u7bc7\u6587\u7ae0Linux C \u4e00\u7ad9\u5f0f\u7f16\u7a0b\uff1a\u7b2c 10 \u7ae0 gdb\uff0c\u628a\u8fd9\u8fb9\u7684\u8c03\u8bd5\u5b9e\u4f8b\u90fd\u8fc7\u4e00\u904d\uff5e

"},{"location":"programming_lecture/lecture1/lecture1/#_24","title":"\u53c2\u8003\u8d44\u6599","text":"\u53c2\u8003\u8d44\u6599
  • GCC and Make - A Tutorial on how to compile, link and build C/C++ applications
  • Understanding GCC warnings
  • The GCC warning flags every C programmer should know about
  • What Is /lib64/ld-linux-x86-64.so.2?
  • GDB Tutorial: A Walkthrough with Examples
  • \u770b\u4e91\uff1aLinux C \u4e00\u7ad9\u5f0f\u5b66\u4e60
"},{"location":"programming_lecture/lecture1/pre_class/","title":"\u8bfe\u524d\uff1a\u51c6\u5907\u5f00\u53d1\u4e0e\u8c03\u8bd5\u73af\u5883","text":"

Info

\u672c\u6587\u6863\u66f4\u6539\u81ea\u5468\u5065\u5747\u5b66\u957f\u4e3a\u56fe\u7075\u7a0b\u7b97\u8bfe\u7a0b\u51c6\u5907\u7684\u8d44\u6599\uff0c\u611f\u8c22\u5468\u5065\u5747\u5b66\u957f\u7684\u4ed8\u51fa\u3002

\u5185\u5bb9\u63d0\u8981

\u5728\u53c2\u4e0e\u7ebf\u4e0b\u6388\u8bfe\u524d\uff0c\u540c\u5b66\u4eec\u6700\u597d\u80fd\u591f\u5b89\u88c5\u597d\u76f8\u5173\u7684\u5f00\u53d1\u73af\u5883\uff0c\u4ee5\u4fbf\u80fd\u591f\u66f4\u597d\u7684\u8ddf\u968f\u8001\u5e08\u7684\u8bb2\u89e3\u3002

  • \u547d\u4ee4\u884c\u7b80\u4ecb
  • WSL \u5b89\u88c5\u5f15\u5bfc
  • \u5728 Windows \u4e0a\u5b89\u88c5 C \u8bed\u8a00\u7f16\u8bd1\u5668
  • VSCode \u5b89\u88c5\u4e0e\u914d\u7f6e

\u540c\u5b66\u4eec\u53ef\u4ee5\u4ece\u53f3\u4fa7\uff08\u7535\u8111\u7aef\uff09\u6216\u5de6\u4fa7\uff08\u624b\u673a\u7aef\uff09\u76ee\u5f55\u8df3\u8f6c\u5230\u81ea\u5df1\u9700\u8981\u7684\u7ae0\u8282\u3002

\u975e\u8ba1\u7b97\u673a\u4e13\u4e1a\u540c\u5b66\uff0c\u4f7f\u7528 Dev-C++ \u7b49 IDE \u6216\u5728\u7ebf IDE \u5373\u53ef\u3002

\u672c\u7bc7\u6587\u7ae0\u63cf\u8ff0\u7684\u5185\u5bb9\u9002\u7528\u4e8e\u8ba1\u7b97\u673a\u4e13\u4e1a\u7684\u540c\u5b66\u3002\u975e\u8ba1\u7b97\u673a\u4e13\u4e1a\u7684\u540c\u5b66\uff0c\u4e0d\u9700\u8981\u638c\u63e1\u547d\u4ee4\u884c\u7684\u4f7f\u7528\uff0c\u4f7f\u7528 IDE \u5373\u53ef\u3002\u5e76\u4e14\u66f4\u52a0\u63a8\u8350\u5728\u7ebf IDE\uff0c\u56e0\u4e3a\u672c\u5730 IDE \u6709\u65f6\u4e5f\u4f1a\u51fa\u9519\u3002\u6700\u5e38\u89c1\u7684\u4e00\u4e2a\u4f8b\u5b50\u662f\uff1a\u8fd0\u884c\u4e86\u4e00\u6b21\u7a0b\u5e8f\uff0c\u6ca1\u6709\u4ee5\u6070\u5f53\u7684\u65b9\u5f0f\u7ed3\u675f\u8fdb\u7a0b\uff0c\u518d\u6b21\u70b9\u51fb\u7f16\u8bd1\u65f6\u7f16\u8bd1\u5668 ld \u5c31\u4f1a\u56e0\u4e3a .exe \u88ab\u5360\u7528\u65e0\u6cd5\u5199\u5165\u800c\u62a5\u9519\uff0c\u4f46\u62a5\u9519\u4fe1\u606f\u5e76\u4e0d\u4f1a\u8868\u660e\u662f\u4e0a\u4e00\u4e2a\u7a0b\u5e8f\u6ca1\u5173\uff0c\u641e\u4e0d\u61c2\u662f\u600e\u4e48\u56de\u4e8b\u3002\u6211\u8fd8\u89c1\u8fc7\u6709\u540c\u5b66\uff0c\u6bcf\u6b21\u7f16\u8bd1\u5b8c\u8fd0\u884c\u7a0b\u5e8f\uff0c\u90fd\u8981\u88ab 360 \u5148\u626b\u63cf\u4e00\u904d\uff0c\u7b49\u4e2a\u534a\u5206\u949f\u624d\u80fd\u663e\u793a\u7a97\u53e3\u3002\u5728\u7ebf IDE \u4e0d\u53d7\u4f60\u7535\u8111\u7684\u5f71\u54cd\uff0c\u4e0d\u4f1a\u4ea7\u751f\u8fd9\u4e9b\u95ee\u9898\u3002

\u4e0b\u9762\u7684\u5757\u4ee5 Online GDB \u4e3a\u4f8b\uff0c\u5c55\u793a\u5728\u7ebf IDE \u7684\u7528\u6cd5\u3002\u914d\u597d\u73af\u5883\u7684\u540c\u5b66\u4e5f\u53ef\u4ee5\u770b\u4e00\u770b\uff0c\u56e0\u4e3a\u4f60\u53ef\u80fd\u5076\u5c14\u4e34\u65f6\u7528\u5230\u4e00\u4e2a\u6ca1\u6709\u914d\u7f6e\u73af\u5883\u7684\u7535\u8111\uff0c\u8fd9\u65f6\u4f7f\u7528\u5728\u7ebf IDE \u6700\u4e3a\u4fbf\u6377\u3002

Online GDB \u7684\u4f7f\u7528

  • \u6253\u5f00\u8fd9\u4e2a\u7f51\u5740\uff1awww.onlinegdb.com\u3002
  • \u5b83\u5df2\u7ecf\u4e3a\u4f60\u5199\u597d C \u8bed\u8a00\u7684 Hello World \u7a0b\u5e8f\u6e90\u7801\u3002
  • \u5728\u53f3\u4e0a\u89d2\u9009\u62e9 C \u8bed\u8a00\uff0c\u7136\u540e\u70b9\u51fb\u5de6\u4e0a\u89d2\u7684 Run\u3002
  • \u5728\u4e0b\u65b9\uff0c\u4f60\u5c31\u53ef\u4ee5\u770b\u89c1\u7a0b\u5e8f\u7684\u8f93\u51fa\u3002
  • \u6309\u4e0b Enter \u952e\u79bb\u5f00\u7ec8\u7aef\u3002\u4e0b\u65b9\u4f1a\u663e\u793a\u51e0\u4e2a\u9009\u9879\uff1a
    • Command Line Arguments\uff1a\u547d\u4ee4\u884c\u53c2\u6570\uff0c\u4f60\u4eec\u5e94\u8be5\u4e0d\u4f1a\u5b66\u5230\uff1f
    • Standard Input\uff1a\u6807\u51c6\u8f93\u5165\u3002\u4f60\u53ef\u4ee5\u9009\u62e9 Interactive Console\uff08\u5c31\u662f\u6b63\u5e38\u5730\u7528\u952e\u76d8\u548c\u7a0b\u5e8f\u4ea4\u4e92\uff09\u6216\u8005 Text\uff08\u9884\u5148\u51c6\u5907\u4e00\u4e9b\u6587\u672c\u81ea\u52a8\u8f93\u5165\uff0c\u901a\u5e38\u7528\u4e8e\u6d4b\u8bd5 PTA \u7684\u6837\u4f8b\u6570\u636e\uff09\u3002

\u53ef\u4ee5\u8df3\u8fc7\u672c\u7bc7\u6587\u7ae0\u7684\u540c\u5b66

\u7b26\u5408\u4ee5\u4e0b\u63cf\u8ff0\u7684\u540c\u5b66\u53ef\u4ee5\u8df3\u8fc7\u672c\u7bc7\u6587\u7ae0\uff1a

  • Mac \u548c Linux \u7528\u6237
  • \u5b89\u88c5\u597d\u4e86 WSL \u7684 Windows \u7528\u6237
  • \u5b89\u88c5\u597d\u4e86 MinGW\u3001MSVC\u3001Cygwin\u3001tdm-gcc \u7b49\u7f16\u8bd1\u5668\u7684 Windows \u7528\u6237

\u4f7f\u7528\u96c6\u6210\u5f00\u53d1\u73af\u5883\u7684\u540c\u5b66\uff0c\u4e5f\u8bf7\u770b\u4e00\u4e0b Shell \u90e8\u5206\u3002

\u6e29\u99a8\u63d0\u793a

  • \u70b9\u51fb\u9875\u9762\u4e2d\u7684\u56fe\u7247\u53ef\u4ee5\u653e\u5927\u67e5\u770b\u3002
  • \u5982\u679c\u5b89\u88c5\u8fc7\u7a0b\u9047\u5230\u56f0\u96be\uff0c\u53ef\u4ee5\u5728\u8f85\u5b66\u7fa4\u63d0\u95ee\uff0c\u6216\u79c1\u6233\u6388\u8bfe\u5b66\u957f\uff5e
"},{"location":"programming_lecture/lecture1/pre_class/#shell","title":"Shell \u4f7f\u7528\u62fe\u9057","text":"

\u672c\u8282\u6211\u4eec\u8981\u8ba4\u8bc6\u4e00\u4e2a\u5373\u5c06\u6210\u4e3a\u4f60\u7684\u8001\u670b\u53cb\u7684\u4e1c\u897f\u2014\u2014Shell\u3002\u4e0b\u9762\u662f\u540c\u5b66\u4eec\u63a5\u4e0b\u6765\u4f1a\u7ecf\u5e38\u89c1\u5230\u7684\u51e0\u4e2a\u540d\u8bcd\uff1a

  • Terminal \u7ec8\u7aef\uff1a\u4e0b\u56fe\u4e2d\uff0c\u8fd9\u4e2a\u7a97\u53e3\u5c31\u662f Windows Terminal\u3002\u5b83\u8d1f\u8d23\u63a5\u6536\u4f60\u7684\u8f93\u5165\uff0c\u628a\u8f93\u5165\u4f20\u9012\u7ed9 Shell\uff0c\u7136\u540e\u628a Shell \u7684\u8f93\u51fa\u663e\u793a\u7ed9\u4f60\u3002\u4f60\u53ef\u4ee5\u4ece\u56fe\u4e2d\u770b\u5230\uff0c\u4e00\u4e2a Terminal \u53ef\u4ee5\u8fde\u63a5\u5230\u591a\u4e2a Shell\uff0c\u5c31\u50cf\u4e00\u53f0\u663e\u793a\u5668\u53ef\u4ee5\u8fde\u63a5\u5230\u591a\u53f0\u7535\u8111\u4e00\u6837\u3002\u628a Terminal \u7406\u89e3\u4e3a\u952e\u76d8\u548c\u663e\u793a\u5668\u5c31\u597d\u3002
  • Shell \u547d\u4ee4\u89e3\u91ca\u5668\uff1a\u63a5\u6536\u4f60\u7ed9\u51fa\u7684\u547d\u4ee4\u3001\u6267\u884c\u5e76\u7ed9\u51fa\u54cd\u5e94\u7684\uff0c\u5c31\u662f Shell\u3002\u5982\u679c\u628a Terminal \u7406\u89e3\u4e3a\u952e\u76d8\u548c\u663e\u793a\u5668\uff0c\u90a3\u4e48 Shell \u5c31\u662f\u4e3b\u673a\u3002
  • Prompt \u63d0\u793a\u7b26\uff1aShell \u4f1a\u7ed9\u4f60\u4e00\u4e2a\u63d0\u793a\u7b26\uff0c\u544a\u8bc9\u4f60\u5b83\u5df2\u7ecf\u51c6\u5907\u597d\u63a5\u6536\u4f60\u7684\u547d\u4ee4\u4e86\u3002\u5728 Linux \u4e2d\uff0c\u63d0\u793a\u7b26\u4e00\u822c\u662f $\u3002\u4e0b\u9762\u7684\u56fe\u4e2d\uff0cbowling \u90a3\u4e00\u5757\u5c31\u662f\u63d0\u793a\u7b26\uff08\u6211\u505a\u4e86\u4e00\u4e9b\u7f8e\u5316\uff09\u3002
  • Command Line Interface \u547d\u4ee4\u884c\u4ea4\u4e92\u754c\u9762\uff1a\u5f53\u6211\u4eec\u4f7f\u7528\u6587\u672c\u547d\u4ee4\u4e0e\u8ba1\u7b97\u673a\u4ea4\u4e92\u65f6\uff0c\u6211\u4eec\u5c31\u5728\u4f7f\u7528 CLI\u3002\u8fd9\u4e0e\u6211\u4eec\u65e5\u5e38\u751f\u6d3b\u4e2d\u4f7f\u7528\u9f20\u6807\u7684\u56fe\u5f62\u4ea4\u4e92\u754c\u9762\uff08Graphical User Interface\uff0cGUI\uff09\u4e0d\u540c\u3002

\u771f\u6b63\u610f\u4e49\u4e0a\u7684 Terminal

\u5728\u8ba1\u7b97\u673a\u53d1\u5c55\u7684\u65e9\u671f\u9636\u6bb5\uff0c\u8fd8\u6ca1\u6709\u50cf\u73b0\u5728\u7684 Windows \u8fd9\u6837\u7684\u56fe\u5f62\u7528\u6237\u754c\u9762\u3002\u90a3\u65f6\u4eba\u4eec\u4f7f\u7528\u7ec8\u7aef\u4e0e\u8ba1\u7b97\u673a\u4ea4\u4e92\u3002

Terminal \u548c Shell \u7684\u4f8b\u5b50

\u8fd9\u5f20\u56fe\u5c55\u793a\u4e86 Windows Terminal \u548c Powershell\u3002

Terminal \u548c Shell \u7684\u5173\u7cfb

\u53ef\u4ee5\u5c06 Terminal \u7406\u89e3\u6210\u663e\u793a\u5668\uff0c\u5c06 Shell \u7406\u89e3\u6210\u7535\u8111\u4e3b\u673a\u3002

\u6742\u8c08\uff1a\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528\u547d\u4ee4\u884c\u4ea4\u4e92\u754c\u9762\u5462\uff1f

\u5f88\u7b80\u5355\uff0c\u56e0\u4e3a\u6211\u4eec\u4e0d\u4ec5\u662f\u5728\u4f7f\u7528\u8ba1\u7b97\u673a\uff0c\u800c\u4e14\u662f\u5728\u5b66\u4e60\u8ba1\u7b97\u673a\u3002GUI \u81ea\u7136\u662f\u6700\u9002\u5408\u4e0e\u4eba\u4ea4\u4e92\u7684\uff0c\u4f46\u5b83\u4e5f\u662f\u7531 CLI \u642d\u5efa\u8d77\u6765\u7684\u3002\u6bd4\u5982\uff0c\u4f60\u53ef\u80fd\u5728\u4f7f\u7528 Dev-C++ \u6216 Visual Studio \u7b49 IDE \u8fdb\u884c\u7f16\u7a0b\uff0c\u53ea\u9700\u8981\u70b9\u4e00\u4e0b\u6309\u94ae\u5c31\u80fd\u81ea\u52a8\u5b8c\u6210\u7a0b\u5e8f\u7f16\u8bd1\u6b65\u9aa4\u3002\u8fd9\u56fa\u7136\u65b9\u4fbf\uff0c\u4f46\u662f\u5b83\u672c\u8d28\u4e0a\u662f\u5e2e\u4f60\u5199\u597d\u5e76\u6267\u884c\u4e86\u4e00\u7cfb\u5217\u7f16\u8bd1\u547d\u4ee4\uff0c\u5e2e\u4f60\u5b8c\u6210\u4e86\u547d\u4ee4\u884c\u7684\u64cd\u4f5c\u3002\u5f53\u4f60\u5f00\u59cb\u6784\u5efa\u5927\u578b\u9879\u76ee\u65f6\uff0c\u8fd9\u5f53\u7136\u662f\u6700\u9002\u5408\u7684\u65b9\u6cd5\u3002\u4f46\u4f5c\u4e3a\u521d\u5b66\u8005\uff0c\u6211\u4eec\u5e94\u5f53\u8d81\u6b64\u673a\u4f1a\u4e86\u89e3\u5176\u80cc\u540e\u7684\u539f\u7406\u3002

\u603b\u4e4b\uff1a\u5982\u679c\u8981\u5b66\u4e60\u8ba1\u7b97\u673a\uff0c\u90a3\u4e48\u5c31\u9700\u8981\u5b66\u4e60\u4f7f\u7528\u547d\u4ee4\u4e0e\u8ba1\u7b97\u673a\u4ea4\u4e92\uff0c\u8fd9\u6837\u624d\u80fd\u66f4\u597d\u5730\u7406\u89e3\u8ba1\u7b97\u673a\u662f\u5982\u4f55\u5de5\u4f5c\u7684\u3002\u6b64\u5916\uff0c\u547d\u4ee4\u884c\u4ea4\u4e92\u754c\u9762\u4e5f\u6709\u8bb8\u591a\u6709\u70b9\uff0c\u6bd4\u5982\uff1a

  • \u901f\u5ea6\u5feb\uff1a\u5728\u547d\u4ee4\u884c\u4e2d\uff0c\u4f60\u53ef\u4ee5\u5feb\u901f\u5730\u8f93\u5165\u547d\u4ee4\uff0c\u800c\u4e0d\u9700\u8981\u4f7f\u7528\u9f20\u6807\u70b9\u51fb\u83dc\u5355\u3002
  • \u53ef\u7f16\u7a0b\uff1a\u4f60\u53ef\u4ee5\u7f16\u5199\u811a\u672c\uff0c\u8ba9\u8ba1\u7b97\u673a\u81ea\u52a8\u6267\u884c\u4e00\u7cfb\u5217\u547d\u4ee4\u3002
  • \u53ef\u8fdc\u7a0b\uff1a\u4f60\u53ef\u4ee5\u901a\u8fc7\u7f51\u7edc\u8fde\u63a5\u5230\u8fdc\u7a0b\u8ba1\u7b97\u673a\uff0c\u4f7f\u7528\u547d\u4ee4\u884c\u4e0e\u5176\u4ea4\u4e92\u3002

\u6700\u4e3b\u8981\u7684\u662f\uff0c\u4f60\u4eca\u540e\u4f1a\u7528\u5230\u7684\u5f88\u591a\u5de5\u5177\u4e0d\u4e00\u5b9a\u4f1a\u63d0\u4f9b\u56fe\u5f62\u754c\u9762\uff0c\u4f46\u4e00\u5b9a\u4f1a\u63d0\u4f9b\u547d\u4ee4\u884c\u754c\u9762\u3002\u5b66\u4e60 CLI \u4e00\u5f00\u59cb\u786e\u5b9e\u6709\u4e9b\u96be\u5ea6\uff0c\u4f46\u53ea\u8981\u5b66\u4e86\uff0c\u5c31\u4f1a\u53d7\u76ca\u65e0\u7a77\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#_2","title":"\u8fd0\u884c\u4e0e\u7ec8\u7aef","text":"

\u5728 Windows \u4e0a\u5982\u4f55\u6253\u5f00 Terminal \u5462\uff1f

\u8fd0\u884c\u7a97\u53e3

\u4f7f\u7528 Win+R \u7ec4\u5408\u952e\uff0c\u5c06\u4f1a\u51fa\u73b0\u56fe\u4e2d\u7684\u7a97\u53e3\u3002\u53ef\u4ee5\u5728\u5176\u4e2d\u8f93\u5165\u547d\u4ee4\u8fd0\u884c\uff0c\u5373\u4f7f\u662f Windows XP \u90fd\u53ef\u4ee5\u4f7f\u7528\u3002

\u547d\u4ee4\u63d0\u793a\u7b26 CMD

\u5728\u8fd0\u884c\u7a97\u53e3\u4e2d\u8f93\u5165 cmd \u540e\u56de\u8f66\uff0c\u5c31\u4f1a\u51fa\u73b0\u547d\u4ee4\u63d0\u793a\u7b26\u3002\u547d\u4ee4\u63d0\u793a\u7b26\u662f Windows \u6700\u57fa\u672c\u7684 Shell\uff08\u4e0e Linux \u7684 bash \u540c\u7b49\u5730\u4f4d\uff09\uff0c\u4f46\u662f\u529f\u80fd\u53ca\u5176\u6709\u9650\uff0c\u4e00\u822c\u4e0d\u7528\u3002

Powershell

Powershell \u7b80\u79f0 pwsh\uff0c\u662f Windows \u7684\u65b0\u4e00\u4ee3\u547d\u4ee4\u89e3\u91ca\u5668\u3002\u5b83\u7684\u529f\u80fd\u5f3a\u5927\uff0c\u4f46\u8bed\u6cd5\u548c\u6211\u4eec\u5c06\u8981\u5b66\u4e60\u4e14\u6700\u5e38\u7528\u7684 Linux Shell \u5927\u4e0d\u76f8\u540c\u3002\u6211\u4eec\u5728 Windows \u4e0a\u7ecf\u5e38\u4f7f\u7528 pwsh\uff0c\u4f46\u4e0d\u7528\u82b1\u65f6\u95f4\u53bb\u5b66\u4e60\u5b83\u3002

Windows Terminal

\u8fd9\u662f Windows \u4e0a\u6700\u597d\u7684 Terminal\uff0c\u5bf9\u5404\u79cd Shell \u7684\u663e\u793a\u6548\u679c\u90fd\u652f\u6301\u7684\u5f88\u597d\u3002\u5728 Microsoft Store \u4e2d\u641c\u7d22 Terminal\uff0c\u51fa\u73b0\u56fe\u4e2d\u7684\u9009\u9879\uff0c\u7136\u540e\u9009\u62e9\u5b89\u88c5\u5373\u53ef\u3002\u5b83\u5bf9\u5e94\u4e8e macOS \u4e0a\u7684 iTerm\u3002\u4eca\u540e\u5b66\u4e60 ssh \u65f6\uff0c\u4f60\u8fd8\u53ef\u80fd\u4f1a\u63a5\u89e6\u5230 Termius\u3002

\u5728\u6bd4\u8f83\u65b0\u7248\u672c\u7684 Windows \u4e2d\uff0cWin \u952e\u6253\u5f00\u83dc\u5355\u4e4b\u540e\u8f93\u5165\u5b57\u7b26\u80fd\u591f\u641c\u7d22\u5230\u5bf9\u5e94\u7a0b\u5e8f\uff0c\u9664\u4e86\u5e38\u7528\u7684\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5916\uff0c\u542f\u52a8 cmd.exe \u4e5f\u53ef\u4ee5\u8fd9\u6837\u8fdb\u884c\uff0c\u6548\u679c\u548c Win + R \u76f8\u540c\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#wsl","title":"WSL \u5b89\u88c5\u7b80\u5355\u5f15\u5bfc\uff08\u53ef\u9009\uff09","text":"

\u63a8\u8350\u88c5\u4e00\u88c5\uff0c\u5982\u679c\u4e3b\u529b\u673a\u662f Windows \u5728\u4ee5\u540e\u5c06\u5bf9 WSL \u6709\u8f83\u5927\u9700\u6c42

WSL\uff0c\u5168\u79f0 Windows Subsystem for Linux\uff08\u9002\u7528\u4e8e Linux \u7684 Windows \u5b50\u7cfb\u7edf\uff09\uff0c\u662f\u4e00\u9879\u5141\u8bb8\u5f00\u53d1\u8005\u4e0d\u4f9d\u9760\u5355\u72ec\u7684\u865a\u62df\u673a\u6216\u53cc\u542f\u52a8 (dual booting) \u800c\u5728 Windows \u4e0a\u8fd0\u884c Linux \u73af\u5883\u7684\u529f\u80fd\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#ubuntu","title":"\u5b89\u88c5\uff1a\u4ee5 Ubuntu \u4e3a\u4f8b","text":"

\u5728\u8fd9\u91cc\u4ee5\u5728 Windows11 \u4e0a\u5b89\u88c5 WSL2 Ubuntu \u4e3a\u4f8b\u4ecb\u7ecd\u6700\u7b80\u5355\u7684\u5b89\u88c5\u6d41\u7a0b\uff0c\u8be6\u7ec6\u7684\u4fe1\u606f\u53ef\u4ee5\u53c2\u8003\u5b98\u65b9\u6587\u6863 Install Linux on Windows with WSL \u6216\u8005\u5b83\u7684\u4e2d\u6587\u7248\u3002

Ubuntu \u662f Linux \u7684\u4e00\u79cd\u53d1\u884c\u7248\u672c\uff0c\u5728\u8fd9\u91cc\u5c31\u4e0d\u5bf9 Linux \u7684\u4f17\u591a\u53d1\u884c\u7248\u672c\u8fdb\u884c\u4ecb\u7ecd\u548c\u8bc4\u4ef7\u4e86\u3002\u6709\u80fd\u529b\u548c\u60f3\u6cd5\u7684\u540c\u5b66\u53ef\u4ee5\u81ea\u5df1\u5bf9\u7167\u6559\u7a0b\u5b89\u88c5\u5176\u4ed6\u53d1\u884c\u7248\uff0c\u6bd4\u5982\u5728\u7ec8\u7aef\u8f93\u5165 wsl --list --online \u53ef\u4ee5\u770b\u5230\u6240\u6709\u53ef\u4ee5\u9009\u62e9\u7684 Linux \u53d1\u884c\u7248

\u6ce8\u610f\u5b89\u88c5 WSL \u7684\u5148\u51b3\u6761\u4ef6\uff1aWindows \u7248\u672c\u4e0d\u4f4e\u4e8e Windows 10 20H2\uff08Build 19042\uff09\u6216\u8005 Windows 11\u3002\u5982\u679c\u7248\u672c\u592a\u8001\uff0c\u8bf7\u66f4\u65b0\u5230\u6700\u65b0\u7248\u672c\uff0c\u5982\u679c\u65e0\u6cd5\u66f4\u65b0\u53ef\u4ee5\u8003\u8651\u91cd\u88c5\u7cfb\u7edf\u3002

\u53ef\u4ee5\u4f7f\u7528 winver \u547d\u4ee4\u67e5\u8be2 Windows \u7248\u672c\uff0cWin + R \u8f93\u5165 winver \u6216\u8005\u5728 Win \u952e\u51fa\u73b0\u7684\u83dc\u5355\u680f\u4e2d\u76f4\u63a5\u8f93\u5165 winver \u90fd\u53ef\u4ee5\u542f\u52a8\u3002\u65b0\u4e70\u7684\u7535\u8111\u53ef\u80fd Windows 11 \u5c45\u591a\uff0c\u5982\u679c\u662f Windows 10 \u7684\u7535\u8111\u7248\u672c\u663e\u793a\u53ef\u80fd\u662f 21H2\uff08\u64cd\u4f5c\u7cfb\u7edf\u5185\u90e8\u7248\u672c 19044.3086\uff09\uff0c\u8fd9\u6837\u4e5f\u662f\u7b26\u5408\u5148\u51b3\u6761\u4ef6\u7684\u3002

\u5728 Powershell\uff08\u7ba1\u7406\u5458\uff09\u4e2d\u76f4\u63a5\u4f7f\u7528\u5982\u4e0b\u547d\u4ee4\u81ea\u52a8\u5b89\u88c5\uff08\u6ce8\u610f\uff0c\u6bcf\u4e00\u884c\u547d\u4ee4\u5206\u522b\u6267\u884c\uff0c\u4e0d\u8981\u591a\u884c\u7c98\u8d34\u6267\u884c\uff09\uff1a

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart\ndism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart\nwsl --install\n

\u4e2d\u9014\u53ef\u80fd\u4f1a\u5f39\u51fa\u4e24\u4e2a\u7a97\u53e3\uff0c\u663e\u793a\u6b63\u5728\u4fee\u6539\u4ec0\u4e48\u4e1c\u897f\uff0c\u7edf\u7edf\u9009\u62e9\u201c\u662f\u201d\u3002\u5b89\u88c5\u5b8c\u6210\u540e\uff0c\u5c06\u51fa\u73b0\u5982\u4e0b\u754c\u9762

  • \u8bbe\u7f6e\u4e00\u4e2a\u7528\u6237\u540d\uff0c\u5efa\u8bae\u5168\u82f1\u6587\u65e0\u7a7a\u683c
    • \u82e5\u6709\u7a7a\u683c\uff0c\u5c06\u4f1a\u53ea\u53d6\u7b2c\u4e00\u4e2a\u7a7a\u683c\u524d\u9762\u7684\u5185\u5bb9\u4f5c\u4e3a\u4f60\u7684\u7528\u6237\u540d
  • \u8f93\u5165\u5bc6\u7801\uff0c\u6ce8\u610f\u4f60\u8f93\u5165\u7684\u5b57\u7b26\u4e0d\u4f1a\u5728\u5c4f\u5e55\u4e0a\u663e\u793a\uff0c\u9700\u8981\u76f2\u6253
    • \u5982\u679c\u6253\u4e86\u4e71\u4e03\u516b\u7cdf\u7684\u5b57\u7b26\u4e0d\u8981\u614c\uff0c\u786e\u8ba4\u5bc6\u7801\u65f6\u6545\u610f\u6253\u9519\u4f1a\u91cd\u65b0\u8ba9\u4f60\u8bbe\u7f6e\u5bc6\u7801
    • \u786e\u8ba4\u5bc6\u7801\u4e0e\u8f93\u5165\u5bc6\u7801\u4e00\u81f4\u624d\u4f1a\u8bbe\u7f6e\u6210\u529f

\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86 WSL2 Ubuntu \u7684\u5b89\u88c5\u3002

\u9519\u8bef\uff1a0x80370114

  • \u9996\u5148\u68c0\u67e5\u81ea\u5df1\u662f\u5426\u4e3a Windows 10 \u6216\u8005 Windows 11 \u5bb6\u5ead\u7248\u3002\u8fd9\u4e24\u4e2a\u7248\u672c\u53ef\u80fd\u7f3a\u5931 Hyper-V \u670d\u52a1\uff08WSL \u80cc\u540e\u7684\u865a\u62df\u5316\u652f\u6301\u6280\u672f\uff09\u3002\u8bf7\u6309\u7167\u77e5\u4e4e\uff1a\u5982\u4f55\u5728 Windows 11 Home \u4e2d\u542f\u7528 Hyper-V\u8fd9\u7bc7\u6587\u7ae0\u7684\u65b9\u6cd5\u542f\u7528 Hyper-V\u3002
  • \u5982\u679c\u4ecd\u65e0\u6cd5\u89e3\u51b3\uff0c\u518d\u6309\u7167\u77e5\u4e4e\uff1awin10\u4f7f\u7528wsl2\u5b89\u88c5ubuntu\u9047\u52300x80370114\u95ee\u9898\u7684\u89e3\u51b3\u65b9\u6cd5\u8fd9\u7bc7\u6587\u7ae0\u91cd\u65b0\u542f\u52a8\u865a\u62df\u673a\u5e73\u53f0\u3002

\u4f7f\u7528\u7ec8\u7aef\u7684\u4e00\u5927\u597d\u5904\u662f\u65b9\u4fbf\u6253\u5f00 WSL\u3002\u5982\u4e0b\u56fe\u6240\u793a\uff0c\u70b9\u51fb Ubuntu 22.04.2 LTS \u6216\u8005\u4f7f\u7528 Ctrl + Shift + 5 \u7ec4\u5408\u952e\u5c31\u53ef\u4ee5\u65b9\u4fbf\u5730\u6253\u5f00 Ubuntu 22.04\u3002\u5f53\u7136\u8fd9\u662f\u56e0\u4e3a\u6211\u5b89\u88c5\u7684\u662f Ubuntu 22.04 \u7684\u7f18\u6545\uff0c\u5728\u4f60\u4eec\u7684\u7535\u8111\u4e2d\u663e\u793a\u7684\u5e94\u8be5\u5c31\u662f Ubuntu\u3002

\u5176\u4ed6 WSL \u7684\u4f7f\u7528\u65b9\u6cd5\u7559\u5f85\u4f60\u4eec\u6162\u6162\u63a2\u7d22\u4e86\uff0c\u5728\u6b64\u4e0d\u518d\u8d58\u8ff0\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#c","title":"\u5b89\u88c5 C \u8bed\u8a00\u7f16\u8bd1\u5668","text":"

\u5982\u679c\u5df2\u7ecf\u5b89\u88c5\u597d WSL\uff0c\u90a3\u4e48\u53ef\u4ee5\u8df3\u8fc7\u672c\u8282\uff0c\u56e0\u4e3a\u57fa\u672c\u4e0a\u4e0d\u9700\u8981\u5728 Windows \u4e0a\u518d\u5b89\u88c5\u7f16\u8bd1\u73af\u5883\u4e86\u3002

\u672c\u7bc7\u76f8\u5bf9\u6bd4\u8f83\u590d\u6742\uff0c\u5982\u679c\u5728\u672c\u7bc7\u914d\u7f6e\u9047\u5230\u96be\u4ee5\u89e3\u51b3\u7684\u56f0\u96be\uff0c\u800c\u4f5c\u4e1a/\u5b9e\u9a8c\u622a\u6b62\u65e5\u671f\u5feb\u8981\u5230\u4e86\uff0c\u53ef\u4ee5\u8df3\u8fc7\u672c\u7bc7\u5b89\u88c5 Dev-C++ \u8fdb\u884c\u4e34\u65f6\u5f00\u53d1\u3002

\u5199\u5b8c\u4e86 C \u8bed\u8a00\u4ee3\u7801\uff0c\u6211\u4eec\u9700\u8981\u8ba9\u5b83\u53d8\u6210\u80fd\u8dd1\u7684\u7a0b\u5e8f\uff0c\u8fd9\u5c31\u9700\u8981\u51c6\u5907 C \u8bed\u8a00\u7684\u7f16\u8bd1\u5668\u652f\u6301\u3002\u4ee5\u4e0b\u4e3b\u8981\u4ecb\u7ecd Windows \u7cfb\u7edf\u7684\u914d\u7f6e\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#gcc","title":"\u5c31\u51b3\u5b9a\u662f\u4f60\u4e86\uff0cgcc\uff01","text":"

\u81ea\u7531\u8f6f\u4ef6 (free software)\uff0c\u6839\u636e\u81ea\u7531\u8f6f\u4ef6\u57fa\u91d1\u4f1a\u5bf9\u5176\u7684\u5b9a\u4e49\uff0c\u662f\u4e00\u7c7b\u53ef\u4ee5\u4e0d\u53d7\u9650\u5236\u5730\u81ea\u7531\u4f7f\u7528\u3001\u590d\u5236\u3001\u7814\u7a76\u3001\u4fee\u6539\u548c\u5206\u53d1\u7684\uff0c\u5c0a\u91cd\u7528\u6237\u81ea\u7531\u7684\u8f6f\u4ef6\u3002\u2014\u2014\u7ef4\u57fa\u767e\u79d1

gcc\uff0c\u5168\u79f0 GNU Compiler Collection\uff0c\u8457\u540d\u7684\u81ea\u7531\u8f6f\u4ef6\uff0c\u88ab\u8bb8\u591a\u73b0\u4ee3\u7c7b Unix \u64cd\u4f5c\u7cfb\u7edf\u91c7\u7528\u4e3a\u6807\u51c6\u7f16\u8bd1\u5668\uff0c\u4f46\u662f Windows \u4e0a\u5e76\u4e0d\u76f4\u63a5\u652f\u6301\u3002\u6211\u4eec\u60f3\u8981\u5728 Windows \u7cfb\u7edf\u4e0a\u4f7f\u7528\uff0c\u4e00\u822c\u5f97\u4f9d\u8d56 MinGW \u7684 gcc\uff0ctdm-gcc \u4e5f\u662f\u57fa\u4e8e MinGW \u7684 gcc \u6765\u7684\u3002

\u6709\u80fd\u529b\u7684\u540c\u5b66\u63a8\u8350\u5728 Windows \u4e0a\u5f00\u542f WSL\uff0c\u4f7f\u7528 WSL \u8fdb\u884c C \u8bed\u8a00\u5f00\u53d1\u3002WSL \u53ef\u4ee5\u7406\u89e3\u4e3a\u5728 Windows \u7684\u7535\u8111\u4e2d\u6a21\u62df\u4e00\u4e2a Linux \u7684\u5c0f\u7cfb\u7edf\uff0c\u4ece\u800c\u80fd\u65b9\u4fbf\u5730\u63a7\u5236\u73af\u5883\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#windows-tdm-gcc","title":"Windows \u5c0f\u767d\u6559\u7a0b\u4e4b tdm-gcc","text":"

\u524d\u9762\u9009\u62e9\u4e86 WSL \u7684\u540c\u5b66\u53ef\u4ee5\u81ea\u884c\u914d\u7f6e\uff0c\u7136\u540e\u518d\u770b\u7b2c 3 \u8282\u3002Mac \u7528\u6237\u53ef\u4ee5\u76f4\u63a5\u770b\u7b2c 3 \u8282\u3002

\u53ef\u4ee5\u6309\u7167\u8001\u5e08\u7684\u89c6\u9891\u6559\u7a0b\u4e0b\u8f7d tdm-gcc\uff0c\u76ee\u524d\u6700\u65b0\u7248\u4e3a gcc 10.3.0\u3002

\u9700\u8981\u5224\u65ad\u81ea\u5df1\u7684 Windows \u662f 64 \u4f4d\u7cfb\u7edf\u8fd8\u662f 32 \u4f4d\u7cfb\u7edf\uff08\u73b0\u5728\u4e00\u822c\u90fd\u662f 64 \u4f4d\u7cfb\u7edf\uff09\u3002

Windows 11Windows 10

\u70b9\u51fb Win \u952e\uff0c\u8f93\u5165\u201c\u5173\u4e8e\u201d\uff0c\u5982\u4e0b\u56fe\u6240\u793a\u3002\u6253\u5f00\u201c\u5173\u4e8e\u4f60\u7684\u7535\u8111\u201d\u540e\u5c31\u53ef\u4ee5\u770b\u5230\u7535\u8111\u662f\u4e0d\u662f 64 \u4f4d\u4e86\uff0c\u65b0\u7535\u8111\u4e00\u822c\u90fd\u662f 64 \u4f4d\u3002

\u684c\u9762\u627e\u5230\u201c\u6b64\u7535\u8111\u201d\uff0c\u53f3\u952e\u5c5e\u6027

\u53ef\u4ee5\u770b\u5230\u662f 64 \u4f4d\u7cfb\u7edf\u8fd8\u662f 32 \u4f4d\u7cfb\u7edf\u3002

64 \u4f4d\u7cfb\u7edf\u76f4\u63a5\u4e0b\u8f7d tdm64-gcc-10.3.0-2.exe \u5b89\u88c5\u5373\u53ef\uff0c32 \u4f4d\u5219\u9009\u62e9 tdm-gcc-10.3.0.exe\u3002

\u51c6\u5907\u5b89\u88c5\u3002\u5bf9\u4e8e\u96f6\u57fa\u7840\u7684\u540c\u5b66\uff0c\u7535\u8111\u91cc\u5e94\u8be5\u8fd8\u6ca1\u88c5\u8fc7 tdm-gcc\uff0c\u9009\u62e9 create \u5373\u53ef\u3002

\u63a5\u4e0b\u6765\u5c31\u662f\u6839\u636e 64/32 \u4f4d\u7cfb\u7edf\u9009\u62e9\u5bf9\u5e94\u7684\u7248\u672c

\u9009\u62e9\u5b89\u88c5\u8def\u5f84\uff0c\u63a8\u8350\u96f6\u57fa\u7840\u540c\u5b66\u9009\u62e9\u9ed8\u8ba4\u8def\u5f84\uff08\u5982 64 \u4f4d\u7684 C:\\TDM-GCC-64\uff09

\u63a5\u4e0b\u6765\u662f\u8981\u8ba4\u771f\u8003\u8651\u7684\u9875\u9762\u3002

  • \u53ef\u9009\u7684\u5b89\u88c5\u9879
    • \u53ef\u4ee5\u5168\u9009\u3002\u5982\u679c\u786e\u5b9a\u4e0d\u9700\u8981\u4e00\u4e9b\u4e1c\u897f\u53ef\u4ee5\u4e0d\u9009\uff0c\u6bd4\u5982\u786e\u5b9a\u81ea\u5df1\u4e0d\u4f1a\u518d\u9700\u8981\u8c03\u8bd5 32 \u4f4d\u7a0b\u5e8f\u7684\u8bdd\u53ef\u4ee5\u4e0d\u9009 gdb32\u3002
  • Start Menu items
    • \u770b\u4e2a\u4eba\u610f\u613f\uff0c\u53ef\u4ee5\u4e0d\u9009
  • Add to PATH
    • \u5efa\u8bae\u9009\u4e0a\u3002\u5982\u679c\u4e0d\u9009\u6216\u8005\u5fd8\u9009\u4e86\uff0c\u5c06\u4f1a\u9700\u8981\u81ea\u5df1\u914d\u7f6e tdm-gcc \u7684\u73af\u5883\u53d8\u91cf\u8def\u5f84\u3002

\u5982\u679c\u5e0c\u671b\u7528\u66f4\u65b0\u7248\u672c\u7684 gcc \u53ef\u4ee5\u4f7f\u7528 winlibs \u7f16\u8bd1\u7684 mingw-gcc\uff0c\u6216\u8005\u4f60\u53ef\u4ee5\u81ea\u5df1\u9009\u62e9\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#gcc_1","title":"\u6d4b\u8bd5 gcc \u662f\u5426\u6b63\u786e\u5b89\u88c5","text":"WindowsWSLmacOS

\u5728\u547d\u4ee4\u63d0\u793a\u7b26/\u7ec8\u7aef\u4e2d\u8f93\u5165 gcc\uff0c\u5e94\u5f53\u51fa\u73b0\u5982\u4e0b\u4fe1\u606f\uff1a

gcc: fatal error: no input files\ncompilation terminated.\n

\u5982\u679c\u6ca1\u6709\uff0c\u53ef\u80fd\u662f\u4f60\u8fd8\u6ca1\u6709\u5b89\u88c5 gcc\uff0c\u6216\u8005\u4f60\u524d\u4e00\u6b65 Add to PATH \u6ca1\u6709\u6b63\u5e38\u8fdb\u884c\uff0c\u53ef\u80fd\u9700\u8981\u53c2\u7167 Windows \u4fee\u6539\u73af\u5883\u53d8\u91cf\u8fdb\u884c\u73af\u5883\u53d8\u91cf\u7684\u68c0\u67e5\u3002

\u547d\u4ee4\u63d0\u793a\u7b26/\u7ec8\u7aef\u4e2d\u8f93\u5165 gcc --version\uff0c\u5e94\u5f53\u51fa\u73b0\u7c7b\u4f3c\u5982\u4e0b\u7684\u4fe1\u606f\u3002

gcc.exe (tdm64-1) 9.2.0\nCopyright (C) 2019 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n

\u6211\u7684\u7248\u672c\u663e\u793a\u662f 9.2.0\uff0c\u662f\u56e0\u4e3a\u88c5\u4e86\u65e7\u7248\u672c\u7684 tdm-gcc\uff0c\u4f60\u4eec\u7684\u663e\u793a\u5c06\u4f1a\u662f 10.3.0\u3002

\u5982\u4e0b\u547d\u4ee4\u5b89\u88c5 gcc\u3002\u5982\u679c\u9519\u8bef\uff0c\u5c1d\u8bd5 sudo apt-get update \u540e\u518d\u91cd\u65b0\u6267\u884c\u4e0b\u9762\u7684\u547d\u4ee4\u3002

sudo apt install gcc\n

\u7ec8\u7aef\u4e2d\u8f93\u5165 gcc\uff0c\u5e94\u5f53\u51fa\u73b0\u5982\u4e0b\u4fe1\u606f\uff1a

gcc: fatal error: no input files\ncompilation terminated.\n

\u7ec8\u7aef\u4e2d\u8f93\u5165 gcc --version\uff0c\u53ef\u80fd\u4f1a\u51fa\u73b0\u7c7b\u4f3c\u5982\u4e0b\u7684\u4fe1\u606f\uff1a

gcc (Ubuntu 11.2.0-19ubuntu1) 11.2.0\nCopyright (C) 2021 Free Software Foundation, Inc.\nThis is free software; see the source for copying conditions.  There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n

Mac \u7528\u6237\u76f4\u63a5\u4f7f\u7528 gcc -v \uff08\u6216\u8005 xcode-select --install\uff09\u4f1a\u63d0\u793a\u4f60\u5b89\u88c5\u5f00\u53d1\u8005\u5de5\u5177\uff0c\u7136\u540e\u5c31\u4f1a\u81ea\u52a8\u5b89\u88c5 XCode \u5728\u5185\u7684\u4e00\u7cfb\u5217\u5f00\u53d1\u652f\u6301\uff0c\u6700\u540e\u544a\u8bc9\u4f60\u4f60\u5b89\u88c5\u7684 gcc \u5176\u5b9e\u662f clang\uff0c\u672c\u8d28\u4e0a\u662f\u5b83\u5c06 gcc \u4f5c\u4e3a clang \u7684\u522b\u540d (alias) \u4e86\u3002

\u6210\u529f\u5b89\u88c5\u540e\uff0c\u7ec8\u7aef\u8f93\u5165 gcc \u4f1a\u51fa\u73b0\u5982\u4e0b\u4fe1\u606f\uff1a

clang: error: no input files\n

\u4f7f\u7528 gcc --version \u53ef\u80fd\u51fa\u73b0\u4ee5\u4e0b\u4fe1\u606f\uff1a

Apple clang version 14.0.3 (clang-1403.0.22.14.1)\nTarget: x86_64-apple-darwin22.6.0\nThread model: posix\nInstalledDir: /Library/Developer/CommandLineTools/usr/bin\n

gcc \u548c clang \u90fd\u662f C \u8bed\u8a00\u7f16\u8bd1\u5668\uff0c\u53ea\u662f\u7279\u6027\u4e0a\u5b58\u5728\u5dee\u5f02\u3002\u5728\u4f5c\u4e1a\u548c\u5b9e\u9a8c\u4e2d\uff0c\u4e00\u4e2a\u597d\u7684\u9075\u4ece\u6807\u51c6\u7684 C \u4ee3\u7801\uff0c\u7531\u4e0d\u540c\u7684\u7f16\u8bd1\u5668\u7f16\u8bd1\u540e\u4e0d\u5e94\u5f53\u4ea7\u751f\u4e0d\u540c\u7684\u8fd0\u884c\u7ed3\u679c\u3002\u56e0\u6b64\u5982\u679c\u4f60\u4f7f\u7528 clang \u7f16\u8bd1 C \u4ee3\u7801\u8fd0\u884c\u4e0d\u7b26\u5408\u9884\u671f\uff0c\u4ee3\u7801\u51fa\u95ee\u9898\u7684\u6982\u7387\u6bd4 clang \u7279\u6027\u51fa\u95ee\u9898\u7684\u6982\u7387\u5927\u5f88\u591a\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#windows","title":"Windows \u4fee\u6539\u73af\u5883\u53d8\u91cf","text":"

Windows \u7528\u6237\u73af\u5883\u53d8\u91cf\u914d\u7f6e\u51fa\u73b0\u95ee\u9898\u4e86\u624d\u9700\u8981\u770b\u8fd9\u4e00\u5c0f\u8282

\u68c0\u67e5\u4e00\u4e0b\u73af\u5883\u53d8\u91cf\uff0cWin + R \u952e\u8f93\u5165 sysdm.cpl \u540e\u56de\u8f66\uff0c\u4f1a\u51fa\u73b0 \u201c\u7cfb\u7edf\u5c5e\u6027\u201d \u754c\u9762\uff0c\u9009\u62e9 \u201c\u9ad8\u7ea7\u201d\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff1a

\u6253\u5f00\u73af\u5883\u53d8\u91cf\uff0c\u5728 \u201c\u7cfb\u7edf\u53d8\u91cf\u201d \u6216\u8005 \u201c\u7528\u6237\u53d8\u91cf\u201d \u4e2d\u627e\u5230 PATH \u53d8\u91cf\uff0c\u5728\u5176\u4e2d\u589e\u52a0\u4e00\u9879 tdm-gcc \u7684\u8def\u5f84\u3002\u4f8b\u5982\u4f60\u5982\u679c\u9ed8\u8ba4\u5b89\u88c5 tdm-gcc\uff0c\u90a3\u4e48\u8def\u5f84\u53ef\u80fd\u5c31\u662f C:\\TDM-GCC-64\\bin\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#vscode","title":"VSCode \u5b89\u88c5\u4e0e\u914d\u7f6e","text":"

VSCode \u7684\u5168\u79f0\u662f Visual Studio Code\uff0c\u6ce8\u610f\u5b83\u548c Visual Studio \u5b8c\u5168\u662f\u4e24\u4e2a\u4e1c\u897f

\u4e0d\u5efa\u8bae\u5b89\u88c5 Visual Studio\uff0c\u9664\u975e\u4f60\u6e05\u695a\u4f60\u5b89\u88c5\u5b83\u662f\u4e3a\u4e86\u4ec0\u4e48

\u5728\u8fd9\u91cc\u4ec5\u4ecb\u7ecd Visual Studio Code \u7684\u5b89\u88c5\u3002\u9664\u4e86\u8001\u5e08\u7684\u89c6\u9891\u4e4b\u5916\uff0c\u5927\u5bb6\u5b89\u88c5\u914d\u7f6e\u65f6\u8fd8\u53ef\u4ee5\u53c2\u8003 GZTime \u7684\u6559\u7a0b\uff0c\u5bf9\u4e8e\u521d\u5b66\u8005\u6765\u8bf4\u8fd8\u4e0d\u9519\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#_3","title":"\u5b89\u88c5","text":"

VSCode \u76f4\u63a5\u4ece\u5b98\u7f51\u9009\u62e9\u81ea\u5df1\u5e73\u53f0\u5bf9\u5e94\u7684\u5b89\u88c5\u5305\u4e0b\u8f7d\u5c31\u884c

WindowsMac

Windows \u7684 exe \u5b89\u88c5\u53ef\u4ee5\u5168\u9009\u9ed8\u8ba4\u9009\u9879\u4e00\u8def Next\uff0c\u6bd4\u8f83\u719f\u6089\u7684\u540c\u5b66\u53ef\u4ee5\u81ea\u5b9a\u4e49\u9009\u9879\uff1a

  • \u5b89\u88c5\u76ee\u5f55
    • \u63a8\u8350\u9ed8\u8ba4 C \u76d8\uff0c\u53ef\u80fd\u8fd0\u884c\u901f\u5ea6\u66f4\u5feb\uff0c\u4e5f\u53ef\u4ee5\u907f\u514d\u4e00\u4e9b\u6743\u9650\u95ee\u9898
  • \u5c06 \u201c\u901a\u8fc7 Code \u6253\u5f00\u201d \u64cd\u4f5c\u6dfb\u52a0\u5230 Windows \u8d44\u6e90\u7ba1\u7406\u5668\u6587\u4ef6/\u76ee\u5f55\u4e0a\u4e0b\u6587\u83dc\u5355
    • \u9009\u4e2d\u8be5\u9879\u540e\uff0c\u9009\u4e2d\u6587\u4ef6\u6216\u8005\u6587\u4ef6\u5939\uff0c\u53f3\u952e\u83dc\u5355\u4e2d\u4f1a\u51fa\u73b0 \u901a\u8fc7 Code \u6253\u5f00 \u7684\u9009\u9879
    • \u5982\u679c\u5e0c\u671b\u53f3\u952e\u83dc\u5355\u4e0d\u90a3\u4e48\u81c3\u80bf\u7684\u8bdd\u53ef\u4ee5\u4e0d\u9009\u8fd9\u4e00\u9879
    • \u672c\u4eba\u6ca1\u6709\u9009\u62e9\u8be5\u9009\u9879\uff0c\u53ef\u4ee5\u81ea\u884c\u601d\u8003\u9009\u62e9
  • \u5c06 Code \u6ce8\u518c\u4e3a\u53d7\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\u7684\u7f16\u8f91\u5668\uff08\u63a8\u8350\uff09
    • \u6253\u5f00\u53d7\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\u65f6\uff0cVSCode \u5c06\u4f1a\u6210\u4e3a\u53ef\u9009\u9879
  • \u6dfb\u52a0\u5230 PATH\uff08\u63a8\u8350\uff09
    • \u5728\u547d\u4ee4\u884c\u7a97\u53e3/\u7ec8\u7aef\u53ef\u4ee5\u7528 code \u547d\u4ee4\u6253\u5f00 VSCode

Mac \u7684\u5305\u4e0b\u8f7d\u4e0b\u6765\u4e4b\u540e\u62d6\u5165 Application \u6587\u4ef6\u5939\u53ef\u4ee5\u76f4\u63a5\u8fd0\u884c

  • \u6dfb\u52a0\u5230 PATH\uff1a\u5982\u679c\u9700\u8981\u5728\u547d\u4ee4\u884c\u7a97\u53e3/\u7ec8\u7aef\u7528 code \u547d\u4ee4\u6253\u5f00 VSCode\uff0c\u90a3\u4e48\u9700\u8981\u5982\u4e0b\u64cd\u4f5c
    • \u6253\u5f00 VSCode \u754c\u9762
    • \u4f7f\u7528 Shift + Command + P \u6253\u5f00\u547d\u4ee4\u9762\u677f
    • \u8f93\u5165 shell command\uff0c\u9009\u62e9 Shell Command: Install \u2018code\u2019 command in PATH \u56de\u8f66\u6267\u884c
"},{"location":"programming_lecture/lecture1/pre_class/#_4","title":"\u63d2\u4ef6\u5b89\u88c5","text":"

\u6253\u5f00 VSCode \u540e\uff0c\u5728\u5de6\u4fa7\u7ad6\u680f\u5bfb\u627e\u4e0b\u9762\u8fd9\u4e2a\u56fe\u6807\uff1a

\u70b9\u51fb\u8fd9\u4e2a\u56fe\u6807\u5c31\u8fdb\u5165\u4e86\u63d2\u4ef6\u7ba1\u7406\u3002\u5efa\u8bae\u53ef\u4ee5\u5b89\u88c5\u4e0b\u9762\u4e24\u4e2a\u63d2\u4ef6\uff1a

  • C/C++: \u5fae\u8f6f\u81ea\u5bb6\u7684\u63d2\u4ef6\uff0c\u53ef\u7528\u4e8e\u8bed\u6cd5\u8bc6\u522b\u3001\u4ee3\u7801\u9ad8\u4eae
  • Chinese(Simplified): \u754c\u9762\u6c49\u5316\u63d2\u4ef6\uff08\u53ef\u9009\uff09

\u5b89\u88c5\u6c49\u5316\u63d2\u4ef6\u540e\u53ef\u80fd\u9700\u8981\u4f60\u624b\u52a8\u5207\u6362\u663e\u793a\u8bed\u8a00\u3002Ctrl + Shift + P\uff0c\u51fa\u73b0\u7684\u641c\u7d22\u6846\u4e2d\u8f93\u5165 Configure\uff0c\u9009\u62e9 Configure Display Language\u3002

\u968f\u540e\u518d\u9009\u62e9\u201c\u4e2d\u6587(\u7b80\u4f53)\u201d\u5c31\u53ef\u4ee5\u5b8c\u6210\u754c\u9762\u6c49\u5316\u4e86\u3002

\u82f1\u8bed\u57fa\u7840\u4e0d\u592a\u597d\u7684\u540c\u5b66\u6709\u56f0\u96be\u53ef\u4ee5\u4f7f\u7528\uff0c\u82f1\u8bed\u57fa\u7840\u6bd4\u8f83\u597d\u4ee5\u53ca\u60f3\u8981\u5728\u65e5\u5e38\u5b9e\u8df5\u4e2d\u5b66\u4e60\u82f1\u8bed\u7684\u540c\u5b66\u5efa\u8bae\u8df3\u8fc7\u8fd9\u4e00\u6b65\u3002

\u8fd9\u91cc\u53ea\u63d0\u4f9b\u6700\u57fa\u672c\u7684\u63d2\u4ef6\u548c\u4f7f\u7528\u793a\u4f8b\uff0c\u590d\u6742\u7684\u914d\u7f6e\u4e0e\u4f7f\u7528\u5927\u5bb6\u53ef\u4ee5\u53c2\u8003 GZTime \u7684\u6559\u7a0b

"},{"location":"programming_lecture/lecture1/pre_class/#vscode_1","title":"VSCode \u4f7f\u7528\u7684\u4e00\u4e2a\u7b80\u5355\u793a\u4f8b","text":"

\u8fd9\u91cc\u4e3a\u60f3\u8981\u5c3d\u5feb\u4e0a\u624b\u7684\u540c\u5b66\u63d0\u4f9b\u4e00\u4e2a\u7b80\u5355\u7684\u4f7f\u7528\u793a\u4f8b\u3002\u6253\u5f00 VSCode\uff08\u6253\u5f00\u65f6\u6ca1\u6709\u6307\u5b9a\u5de5\u4f5c\u76ee\u5f55\uff09\uff0c\u5c06\u4f1a\u51fa\u73b0\u5982\u4e0b\u7684\u7a97\u53e3\uff1a

\u5de5\u4f5c\u76ee\u5f55\uff0c\u6307\u67d0\u4e2a\u4e13\u95e8\u5b58\u653e\u4f60\u7528\u4e8e\u67d0\u4e2a\u76ee\u7684\u7684\u6587\u4ef6\u7684\u6587\u4ef6\u5939\u3002\u4f8b\u5982\u4f60\u53ef\u80fd\u4f1a\u5efa\u7acb\u4e00\u4e2a\u6587\u4ef6\u5939\uff0c\u4e13\u95e8\u5b58\u653e\u6240\u6709\u4e0e\u7b2c\u4e00\u6b21\u4f5c\u4e1a\u76f8\u5173\u7684\u4ee3\u7801\u3001\u6587\u6863\u3001\u914d\u7f6e\u6587\u4ef6\u7b49\uff0c\u5728\u4f60\u4e3a\u5b8c\u6210\u7b2c\u4e00\u6b21\u4f5c\u4e1a\u800c\u5de5\u4f5c\u65f6\uff0c\u8fd9\u4e2a\u6587\u4ef6\u5939\u5c31\u662f\u4f60\u7684\u5de5\u4f5c\u76ee\u5f55

\u70b9\u51fb\u5de6\u4fa7\u7684 Open Folder\uff0c\u9009\u62e9\u4e00\u4e2a\u76ee\u5f55\u4f5c\u4e3a\u4f60\u7684\u5de5\u4f5c\u76ee\u5f55\uff0c\u4e00\u822c\u4f1a\u628a\u4f60\u8fd9\u4e2a\u7a97\u53e3\u6240\u8981\u5904\u7406\u7684\u6240\u6709\u6587\u4ef6\u653e\u7f6e\u5728\u8fd9\u91cc\u3002\u9876\u680f Terminal > New Terminal\uff08\u6216\u7ec8\u7aef > \u65b0\u5efa\u7ec8\u7aef\uff09\u6253\u5f00 VSCode \u7684\u5185\u90e8\u7ec8\u7aef\uff0c\u529f\u80fd\u5927\u81f4\u4e0e\u547d\u4ee4\u63d0\u793a\u7b26/\u7ec8\u7aef\u76f8\u540c\u3002

\u4e0b\u56fe\u5c31\u662f\u6253\u5f00\u4e86\u5de5\u4f5c\u76ee\u5f55\u5e76\u65b0\u5efa\u4e86\u7ec8\u7aef\u7684\u754c\u9762\u72b6\u6001\u3002

\u9f20\u6807\u79fb\u52a8\u5230\u5de5\u4f5c\u533a\uff0c\u6309 New File \u952e\u53ef\u4ee5\u65b0\u5efa\u6587\u4ef6\uff0c\u65c1\u8fb9\u6709\u65b0\u5efa\u6587\u4ef6\u5939\u6309\u952e\u3002\u5f53\u7136\uff0c\u76f4\u63a5\u5728\u5de6\u4fa7\u5de5\u4f5c\u76ee\u5f55\u53f3\u952e\u4e5f\u53ef\u4ee5\u65b0\u5efa\u6587\u4ef6/\u6587\u4ef6\u5939\u3002

\u521b\u5efa test.c\uff0c\u8f93\u5165 Hello World \u7684\u4ee3\u7801\u5e76\u4fdd\u5b58\u6587\u4ef6\u3002\u7136\u540e\u5728\u7ec8\u7aef\u8f93\u5165\u4ee5\u4e0b\u547d\u4ee4\u5e76\u6267\u884c\uff1a

gcc test.c\n

\u5728\u4e0d\u540c\u7684\u7cfb\u7edf\u5c06\u4f1a\u751f\u6210\u4e0d\u540c\u7684\u7f16\u8bd1\u4ea7\u7269\u3002

WindowsWSL/macOS

\u5c06\u4f1a\u5728\u548c test.c \u540c\u76ee\u5f55\u4e0b\u751f\u6210 a.exe\uff0c\u968f\u540e\u5728\u7ec8\u7aef\u8f93\u5165\u4ee5\u4e0b\u547d\u4ee4\u8fdb\u884c\u6267\u884c

./a.exe\n

\u5c06\u4f1a\u5728\u548c test.c \u540c\u76ee\u5f55\u4e0b\u751f\u6210 a.out\uff0c\u968f\u540e\u5728\u7ec8\u7aef\u8f93\u5165\u4ee5\u4e0b\u547d\u4ee4\u8fdb\u884c\u6267\u884c

./a.out\n

\u4ee5\u4e0b\u5c55\u793a\u5728 macOS \u4e0a\u7684\u6267\u884c\u7ed3\u679c\uff1a

\u8fd9\u91cc\u6709\u51e0\u4e2a\u6ce8\u610f\u70b9\uff1a

  • \u8bb0\u5f97\u4fdd\u5b58\u6587\u4ef6\u540e\u518d gcc \u7f16\u8bd1\uff0c\u53ef\u4ee5\u8003\u8651\u5f00\u542f\u81ea\u52a8\u4fdd\u5b58
    • \u5982\u4e0b\u56fe\u6240\u793a\uff0c\u627e\u5230\u5de6\u4e0b\u89d2\u7684\u9f7f\u8f6e\u70b9\u51fb\u540e\u9009\u62e9 Setting \u6216\u8005\u8bbe\u7f6e\uff0c\u51fa\u73b0\u7684\u8bbe\u7f6e\u9875\u9762\u4e2d\u641c\u7d22 auto \u53ef\u4ee5\u627e\u5230\u5982\u56fe\u6240\u793a\u7684 Auto Save \u8bbe\u7f6e\u9879\uff0c\u8bbe\u7f6e\u4e3a afterDelay \u5373\u53ef
    • afterDelay \u662f\u5bf9\u6587\u4ef6\u505a\u51fa\u4fee\u6539\u5c31\u5b9e\u65f6\u4fdd\u5b58\uff0c\u5982\u679c\u5acc\u4fdd\u5b58\u9891\u7387\u8fc7\u9ad8\u53ef\u4ee5\u9009\u62e9 onFocusChange \u6216\u8005 onWindowsChange
    • \u6211\u672c\u4eba\u4f7f\u7528\u7684\u662f onFocusChange\uff0c\u8fd9\u6837\u79fb\u52a8\u5230\u7ec8\u7aef\u51c6\u5907\u7f16\u8bd1\u8fd0\u884c\u65f6\u6e90\u4ee3\u7801\u6587\u4ef6\u5c31\u4f1a\u81ea\u52a8\u4fdd\u5b58\uff0c\u65e2\u81ea\u52a8\u4fdd\u5b58\u53c8\u4e0d\u4f1a\u4fdd\u5b58\u592a\u9891\u7e41

  • \u5efa\u8bae\u5de5\u4f5c\u76ee\u5f55\u548c\u6587\u4ef6\u540d\u5168\u82f1\u6587\uff0c\u7ed9\u51fa\u4ee5\u4e0b\u51e0\u4e2a\u53cd\u9762\u6848\u4f8b\uff1a
    • \u6587\u4ef6\u540d \u4f5c\u4e1a.c
    • \u5de5\u4f5c\u76ee\u5f55 \u7f16\u7a0b
    • \u5de5\u4f5c\u76ee\u5f55\u53eb Coding\uff0c\u4f46\u662f\u7edd\u5bf9\u8def\u5f84\u662f D:/\u5b66\u4e60\u8d44\u6599/Coding
  • \u53ef\u4ee5\u6307\u5b9a\u7f16\u8bd1\u751f\u6210\u7684\u6587\u4ef6\u540d\uff0c\u6bd4\u5982\u4f60\u60f3\u8981\u8f93\u51fa\u6587\u4ef6\u540d\u4e3a hello.exe\uff0c\u5c31\u53ef\u4ee5\u6267\u884c
    gcc test.c -o hello.exe\n
  • \u66f4\u591a\u7684 gcc \u9009\u9879\u548c VSCode \u6269\u5c55\u529f\u80fd\u7559\u5f85\u4f60\u4eec\u63a2\u7d22
"},{"location":"programming_lecture/lecture1/pre_class/#vscode-wsl","title":"VSCode + WSL\uff08\u53ef\u9009\uff09","text":"

\u524d\u9762\u9009\u62e9\u5b89\u88c5\u4e86 WSL \u7684\u4f7f\u7528 Windows \u4e3b\u529b\u673a\u7684\u540c\u5b66\u53ef\u4ee5\u53c2\u8003\u4e00\u4e0b\uff0c\u975e\u5e38\u6709\u7528\u7684\u529f\u80fd

\u4ee5\u4e0b\u5f15\u5bfc\u4e3b\u8981\u6309\u7167 Microsoft \u7684\u5b98\u65b9\u6587\u6863\uff0c\u4e5f\u53ef\u4ee5\u53c2\u8003\u5176\u4e2d\u6587\u7248\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#vscode-wsl_1","title":"\u4ece VSCode \u8fde\u63a5\u5230 WSL","text":"

\u5b89\u88c5 WSL \u63d2\u4ef6\uff0c\u5982\u4e0b\u56fe\u6240\u793a\uff1a

\u6216\u8005\u4f60\u4e5f\u53ef\u4ee5\u50cf\u5b98\u65b9\u6587\u6863\u90a3\u6837\uff0c\u76f4\u63a5\u5b89\u88c5\u6574\u4e2a Remote Development \u6269\u5c55\u5305\uff1a

\u5176\u4e2d\u4e0d\u4ec5\u6709 WSL\uff0c\u8fd8\u5305\u62ec\u53e6\u5916\u4e09\u4e2a\u975e\u5e38\u6709\u7528\u7684\u8fdc\u7a0b\u5f00\u53d1\u63d2\u4ef6\u3002

  • Ctrl + Shift + P\uff0c\u5728\u51fa\u73b0\u7684\u547d\u4ee4\u6846\u4e2d\u8f93\u5165 WSL\uff0c\u9009\u62e9 WSL: Connect to WSL in New Window\uff08\u6216 WSL: \u5728\u65b0\u7a97\u53e3\u4e2d\u8fde\u63a5\u5230 WSL\uff09
  • \u5c06\u6253\u5f00\u4e00\u4e2a\u65b0\u7684 VSCode \u7a97\u53e3\uff0c\u91cc\u9762\u5df2\u7ecf\u8fde\u63a5\u5230\u9ed8\u8ba4\u7684 WSL \u73af\u5883

\u5982\u679c\u9700\u8981\u5728\u672c\u7a97\u53e3\u8fde\u63a5\u5230 WSL\uff0c\u6216\u8fde\u63a5\u5230\u975e\u9ed8\u8ba4\u7684 WSL \u6240\u5b89\u88c5\u7684\u5176\u4ed6 Linux \u53d1\u884c\u7248\uff0c\u53ef\u4ee5\u9009\u62e9\u5176\u4ed6 WSL \u7684\u547d\u4ee4

\u6ce8\u610f\u4e0a\u56fe\u5de6\u4e0b\u89d2\u6240\u663e\u793a\u7684\u72b6\u6001\uff0c\u8868\u660e\u5df2\u7ecf\u8fde\u63a5\u5230 WSL \u6240\u5b89\u88c5\u7684 Ubuntu-22.04\uff0c\u63a5\u4e0b\u6765\u7684\u5f00\u53d1\u64cd\u4f5c\u548c\u4e0a\u4e00\u8282\u5c31\u533a\u522b\u4e0d\u5927\u4e86\u3002

"},{"location":"programming_lecture/lecture1/pre_class/#wsl-vscode","title":"\u4ece WSL \u542f\u52a8 VSCode","text":"

\u786e\u4fdd\u4f60\u5df2\u7ecf\u5c06 VSCode \u6dfb\u52a0\u5230 PATH \u73af\u5883\u53d8\u91cf\u4e2d\u3002\u5982\u679c\u5df2\u7ecf\u6dfb\u52a0\uff0c\u90a3\u4e48\u76f4\u63a5\u5728 WSL \u7684\u547d\u4ee4\u884c\u4e2d\u4f60\u6240\u5e0c\u671b\u4f5c\u4e3a\u5de5\u4f5c\u76ee\u5f55\u7684\u4f4d\u7f6e\u6267\u884c

code .\n

\u5c31\u53ef\u4ee5\u6253\u5f00 VSCode\uff0c\u8fde\u63a5\u5230 WSL \u5e76\u4e14\u6253\u5f00\u8be5\u76ee\u5f55\u4f5c\u4e3a\u5de5\u4f5c\u76ee\u5f55\u3002. \u5728\u8fd9\u91cc\u8868\u793a\u5f53\u524d\u76ee\u5f55\u5373 pwd\uff0c\u5982\u679c\u5c06\u5b83\u66ff\u6362\u6210\u5176\u4ed6\u76ee\u5f55\u7684\u8def\u5f84\u4e5f\u662f\u53ef\u4ee5\u5c06\u5176\u6253\u5f00\u4f5c\u4e3a\u5de5\u4f5c\u76ee\u5f55\u7684\u3002

\u5982\u679c\u4f60\u8fd8\u672a\u5c06 VSCode \u6dfb\u52a0\u5230 PATH \u73af\u5883\u53d8\u91cf\u4e2d\uff0c\u90a3\u8be5\u529f\u80fd\u5c06\u65e0\u6cd5\u4f7f\u7528\uff0c\u9700\u8981\u4f60\u624b\u52a8\u6dfb\u52a0 VSCode \u5230 PATH \u73af\u5883\u53d8\u91cf\u3002\u4f8b\u5982\u4f60\u7684 Windows \u7528\u6237\u540d\u662f ZTM\uff0c\u5e76\u628a VSCode \u5b89\u88c5\u5728\u9ed8\u8ba4\u76ee\u5f55\uff0c\u90a3\u4e48\u9700\u8981\u5c06 C:\\Users\\ZTM\\AppData\\Local\\Programs\\Microsoft VS Code\\bin \u52a0\u5165\u5230 PATH \u73af\u5883\u53d8\u91cf\uff0c\u53c2\u8003 Windows \u4fee\u6539\u73af\u5883\u53d8\u91cf\u7ae0\u8282\u3002

"},{"location":"programming_lecture/lecture2/lecture2/","title":"\u7c7b\u578b\u7cfb\u7edf\u4e0e\u5185\u5b58\u6a21\u578b","text":"

\u65bd\u5de5\u4e2d

\u672c\u9875\u9762\u6b63\u5728\u7f16\u8f91\u4e2d\u3002

Abstract

  • C \u7c7b\u578b\u7cfb\u7edf\u7684\u5b8c\u6574\u63cf\u8ff0
  • \u5982\u4f55\u9605\u8bfb\u58f0\u660e
  • \u7a0b\u5e8f\u5185\u5b58\u7a7a\u95f4\u7684\u5e03\u5c40
  • \u5982\u4f55\u7ba1\u7406\u5185\u5b58
"},{"location":"programming_lecture/lecture2/lecture2/#_2","title":"\u7c7b\u578b\u7cfb\u7edf","text":"

Abstract

\u8be5\u90e8\u5206\u5728\u8bfe\u5802\u4e0a\u6709\u8f83\u4e3a\u8be6\u7ec6\u7684\u8bb2\u89e3\uff0c\u4f60\u5e94\u5f53\u5df2\u7ecf\u4e86\u89e3\u4e0b\u9762\u8fd9\u4e9b\u57fa\u672c\u6570\u636e\u7c7b\u578b\u7684\u4f7f\u7528\uff1a

  • \u6574\u578b\uff1aint\u3001long\u3001short\u3001char\u3001unsigned\u3001signed \u7b49\u3002
  • \u7ed3\u6784
"},{"location":"programming_lecture/lecture2/lecture2/#_3","title":"\u6570\u636e\u662f\u4ec0\u4e48\uff1f","text":"

todo: \u6570\u636e\u4e0e\u7c7b\u578b\u7684\u57fa\u672c\u6982\u5ff5

"},{"location":"programming_lecture/lecture2/lecture2/#c","title":"C \u8bed\u8a00\u7684\u7c7b\u578b\u7cfb\u7edf","text":"\u5b57\u7b26\u7c7b\u578b\u89e3\u60d1

\u6216\u8bb8\u4f60\u4f1a\u548c\u6211\u540c\u6837\u5bf9\u4ee5\u4e0b\u51e0\u4e2a\u95ee\u9898\u611f\u5230\u56f0\u60d1\uff1a

  • \u4e3a\u4ec0\u4e48\u5b57\u7b26\u5e38\u91cf\u7684\u7c7b\u578b\u662f int \u4e14\u957f\u5ea6\u662f 4 \u4e2a\u5b57\u8282\uff1f
  • \u4e3a\u4ec0\u4e48 getchar() \u7b49\u51fd\u6570\u8fd4\u56de int \u800c\u4e0d\u662f char\uff1f
  • \u5bbd\u5b57\u7b26\u3001\u591a\u5b57\u8282\u5b57\u7b26\u548c Unicode \u7a76\u7adf\u5982\u4f55\u4f7f\u7528\uff1f

\u8fd9\u91cc\u5c06\u89e3\u91ca\u524d\u4e24\u4e2a\u95ee\u9898\uff0c\u7b2c\u4e09\u4e2a\u95ee\u9898\u4e0d\u505a\u8981\u6c42\uff0c\u6709\u5174\u8da3\u53ef\u4ee5\u53c2\u770b\u4e2d\u7684\u76f8\u5173\u5185\u5bb9\u3002

  • \u5b57\u7b26\u5e38\u91cf\u7684\u7c7b\u578b\u4e3a\u4ec0\u4e48\u662f int\uff1f

\u591a\u5b57\u7b26\u5e38\u91cf\uff08Multicharacter constants\uff09\u7ee7\u627f\u4e8e C \u8bed\u8a00\u7684\u524d\u8eab B \u8bed\u8a00\u3002\u5b83\u4eec\u7684\u4e3b\u8981\u7528\u9014\u662f\u7528\u4e8e\u7f16\u5199\u6c47\u7f16\u8bed\u8a00\uff0c\u56e0\u4e3a\u6c47\u7f16\u8bed\u8a00\u4e2d\u7684\u6307\u4ee4\u901a\u5e38\u662f\u591a\u5b57\u8282\u7684\u3002\u4f8b\u5982\uff0c'abcd' \u53ef\u4ee5\u7528\u4e8e\u8868\u793a\u4e00\u4e2a 32 \u4f4d\u7684\u6307\u4ee4\u3002

\u5728 C \u6807\u51c6\u4e2d\uff0c\u591a\u5b57\u7b26\u5e38\u91cf\u88ab\u5b9a\u4e49\u4e3a int \u7c7b\u578b\uff0c\u957f\u5ea6\u662f 4 \u4e2a\u5b57\u8282\u3002\u5728 C \u8bed\u8a00\u7684\u5b9e\u9645\u4f7f\u7528\u4e2d\uff0c\u591a\u5b57\u7b26\u5e38\u91cf\u901a\u5e38\u662f\u51fa\u4e8e\u8c03\u8bd5\u76ee\u7684\u800c\u5d4c\u5165\u7ed3\u6784\u4e2d\u7684\u9b54\u6570\uff08Magic Numbers\uff09\uff0c\u5c31\u50cf\u6709\u4e9b\u4eba\u4f1a\u4f7f\u7528 0xfeedbeef \u548c 0xdeadbeef \u800c\u4e0d\u662f NULL \u6765\u6807\u8bb0\u6307\u9488\u7684\u672a\u521d\u59cb\u5316\u548c\u5df2\u5220\u9664\u72b6\u6001\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u662f\uff0c\u5982\u679c\u7a0b\u5e8f\u51fa\u73b0\u4e86\u9519\u8bef\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u6253\u5370\u51fa\u8fd9\u4e9b\u9b54\u6570\u6765\u5b9a\u4f4d\u9519\u8bef\u7684\u4f4d\u7f6e\u3002

\u6211\u4eec\u4f7f\u7528\u65f6\u5e94\u5f53\u907f\u514d\u5c06\u591a\u5b57\u7b26\u5e38\u91cf\u4ece int \u7c7b\u578b\u8f6c\u6362\u4e3a char \u7c7b\u578b\uff0c\u56e0\u4e3a\u8fd9\u4e00\u8f6c\u6362\u8fc7\u7a0b\u662f\u7531\u7f16\u8bd1\u5668\u5b9e\u73b0\u51b3\u5b9a\u7684\u3002\u6bd4\u5982 char a = 'ABCD'\uff0c\u5728 gcc\u3001clang\u3001msvc \u4e0a\u5747\u4e3a a = 'D'\uff0c\u4f46\u662f\u5728 armcc \u4e0a\u4e3a a = 'A'\u3002

  • getchar() \u4e3a\u4ec0\u4e48\u8981\u8fd4\u56de int \u7c7b\u578b\uff1f

\u56e0\u4e3a\u5b83\u4f1a\u8fd4\u56de EOF\uff0c\u800c EOF \u5728\u6807\u51c6\u4e2d\u5b9a\u4e49\u4e3a int \u7c7b\u578b\uff0c\u901a\u5e38\u4e3a (int)-1\u3002

This macro is an integer value that is returned by a number of narrow stream functions to indicate an end-of-file condition, or some other error situation.

\u4e3a\u4ec0\u4e48\u8981\u8fd9\u4e48\u5b9a\u4e49\uff1f\u4ece\u903b\u8f91\u4e0a\u8bf4\uff0cEOF \u5e94\u5f53\u4e0e\u4efb\u4f55\u4e00\u4e2a\u5b57\u7b26\u503c\u90fd\u4e0d\u540c\u3002(char)-1 \u4e5f\u662f\u4e00\u4e2a\u5408\u6cd5\u7684\u5b57\u7b26\uff08\u56e0\u4e3a\u5b83\u662f char \u7c7b\u578b\uff0cchar \u7c7b\u578b\u7684\u6bcf\u4e2a\u503c\u90fd\u80fd\u8868\u793a\u5b57\u7b26\uff09\uff0c\u6240\u4ee5\u4e0d\u80fd\u7528\u4f5c EOF\uff0c\u5fc5\u987b\u4f7f\u7528 (int)-1\uff0c\u5b83\u4e0e\u524d\u8005\u5bbd\u5ea6\u4e0d\u540c\uff0c\u56e0\u6b64\u662f\u4e0d\u540c\u7684\u503c\u3002

\u8fd8\u8bb0\u5f97\u7684\u5728\u7c7b\u578b\u8f6c\u6362\u4e2d\u63d0\u5230\u7684\u6574\u5f62\u63d0\u5347\u5417\uff1f\u5982\u679c\u6211\u4eec\u8ba9 getchar() \u8fd4\u56de (char)-1\uff0c\u5f53\u51fd\u6570\u63a5\u6536\u5230 (char)-1 \u65f6\uff0c\u5b83\u4f1a\u6267\u884c\u4ece\u65e0\u7b26\u53f7\u6570\u5230\u6709\u7b26\u53f7\u6570\u7684\u8f6c\u6362\uff08\u5373\u4f7f\u5b9e\u73b0\u4e3a\u6709\u7b26\u53f7\u7684 char\uff09\uff0c\u4ece\u800c\u8fd4\u56de (int)255\uff0c\u8fd9\u4e0e EOF \u7684\u5b9a\u4e49\u4e0d\u7b26\u3002

\u6b64\u5916\uff0cchar\u3001signed char \u4e0e unsigned char \u76f4\u63a5\u4e24\u4e24\u4e0d\u540c\uff0c\u5c3d\u7ba1 char \u5177\u4f53\u5b9e\u73b0\u4e3a\u6709\u7b26\u53f7\u6570\u8fd8\u662f\u65e0\u7b26\u53f7\u6570\u7531\u5b9e\u73b0\u51b3\u5b9a\u3002

\u53c2\u8003\u8d44\u6599\uff1a

  • What is the purpose of multi character constants in C? - Quora
  • Character constant - cppreference.com
  • int c = getchar()? Why int? : C_Programming (reddit.com)
  • Implicit conversions - cppreference.com
"},{"location":"programming_lecture/lecture2/lecture2/#_4","title":"\u7ed3\u6784\u4e0e\u5176\u4ed6\u6570\u636e\u7c7b\u578b","text":""},{"location":"programming_lecture/lecture2/lecture2/#_5","title":"\u9605\u8bfb\u548c\u64b0\u5199\u7c7b\u578b\u58f0\u660e","text":"

Info

\u672c\u8282\u5185\u5bb9\u4e3b\u8981\u6765\u81ea\u300aC \u4e13\u5bb6\u7f16\u7a0b\u300b\u7b2c 3 \u7ae0\u201c\u5206\u6790 C \u8bed\u8a00\u7684\u58f0\u660e\u201d\u3002

\u5728\u5b9e\u9645\u5de5\u4f5c\u4e2d\u6700\u597d\u4f7f\u7528 typedef \u9010\u6b65\u5408\u6210\u58f0\u660e\u3002

One good way to synthesize declarations is in small steps with typedef. K&R C, 5.12.

\u300aC \u4e13\u5bb6\u7f16\u7a0b\u300b\u548c\u300aC \u9677\u9631\u4e0e\u7f3a\u9677\u300b\u90fd\u63d0\u51fa\u7528\u4e0b\u9762\u8fd9\u79cd\u65b9\u6cd5\u7406\u89e3\u590d\u6742\u7684\u7c7b\u578b\u58f0\u660e\uff0c\u5b83\u4eec\u672c\u8d28\u662f\u4e00\u6837\u7684\uff0c\u5206\u522b\u8868\u8ff0\u4e3a\uff1a

  • \u58f0\u660e\u7684\u5f62\u5f0f\u4e0e\u4f7f\u7528\u7684\u5f62\u5f0f\u76f8\u4f3c\u3002
  • \u58f0\u660e\u662f\u7c7b\u578b+\u8868\u8fbe\u5f0f\uff0c\u5bf9\u8be5\u8868\u8fbe\u5f0f\u6c42\u503c\u5c06\u5f97\u5230\u8be5\u7c7b\u578b\u3002
\u7b80\u5355\u7684\u4f8b\u5b50\u590d\u6742\u7684\u4f8b\u5b50

\u770b\u770b\u8fd9\u4e2a\u58f0\u660e\uff1aint *p

  • p \u662f\u4e00\u4e2a\u6307\u9488\u3002\u6211\u4eec\u58f0\u660e\u5b83\u7684\u5f62\u5f0f\u4e0e\u4f7f\u7528\u5b83\u7684\u5f62\u5f0f *p \uff08\u89e3\u5f15\u7528 p\uff09\u7c7b\u4f3c\u3002
  • p \u662f\u4e00\u4e2a\u6307\u9488\uff0c\u5bf9\u5b83\u6c42\u503c\u5f97\u5230\u4e00\u4e2a int \u7c7b\u578b\u7684\u503c\u3002

\u518d\u770b\u770b\u8fd9\u4e2a\u58f0\u660e\uff1achar (*(*x[3])())[5]

  • x \u662f\u4e00\u4e2a\u6570\u7ec4\u3002\u6211\u4eec\u58f0\u660e\u5b83\u7684\u5f62\u5f0f\u4e0e\u4f7f\u7528\u5b83\u7684\u5f62\u5f0f x[3] \u7c7b\u4f3c\u3002
  • \u628a (*(*x[3])())[5] \u770b\u4f5c\u4e00\u4e2a\u8868\u8fbe\u5f0f\uff0c\u4ece\u5185\u5411\u5916\u6309\u7167\u8fd0\u7b97\u7b26\u548c\u7ed3\u5408\u5f8b\u5bf9\u5176\u6c42\u503c\uff0c\u6700\u7ec8\u4f1a\u5f97\u5230\u4e00\u4e2a char \u7c7b\u578b\u3002\u6c42\u503c\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6211\u4eec\u4f9d\u6b21\u5f97\u5230\u4e86\u6570\u7ec4\u3001\u51fd\u6570\u6307\u9488\u3001\u6570\u7ec4\u6307\u9488\uff0c\u6700\u540e\u5f97\u5230\u4e86 char \u7c7b\u578b\u3002
K&R \u5bf9 C \u8bed\u8a00\u7c7b\u578b\u58f0\u660e\u7684\u89e3\u8bfb

Todo

\u5bf9\u4e8e\u58f0\u660e\u6765\u8bf4\uff0c\u4e0a\u9762\u7684\u65b9\u6cd5\u5df2\u7ecf\u8db3\u591f\u4e86\uff0c\u56e0\u4e3a\u603b\u662f\u5bb9\u6613\u627e\u5230\u53d8\u91cf\u7684\u540d\u5b57\u5728\u54ea\u91cc\u3002\u4f46\u662f\u5bf9\u4e8e\u5f62\u5f0f\u53c2\u6570\u3001typedef\u3001sizeof \u548c\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u7b26\u7b49\u60c5\u51b5\u6765\u8bf4\uff0c\u627e\u4e0d\u5230\u53d8\u91cf\u7684\u540d\u5b57\uff0c\u4e0a\u9762\u7684\u65b9\u6cd5\u5c31\u4e0d\u591f\u4e86\u3002\u8fd9\u65f6\u6709\u4e00\u4e2a\u66f4\u597d\u7684\u529e\u6cd5\uff1a\u4ece\u6700\u5185\u5c42\u62ec\u53f7\u5f00\u59cb\u8bfb\u3002

\u770b\u770b\u8fd9\u4e2a\u8868\u8fbe\u5f0f\uff1a

(*(void(*)())0)();\n
  • \u4ece\u6700\u5185\u5c42\u62ec\u53f7\u5f00\u59cb\u8bfb\uff1avoid(*)() \u663e\u7136\u662f\u4e00\u4e2a\u51fd\u6570\u6307\u9488\uff0c\u6307\u5411\u7684\u51fd\u6570\u7684\u8fd4\u56de\u7c7b\u578b\u662f void\uff0c\u53c2\u6570\u5217\u8868\u4e3a\u7a7a\u3002
  • \u4e00\u5c42\u62ec\u53f7\u628a void(*)() \u5305\u8d77\u6765\uff0c\u8fd9\u662f\u5f3a\u5236\u7c7b\u578b\u8f6c\u6362\u7684\u7528\u6cd5\uff0c\u628a 0 \u8f6c\u6362\u4e3a void(*)() \u7c7b\u578b\u7684\u6307\u9488\u3002
  • \u6700\u540e\u5c31\u5269\u4e0b (*fp)() \u5f62\u5f0f\u7684\u51fd\u6570\u8c03\u7528\u4e86\u3002

\u7efc\u4e0a\u6240\u8ff0\uff0c\u8fd9\u4e2a\u8868\u8fbe\u5f0f\u7684\u76ee\u7684\u662f\u8c03\u7528\u9996\u5730\u5740\u4e3a 0 \u7684\u51fd\u6570\u3002\u5b9e\u9645\u5de5\u4f5c\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u5206\u89e3\u8fd9\u4e2a\u51fd\u6570\u58f0\u660e\uff1a

typedef void (*funcptr)();\n(*(funcptr)0)();\n

C \u8bed\u8a00\u8003\u8bd5\u4e2d\u8fd8\u4f1a\u8981\u6c42\u4f60\u9605\u8bfb\u4ee3\u7801\u7247\u6bb5\uff0c\u4e3a\u5f62\u53c2\u7b49\u4f4d\u7f6e\u586b\u5199\u7c7b\u578b\u58f0\u660e\u3002\u8bf7\u53c2\u8003\u5386\u5e74\u5377\u603b\u7ed3\u4e2d\u7684\u4f8b\u9898\u3002

\u5206\u5272\u7ebf\u4e0b\u65b9\u7684\u5185\u5bb9\u8fd8\u672a\u6574\u7406

"},{"location":"programming_lecture/lecture2/lecture2/#_6","title":"\u5185\u5b58\u7ba1\u7406","text":"

C \u7684\u5185\u5b58\u7ba1\u7406\u662f\u4e00\u5927\u75db\u70b9\uff0c\u56e0\u4e3a\u5b83\u672c\u8eab\u5e76\u4e0d\u63d0\u4f9b\u68c0\u67e5\u673a\u5236\uff0c\u4e00\u5207\u90fd\u4f9d\u8d56\u4e8e\u7a0b\u5e8f\u5458\u81ea\u5df1\u3002\u56e0\u6b64\uff0c\u597d\u597d\u638c\u63e1\u5185\u5b58\u7ba1\u7406\u5bf9\u4e8e\u5199\u51fa\u5b89\u5168\u3001\u7a33\u5b9a\u7684\u7a0b\u5e8f\u662f\u975e\u5e38\u5fc5\u8981\u7684\u3002

"},{"location":"programming_lecture/lecture2/lecture2/#_7","title":"\u5bf9\u8c61\u548c\u6807\u8bc6\u7b26","text":"

\u8ba9\u6211\u4eec\u6765\u4e86\u89e3\u51e0\u4e2a\u6982\u5ff5\uff1a\u5bf9\u8c61\u3001\u6807\u8bc6\u7b26

  • \u6bcf\u4e2a\u88ab\u5b58\u50a8\u7684\u503c\u90fd\u5360\u7528\u4e00\u5b9a\u7684\u7269\u7406\u5185\u5b58\uff0c\u8fd9\u6837\u7684\u4e00\u5757\u5185\u5b58\u79f0\u4e3a\u5bf9\u8c61\u3002\u5bf9\u8c61\u53ef\u4ee5\u50a8\u5b58\u4e00\u4e2a\u6216\u591a\u4e2a\u503c\u3002

\u5bf9\u8c61\u7684\u5176\u4ed6\u542b\u4e49

\u201c\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u201d\u4e2d\u7684\u5bf9\u8c61\u6307\u7684\u662f\u201c\u7c7b\u5bf9\u8c61\u201d\u3002

  • \u58f0\u660e\u53d8\u91cf\u521b\u5efa\u4e86\u4e00\u4e2a\u6807\u8bc6\u7b26\uff0c\u6807\u8bc6\u7b26\u7528\u4e8e\u6307\u5b9a\u786c\u4ef6\u5185\u5b58\u4e2d\u7684\u5bf9\u8c61\u3002
  • \u6307\u9488\u4e0e\u6807\u8bc6\u7b26\u4e0d\u540c\uff0c\u5b83\u662f\u53e6\u4e00\u79cd\u6307\u5b9a\u5bf9\u8c61\u7684\u9014\u5f84\u3002

\u5de6\u503c

\u6307\u5b9a\u5bf9\u8c61\u7684\u8868\u8fbe\u5f0f\u88ab\u79f0\u4e3a\u5de6\u503c\u3002

  • entity \u6807\u8bc6\u7b26\uff0c\u662f\u5de6\u503c
  • *pt \u662f\u8868\u8fbe\u5f0f\uff0c\u4e5f\u662f\u5de6\u503c
  • 2 * entity \u4e0d\u662f\u6807\u8bc6\u7b26\uff0c\u4e5f\u4e0d\u662f\u5de6\u503c
  • *(pt + 2) \u662f\u8868\u8fbe\u5f0f\uff0c\u4e5f\u662f\u5de6\u503c

\u5982\u679c\u53ef\u4ee5\u4f7f\u7528\u5de6\u503c\u6539\u53d8\u5bf9\u8c61\u4e2d\u7684\u503c\uff0c\u90a3\u4e48\u79f0\u4e3a\u53ef\u4fee\u6539\u7684\u5de6\u503c\u3002

const char * pc = \"xxxx\";\n
  • pc \u662f\u53ef\u4fee\u6539\u7684\u5de6\u503c
  • *pc \u662f\u4e0d\u53ef\u4fee\u6539\u7684\u5de6\u503c
"},{"location":"programming_lecture/lecture2/lecture2/#_8","title":"\u5b58\u50a8\u671f\u3001\u4f5c\u7528\u57df\u548c\u94fe\u63a5","text":"

Note

\u5b58\u50a8\u671f\u63cf\u8ff0\u5bf9\u8c61\uff0c\u8868\u660e\u5728\u5185\u5b58\u4e2d\u5b58\u50a8\u7684\u65f6\u95f4\u3002

\u4f5c\u7528\u57df\u548c\u94fe\u63a5\u63cf\u8ff0\u6807\u8bc6\u7b26\uff0c\u8868\u660e\u7a0b\u5e8f\u7684\u54ea\u4e9b\u90e8\u5206\u53ef\u4ee5\u4f7f\u7528\u5b83\u3002

"},{"location":"programming_lecture/lecture2/lecture2/#_9","title":"\u4f5c\u7528\u57df","text":"

C \u4e2d\u7684\u53d8\u91cf\u4f5c\u7528\u57df\u6709\u4ee5\u4e0b\u51e0\u79cd\u7c7b\u578b\uff1a

  • \u5757\u4f5c\u7528\u57df

\u5927\u591a\u6570\u53d8\u91cf\u3002\u4ece\u5b9a\u4e49\u5904\u5230\u5757\u672b\u5c3e\u3002

\u51fd\u6570\u5f62\u53c2\uff08\u5373\u4f7f\u5b83\u5728\u82b1\u62ec\u53f7\u5916\u90e8\uff09\u3002

Note

\u5728 C99 \u4e4b\u524d\uff0c\u5757\u4f5c\u7528\u57df\u7684\u53d8\u91cf\u5fc5\u987b\u5728\u5757\u7684\u5f00\u5934\u58f0\u660e\u3002

\u4e5f\u662f\u5728 C99\uff0c\u5757\u7684\u6982\u5ff5\u88ab\u653e\u5bbd\uff1a\u63a7\u5236\u8bed\u53e5\uff08\u6761\u4ef6\u3001\u5faa\u73af\uff09\u4e5f\u662f\u5757\uff08\u5373\u4f7f\u6ca1\u6709\u4f7f\u7528\u82b1\u62ec\u53f7\uff09\u3002\u6bd4\u5982\uff1a

for(int i = 0;;)\n    function();\n

i \u5177\u6709\u5757\u4f5c\u7528\u57df\uff0c\u662f\u5faa\u73af\u7684\u4e00\u90e8\u5206\u3002

\u66f4\u7cbe\u7ec6\u7684\u5b9a\u4e49\uff1a\u5faa\u73af\u4f53\u662f\u6574\u4e2a\u5faa\u73af\u7684\u5b50\u5757\u3002\u4f60\u53ef\u4ee5\u8fd9\u6837\u60f3\u5b83\uff1a

{\n    for(int i;;)\n    {\n        int i;\n    }\n}\n

\u4e0a\u9762\u7684\u4e24\u4e2a\u540c\u540d\u53d8\u91cf i \u4e0d\u5728\u540c\u4e00\u4e2a\u5757\u4e2d\uff0c\u56e0\u6b64\u4e0d\u662f\u91cd\u590d\u5b9a\u4e49\u3002

Tip

\u540c\u540d\u7684\u53d8\u91cf\uff0c\u5185\u90e8\u8986\u76d6\u5916\u90e8\u3002

  • \u51fd\u6570\u4f5c\u7528\u57df

goto \u8bed\u53e5\u7684\u6807\u7b7e\u3002\u8fd9\u610f\u5473\u7740\uff0c\u5373\u4f7f\u6807\u7b7e\u5728\u5185\u5c42\u7684\u5757\u4e2d\uff0c\u5b83\u7684\u4f5c\u7528\u57df\u4e5f\u5ef6\u4f38\u81f3\u6574\u4e2a\u51fd\u6570\u3002

  • \u51fd\u6570\u539f\u578b\u4f5c\u7528\u57df

\u51fd\u6570\u539f\u578b\u4e2d\u7684\u53d8\u91cf\u540d\u3002\u4ece\u5b9a\u4e49\u5904\u5230\u51fd\u6570\u539f\u578b\u7ed3\u675f\u3002

\u53ea\u5728\u4f60\u4f7f\u7528 VLA \u65f6\u9700\u8981\u6ce8\u610f\u8fd9\u4e00\u987a\u5e8f\uff1a

void use_VLA(int n, int m, ar[n][m]);\n
  • \u6587\u4ef6\u4f5c\u7528\u57df

\u5728\u4efb\u4f55\u51fd\u6570\u5916\u5b9a\u4e49\u7684\u53d8\u91cf\u3002\u4ece\u5b9a\u4e49\u5904\u5230\u6587\u4ef6\u672b\u5c3e\u3002

\u8fd9\u6837\u7684\u53d8\u91cf\u79f0\u4e3a\u5168\u5c40\u53d8\u91cf\u3002

\u7ffb\u8bd1\u5355\u5143

\u4f60\u6240\u8ba4\u4e3a\u7684\u591a\u4e2a\u6587\u4ef6\u5bf9\u4e8e\u7f16\u8bd1\u5668\u6765\u8bf4\u53ef\u80fd\u662f\u4e00\u4e2a\u6587\u4ef6\u3002\u6bd4\u5982\u5934\u6587\u4ef6\uff1a\u9884\u5904\u7406\u65f6\uff0c\u5934\u6587\u4ef6\u88ab\u63d2\u5165\u3002\u5bf9\u4e8e\u7f16\u8bd1\u5668\u6765\u8bf4\uff0c\u5b83\u770b\u5230\u7684\u662f\u5355\u4e2a\u6587\u4ef6\u3002

\u8fd9\u6837\u7684\u5355\u4e2a\u6587\u4ef6\u79f0\u4e3a\u4e00\u4e2a\u7ffb\u8bd1\u5355\u5143\u3002\u6bcf\u4e2a\u7ffb\u8bd1\u5355\u5143\u5bf9\u5e94\u4e00\u4e2a\u6e90\u6587\u4ef6\u548c\u5b83 include \u7684\u6587\u4ef6\u3002

\u521a\u624d\u6211\u4eec\u8bf4\u7684\u6587\u4ef6\u4f5c\u7528\u57df\u5176\u5b9e\u662f\u5728\u6574\u4e2a\u7ffb\u8bd1\u5355\u5143\u53ef\u89c1\u3002

"},{"location":"programming_lecture/lecture2/lecture2/#_10","title":"\u94fe\u63a5","text":"
  • \u5916\u90e8\u94fe\u63a5

\u53ef\u4ee5\u5728\u591a\u6587\u4ef6\u7a0b\u5e8f\u4e2d\u7684\u4efb\u4f55\u5730\u65b9\u4f7f\u7528\u3002

  • \u5185\u90e8\u94fe\u63a5

\u53ea\u80fd\u5728\u4e00\u4e2a\u7ffb\u8bd1\u5355\u5143\u4e2d\u4f7f\u7528\u3002\u7531 static \u5173\u952e\u5b57\u8bf4\u660e\u3002

\u7528\u8bed

\u7a0b\u5e8f\u5458\u4eec\u901a\u5e38\u7528\u5168\u5c40\u4f5c\u7528\u57df\u6216\u7a0b\u5e8f\u4f5c\u7528\u57df\u6307\u4ee3\u5916\u90e8\u94fe\u63a5\uff0c\u7528\u6587\u4ef6\u4f5c\u7528\u57df\u6307\u4ee3\u5185\u90e8\u94fe\u63a5\u3002

  • \u65e0\u94fe\u63a5

\u5757\u4f5c\u7528\u57df\u3001\u51fd\u6570\u4f5c\u7528\u57df\u3001\u51fd\u6570\u539f\u578b\u4f5c\u7528\u57df\u3002

"},{"location":"programming_lecture/lecture2/lecture2/#_11","title":"\u5b58\u50a8\u671f","text":"
  • \u9759\u6001\u5b58\u50a8\u671f

\u6574\u4e2a\u7a0b\u5e8f\u6267\u884c\u671f\u95f4\u3002\u6587\u4ef6\u4f5c\u7528\u57df\u7684\u53d8\u91cf\u3002

\u5757\u4f5c\u7528\u57df\u7684\u53d8\u91cf\u4e5f\u80fd\u5177\u6709\u9759\u6001\u5b58\u50a8\u671f\uff0c\u4f7f\u7528 static \u9650\u5b9a\u7b26\u58f0\u660e\u5373\u53ef\u3002

  • \u7ebf\u7a0b\u5b58\u50a8\u671f

\u4ece\u58f0\u660e\u5904\u5230\u7ebf\u7a0b\u7ed3\u675f\u3002\u5bf9\u6587\u4ef6\u4f5c\u7528\u57df\u7684\u58f0\u660e\u4f7f\u7528 _Thread_local \u9650\u5b9a\u7b26\u8bf4\u660e\u3002\u6bcf\u4e2a\u7ebf\u7a0b\u6709\u8fd9\u4e2a\u53d8\u91cf\u7684\u79c1\u6709\u62f7\u8d1d\u3002

  • \u81ea\u52a8\u5b58\u50a8\u671f

\u7a0b\u5e8f\u8fdb\u5165\u5757\u65f6\u5206\u914d\uff0c\u79bb\u5f00\u5757\u65f6\u91ca\u653e\u3002\u5757\u4f5c\u7528\u57df\u7684\u53d8\u91cf\u3002

VLA \u662f\u4e00\u4e2a\u4f8b\u5916\uff0c\u5b83\u4ece\u5b9a\u4e49\u5904\u5230\u5757\u672b\u5c3e\u5b58\u5728\u3002\uff08\u6bd5\u7adf\u5230\u5b9a\u4e49\u5904\u624d\u80fd\u77e5\u9053\u5176\u5927\u5c0f\uff09\u3002

  • \u52a8\u6001\u5206\u914d\u5b58\u50a8\u671f
"},{"location":"programming_lecture/lecture2/lecture2/#_12","title":"\u603b\u7ed3","text":"

\u4e0d\u8003\u8651\u5e76\u53d1\u7f16\u7a0b\uff0cC \u8bed\u8a00\u6709\u4e94\u79cd\u5b58\u50a8\u7c7b\u578b\u3002\u8bf7\u63cf\u8ff0\u5b83\u4eec\u7684\u5b58\u50a8\u671f\u3001\u4f5c\u7528\u57df\u3001\u94fe\u63a5\u548c\u5b9a\u4e49\u65b9\u5f0f\u3002

  • \u81ea\u52a8
  • \u5bc4\u5b58\u5668

\u5bc4\u5b58\u5668\u53d8\u91cf\u5b58\u653e\u5728\u53ef\u7528\u7684\u6700\u5feb\u7684\u5185\u5b58\u4e2d\u3002\u7531\u4e8e\u5b83\u53ef\u80fd\u5b58\u653e\u5728\u5bc4\u5b58\u5668\u4e2d\uff0c\u56e0\u6b64\u4e0d\u80fd\u53d6\u5f97\u5b83\u7684\u5730\u5740\u3002\u5176\u4ed6\u65b9\u9762\u4e0e\u81ea\u52a8\u53d8\u91cf\u76f8\u540c\u3002

\u80fd\u591f\u88ab\u58f0\u660e\u4e3a\u5bc4\u5b58\u5668\u7c7b\u578b\u7684\u53d8\u91cf\u7c7b\u578b\u53ef\u80fd\u53d7\u5230\u9650\u5236\u3002\u6bd4\u5982\u5728\u67d0\u4e9b\u5904\u7406\u5668\u4e2d\uff0c\u6bd4 double \u957f\u7684\u7c7b\u578b\u4e0d\u80fd\u58f0\u660e\u4e3a\u5bc4\u5b58\u5668\u53d8\u91cf\u3002

  • \u9759\u6001\u5916\u90e8\u94fe\u63a5

extern \u58f0\u660e\u5e38\u5e38\u662f\u4e0d\u5fc5\u8981\u7684\uff0c\u53ea\u662f\u80fd\u591f\u66f4\u597d\u5730\u8bf4\u660e\u4f7f\u7528\u4e86\u5176\u4ed6\u5730\u65b9\u7684\u53d8\u91cf\u3002

\u4f46\u662f\u5982\u679c\u5728\u5757\u4e2d\uff0c\u518d\u6b21\u58f0\u660e\u4e00\u4e2a\u540c\u540d\u7684\u53d8\u91cf\uff0c\u5219\u4f1a\u8986\u76d6\u9759\u6001\u5916\u90e8\u94fe\u63a5\u7684\u53d8\u91cf\u3002\u5982\u679c\u51fa\u73b0\u8fd9\u79cd\u91cd\u540d\u7684\u60c5\u51b5\uff0c\u5efa\u8bae\u4f7f\u7528 auto \u6ce8\u660e\u3002

  • \u9759\u6001\u5185\u90e8\u94fe\u63a5
  • \u9759\u6001\u65e0\u94fe\u63a5

\u4ec5\u5728\u521d\u59cb\u5316\u65f6\u7f16\u8bd1\u4e00\u6b21\uff0c\u82e5\u672a\u6307\u5b9a\u503c\uff0c\u5219\u4e3a 0\u3002\u5982\u679c\u4f60\u7528\u8c03\u8bd5\u5668\u8c03\u8bd5\uff0c\u5e38\u5e38\u4f1a\u53d1\u73b0\u597d\u50cf\u201c\u8df3\u8fc7\u201d\u4e86\u8fd9\u4e00\u6b65\u3002

Note"},{"location":"programming_lecture/lecture2/lecture2/#-auto-c","title":"- \u53ef\u4ee5\u4f7f\u7528 auto \u663e\u5f0f\u8bf4\u660e\u81ea\u52a8\u5b58\u50a8\u671f\u3002\u4f46\u5728 C++ \u4e2d\u5b83\u6709\u4e0d\u540c\u542b\u4e49\uff0c\u56e0\u6b64\u4e0d\u8981\u4f7f\u7528\u8be5\u9650\u5b9a\u7b26\u3002","text":""},{"location":"programming_lecture/lecture3/lecture3/","title":"I/O \u4e0e\u6587\u4ef6","text":"

\u65bd\u5de5\u4e2d

\u672c\u9875\u9762\u6b63\u5728\u7f16\u8f91\u4e2d\u3002

\u5185\u5bb9\u63d0\u8981

  • C \u7684\u8f93\u5165\u8f93\u51fa\u6a21\u578b\uff1a\u7f13\u51b2\u4e0e\u6d41\u7684\u6982\u5ff5
  • C \u6807\u51c6 I/O \u51fd\u6570
  • \u6587\u4ef6\u7f16\u7801
"},{"location":"programming_lecture/lecture3/lecture3/#c","title":"C \u7684\u8f93\u5165\u8f93\u51fa\u6a21\u578b","text":""},{"location":"programming_lecture/lecture3/lecture3/#_1","title":"\u7f13\u51b2","text":"

\u7f13\u51b2\u8f93\u5165

\u7528\u6237\u8f93\u5165\u7684\u5b57\u7b26\u88ab\u6536\u96c6\u5e76\u50a8\u5b58\u5728\u7f13\u51b2\u533a\uff08buffer\uff09\u4e2d\uff0c\u6309\u4e0b Enter \u952e\u540e\u7a0b\u5e8f\u624d\u80fd\u4f7f\u7528\u7528\u6237\u8f93\u5165\u7684\u5b57\u7b26\u3002

  • \u5b8c\u5168\u7f13\u51b2\uff1a\u4ec5\u7f13\u51b2\u533a\u586b\u6ee1\u65f6\u624d\u53d1\u9001\u5185\u5bb9\u3001\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u901a\u5e38\u7528\u4e8e\u6587\u4ef6\u8f93\u5165\u3002
  • \u884c\u7f13\u51b2\uff1a\u51fa\u73b0\u6362\u884c\u7b26\u65f6\u5237\u65b0\u7f13\u51b2\u533a\uff0c\u901a\u5e38\u7528\u4e8e\u952e\u76d8\u8f93\u5165\u3002

\u4e0e\u4e4b\u5bf9\u5e94\u5730\uff0c\u65e0\u7f13\u51b2\u8f93\u5165\u7684\u7a0b\u5e8f\u80fd\u591f\u7acb\u5373\u4f7f\u7528\u7528\u6237\u8f93\u5165\u7684\u5185\u5bb9\u3002

C \u6807\u51c6\u89c4\u5b9a\uff1a\u8f93\u5165\u662f\u7f13\u51b2\u7684\u3002

\u6211\u53ef\u4ee5\u66f4\u6539\u8f93\u5165\u65b9\u5f0f\u5417\uff1f

UNIX \u5e93\u4e2d\u6709 ioctl() \u51fd\u6570\u7528\u4e8e\u6307\u5b9a\u5f85\u8f93\u5165\u7684\u7c7b\u578b\uff0c\u4f46\u8fd9\u4e0d\u5c5e\u4e8e C \u6807\u51c6\u3002

ANSI C \u4e2d\uff0c\u53ef\u4ee5\u4f7f\u7528 setbuf() \u548c setvbuf() \u63a7\u5236\u7f13\u51b2\uff0c\u4f46\u53d7\u9650\u4e8e\u7cfb\u7edf\u7684\u8bbe\u7f6e\u3002

"},{"location":"programming_lecture/lecture3/lecture3/#_2","title":"\u6d41","text":"

C \u5e93\u63d0\u4f9b\u7684\u8f93\u5165\u8f93\u51fa\u65b9\u5f0f\u79f0\u4e3a\u6807\u51c6 I/O\uff0c\u5b83\u4eec\u662f\u5efa\u7acb\u5728\u64cd\u4f5c\u7cfb\u7edf\u63d0\u4f9b\u7684\u5e95\u5c42 I/O \u4e0a\u7684\u3002\u5e95\u5c42 I/O \u4e4b\u95f4\u5e38\u5e38\u4f1a\u6709\u4e00\u4e9b\u5dee\u5f02\uff1a

\u5404\u4e2a\u7cfb\u7edf\u7684\u6587\u4ef6\u5dee\u5f02

\u5dee\u5f02 UNIX Windows MacOS \u6362\u884c\u7b26 \\n LF \\r\\n CRLF \\n (\u8f83\u65e9\u7684 MacOS \u4f7f\u7528 \\r)LF \u6587\u4ef6\u7ed3\u675f\u7b26 ^D ^Z ^D

\u6ce8\uff1a\u5982 ^Z \u4ee3\u8868 Ctrl+Z\uff0c\u4f60\u53ef\u4ee5\u4f7f\u7528\u8be5\u7ec4\u5408\u952e\u7ed3\u675f\u952e\u76d8\u8f93\u5165\u3002

\u6587\u4ef6\u7ed3\u5c3e\u4e5f\u4e0d\u4e00\u5b9a\u7531\u6587\u4ef6\u7ed3\u675f\u7b26\u6807\u8bb0\u3002\u4e8b\u5b9e\u4e0a\uff0cUNIX \u7cfb\u7edf\u50a8\u5b58\u6587\u4ef6\u5927\u5c0f\u4fe1\u606f\uff0c\u4f9d\u636e\u6587\u4ef6\u5927\u5c0f\u4fe1\u606f\u51b3\u5b9a\u6587\u4ef6\u672b\u5c3e\u3002

\u4ece\u6982\u5ff5\u4e0a\u770b\uff0cC \u5904\u7406\u7684\u662f\u6d41\u800c\u4e0d\u662f\u6587\u4ef6\u3002\u4e0d\u540c\u5c5e\u6027\u548c\u4e0d\u540c\u79cd\u7c7b\u7684\u8f93\u5165\uff0c\u7531\u5c5e\u6027\u66f4\u7edf\u4e00\u7684\u6d41\u6765\u8868\u793a\u3002

\u6d41

\u6d41\u5c31\u662f\u4e00\u7cfb\u5217\u8fde\u7eed\u7684\u5b57\u8282\u3002

\u6253\u5f00\u6587\u4ef6\u7684\u8fc7\u7a0b\u5c31\u662f\u628a\u6d41\u4e0e\u6587\u4ef6\u76f8\u5173\u8054\uff0c\u8bfb\u5199\u90fd\u901a\u8fc7\u6d41\u6765\u5b8c\u6210\u3002

getchar() \u548c scanf() \u7b49\u51fd\u6570\u8bfb\u53d6\u5230\u6587\u4ef6\u7ed3\u5c3e\u65f6\u4f1a\u8fd4\u56de\u4e00\u4e2a\u7279\u6b8a\u7684\u503c EOF\uff0c\u5728 stdio.h \u4e2d\u5b9a\u4e49\u4e86\uff1a

#define EOF (-1)\n

\u4f60\u80fd\u89e3\u91ca\u4e3a\u4ec0\u4e48\u8981\u628a\u5b83\u5b9a\u4e3a -1 \u5417\uff1f

"},{"location":"programming_lecture/lecture3/lecture3/#_3","title":"\u5b57\u7b26\u8f93\u5165\u8f93\u51fa","text":"

\u51fd\u6570\u548c\u5b83\u4eec\u7684\u529f\u80fd

\u529f\u80fd \u51fd\u6570 \u5931\u8d25\u8fd4\u56de\u503c int getchar(void) int getc(FILE *stream) int fgetc(FILE *stream) \u5355\u5b57\u7b26\u8f93\u5165 EOF char *fgets(char *s, int size, FILE *stream) \u5b57\u7b26\u4e32\u8f93\u5165 NULL int ungetc(int c, FILE *stream) \u653e\u56de\u7f13\u51b2\u8f93\u5165 EOF

\u6ce8\u610f\uff1a\u4ee5\u4e0a\u51fd\u6570\u90fd\u5c06\u5b57\u7b26\u4ece\u7f13\u51b2\u533a\u4e2d\u7684 unsigned char \u7c7b\u578b\u8f6c\u6362\u4e3a int \u7c7b\u578b\u3002

\u90a3\u4e48\u8fd9\u662f\u5426\u4f1a\u9020\u6210 EOF \u4e0d\u80fd\u88ab\u8bc6\u522b\uff0c\u800c\u662f\u88ab\u770b\u4f5c\u5b57\u7b26\u5462\uff1f

\u5173\u4e8e getchar() \u51fd\u6570

\u5b83\u7684\u8fd4\u56de\u503c\u662f int \u7c7b\u578b\u800c\u975e char \u7c7b\u578b\uff0c\u503c\u5f97\u6ce8\u610f\u3002

"},{"location":"programming_lecture/lecture3/lecture3/#_4","title":"\u6362\u884c\u7b26\u95ee\u9898","text":"

\u8fd9\u662f\u4e00\u4e2a\u5178\u578b\u7684\u95ee\u9898\uff1ascanf() \u51fd\u6570\uff0c\u9664\u4e86 %c \u4ee5\u5916\u7684\u8f6c\u6362\u8bf4\u660e\uff0c\u90fd\u4e0d\u4f1a\u8bfb\u53d6\u7a7a\u767d\u5b57\u7b26\uff08\u7a7a\u683c\u3001\u5236\u8868\u7b26\u548c\u56de\u8f66\uff09\u3002

\u5199\u4e00\u4e2a\u5b89\u5168\u7684\u8f93\u5165\u51fd\u6570

char * s_gets(char* st, int n)\n{\n    char * ret_val;\n    int i = 0;\n\n    ret_val = fgets(st, n, stdin);\n    if (ret_val)\n    {\n        while (st[i] != '\\n' && st[i] != '\\0)\n            i++;\n        if (st[i] == '\\n')\n            st[i] = '\\0';\n        else //must have words[i] == '\\0'\n            while (getchar() != '\\n')\n                continue;\n    }\n    return ret_val;\n}\n

\u8fd9\u4e2a\u51fd\u6570\u6765\u81ea\u300aC Primer Plus\u300b\uff0c\u4e5f\u662f\u4e66\u4e2d 13 \u7ae0\u4ee5\u540e\u4e00\u76f4\u4f7f\u7528\u7684\u8f93\u5165\u51fd\u6570\u3002\u8fd9\u4e2a\u51fd\u6570\u793a\u8303\u4e86\u5982\u4f55\u4f7f\u7528\u5b89\u5168\u7684 fgets() \u51fd\u6570\uff0c\u5e76\u5c06\u8f93\u5165\u7edf\u4e00\uff0c\u5e76\u5904\u7406\u5269\u4f59\u7684\u5b57\u7b26\u3002

\u5728\u6d89\u53ca\u884c\u7684\u8f93\u5165\u65f6\uff0c\u4e00\u5b9a\u8981\u6ce8\u610f\u7edf\u4e00\u884c\u7ed3\u5c3e\u7684\u5f62\u5f0f\u3002\u8fd9\u5bf9\u4e8e\u6362\u884c\u7b26\uff0c\u7279\u522b\u662f\u6587\u4ef6\u7ed3\u5c3e\u5904\u859b\u5b9a\u8c14\u7684\u6362\u884c\u7b26\uff0c\u6709\u5f88\u5927\u4f5c\u7528\u3002

"},{"location":"programming_lecture/lecture3/lecture3/#_5","title":"\u68c0\u67e5\u8f93\u5165","text":"

\u53ef\u4ee5\u7528\u4e8e\u68c0\u67e5\u8f93\u5165\u7684\u65b9\u5f0f\u6709\u4ee5\u4e0b\u51e0\u79cd\uff1a

  1. scanf() \u7684\u8fd4\u56de\u503c\u3002
"},{"location":"programming_lecture/lecture3/lecture3/#_6","title":"\u6587\u4ef6\u8f93\u5165\u8f93\u51fa","text":""},{"location":"programming_lecture/lecture3/lecture3/#_7","title":"\u6807\u51c6\u5e93","text":""},{"location":"programming_lecture/lecture3/lecture3/#c-standard-library","title":"C standard library","text":""},{"location":"programming_lecture/lecture3/lecture3/#history-of-io-model","title":"History of I/O model","text":"
  • Before the UNIX system,

  • UNIX system designed I/O method isolated about devices. It treats all text stream using standard internal format.

"},{"location":"programming_lecture/lecture3/lecture3/#-ioctl-is-used-to-edit-text-stream-for-output","title":"- ioctl is used to edit text stream for output.","text":""},{"location":"programming_lecture/lecture3/lecture3/#_8","title":"\u5b57\u7b26\u4e32\u7684\u827a\u672f","text":""},{"location":"programming_lecture/lecture3/lecture3/#_9","title":"\u6587\u4ef6","text":"

\u672c\u8282\u7ed3\u5408 <stdio.h> \u5e93\u548c C \u6807\u51c6\u5185\u5bb9\u3002

"},{"location":"programming_lecture/lecture3/lecture3/#_10","title":"\u57fa\u7840\u6982\u5ff5","text":"

C \u628a\u6587\u4ef6\u770b\u4f5c\u8fde\u7eed\u7684\u5b57\u8282\uff0c\u6bcf\u4e2a\u5b57\u8282\u90fd\u80fd\u88ab\u5355\u72ec\u8bfb\u53d6\u3002C \u63d0\u4f9b\u4e24\u79cd\u6587\u4ef6\u6a21\u5f0f\uff0c\u5df2\u7ecf\u5728\u5f00\u5934\u4ecb\u7ecd\u3002

"},{"location":"programming_lecture/lecture3/lecture3/#_11","title":"\u7c7b\u578b\u548c\u5b8f","text":"

\u5728 <stdio.h> \u4e2d\u6709\u5982\u4e0b\u4e0e\u6587\u4ef6\u76f8\u5173\u7684\u7c7b\u578b\u548c\u5b8f\uff1a

  • FILE \u5bf9\u8c61\u7c7b\u578b\uff0c\u8bb0\u5f55\u63a7\u5236\u6d41\u6240\u9700\u8981\u7684\u6240\u6709\u4fe1\u606f\uff0c\u5305\u62ec\uff1a\u6587\u4ef6\u5b9a\u4f4d\u7b26\u3001\u6307\u5411\u76f8\u5173\u7f13\u51b2\u7684\u6307\u9488\u3001\u9519\u8bef\u6307\u793a\u7b26\u548c\u6587\u4ef6\u7ed3\u675f\u7b26\u3002
    • \u4e0d\u8981\u8bd5\u56fe\u63a2\u7d22 FILE * \u6570\u636e\u5bf9\u8c61\u7684\u5185\u90e8\uff0c\u5373\u4f7f\u5b9e\u73b0\u7ed9\u51fa\u4e86\u67d0\u4e9b\u53ef\u89c1\u57df\u3002\u4e0d\u8981\u4fee\u6539\u5bf9\u8c61\u3001\u4e0d\u8981\u62f7\u8d1d\u5bf9\u8c61\u5e76\u4ee3\u66ff\u4f7f\u7528\uff0c\u56e0\u4e3a\u5b9e\u73b0\u5047\u5b9a\u77e5\u9053\u6d41\u6570\u636e\u5bf9\u8c61\u7684\u6240\u6709\u5730\u5740\u3002
  • fpos_t \u5bf9\u8c61\u7c7b\u578b\uff0c\u542b\u6709\u552f\u4e00\u6307\u5b9a\u6587\u4ef6\u4e2d\u6bcf\u4e2a\u4f4d\u7f6e\u6240\u9700\u7684\u6240\u6709\u4fe1\u606f\u3002
  • stderr, stdin, stdout \u90fd\u662f FILE* \u7c7b\u578b\u7684\u8868\u8fbe\u5f0f\u3002
  • EOF \u5c55\u5f00\u4e3a\u4e00\u4e2a\u8d1f\u7684\u6574\u503c\u5e38\u91cf\u3002
  • NULL
  • SEEK_CUR \u6587\u4ef6\u5f53\u524d\u4f4d\u7f6e
  • SEEK_END \u6587\u4ef6\u7ed3\u675f\u4f4d\u7f6e
  • SEEK_SET \u6587\u4ef6\u5f00\u59cb\u4f4d\u7f6e
"},{"location":"programming_lecture/lecture3/lecture3/#_12","title":"\u51fd\u6570","text":"

\u6587\u4ef6\u64cd\u4f5c\uff1a

  • int remove (const char *filename)
  • int rename (const char *old, const char *new)
  • FILE *tmpfile(void)
  • char * tmpnam(char *s)

\u6587\u4ef6\u8bbf\u95ee\uff1a

  • int fclose(FILE *stream)
    • \u5173\u95ed\u6587\u4ef6\uff0c\u6e05\u7a7a\u6d41\uff08\u6e05\u7a7a\u6d41\u5c31\u662f\u4f20\u9012\u7f13\u51b2\u6570\u636e\uff09\uff0c\u91ca\u653e\u7f13\u51b2\u3002
  • int fflush(FILE *stream)
    • \u7acb\u5373\u5199\u5165\uff08\u8981\u6c42\u4e0a\u4e00\u6b21\u64cd\u4f5c\u662f\u8f93\u51fa\uff09\u3002
  • FILE *fopen(const char *filename, const char *mode)
  • FILE *freopen(const char *filename, const char *mode, FILE *stream)
  • void setbuf(FILE *stream, char *buf)
  • int setvbuf(FILE *stream, char *buf, int mode, size_t size)

mode \u5b57\u7b26\u4e32\u7684\u542b\u4e49\uff1a

flag meaning r read w write (new or cut) a append (new or append) b binary + update

\u6ce8\u610f\u4e00\u4e0b\u4e0a\u9762\u8bcd\u8bed\u7684\u542b\u4e49\uff0cupdate \u548c append \u80fd\u5199\u5165\u7684\u8303\u56f4\u5e94\u8be5\u662f\u4e0d\u540c\u7684\u3002

  • append \u6a21\u5f0f\u4e0b\u6240\u6709\u5199\u64cd\u4f5c\u5f3a\u5236\u52a0\u5230\u6587\u4ef6\u7ed3\u675f\u5904\u3002
  • update \u6a21\u5f0f\u4e0b\uff0c\u82e5\u4e0d\u8c03\u7528\u6587\u4ef6\u5b9a\u4f4d\u51fd\u6570\uff0c\u8f93\u5165\u8f93\u51fa\u4e0d\u4e00\u5b9a\u76f8\u4e92\u7d27\u8ddf\u3002

\u5bf9\u4e8e UNIX \u8fd9\u79cd\u53ea\u6709\u4e00\u79cd\u6587\u4ef6\u7c7b\u578b\u7684\u7cfb\u7edf\uff0c\u5e26 b \u4e0e\u5426\u7684\u6a21\u5f0f\u662f\u76f8\u540c\u7684\u3002

C11 \u4e2d\u65b0\u589e\u4e86 x\uff0c\u5e26\u8be5\u5b57\u6bcd\u7684\u5199\u6a21\u5f0f\u6253\u5f00\u5b58\u5728\u6587\u4ef6\u4f1a\u5931\u8d25\uff08\u76f8\u5f53\u4e8e\u52a0\u4e86\u4fdd\u62a4\uff09\uff0c\u4e14\u5141\u8bb8\u72ec\u5360\u3002

\u683c\u5f0f\u5316\u8f93\u5165\u8f93\u51fa\uff1a

  • fprintf
  • fscanf
  • vfprintf
  • vprintf
  • vsprintf

\u5b57\u7b26\u8f93\u5165\u8f93\u51fa\uff1a

  • fgetc
  • fgets
  • fputc
  • fputs
  • getc
  • getchar
  • [DECPRATED] gets
  • putc
  • putchar
  • puts
  • ungetc

\u5176\u4e2d\uff0cfgetc() \u4e0e getc() \u8fd9\u7c7b\u51fd\u6570\u7684\u4e0d\u540c\u662f\u540e\u8005\u53ef\u80fd\u88ab\u5b9e\u73b0\u4e3a\u5b8f\u3002

\u76f4\u63a5 I/O\uff1a

  • size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  • size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

\u6587\u4ef6\u5b9a\u4f4d\uff1a

  • int fseek(FILE *stream, long int offset, int whence)
  • long int ftell(FILE *stream)
  • void rewind(FILE *stream)

\u4ee5\u4e0b\u4e24\u4e2a\u51fd\u6570\u7528\u4e8e\u5904\u7406\u66f4\u5927\u578b\u7684\u6587\u4ef6\uff08long \u65e0\u6cd5\u8868\u793a\u7684\u504f\u79fb\u503c\uff09

  • int fgetpos(FILE *stream, fpos_t *pos)
  • int fsetpos(FILE *stream, const fpos_t *pos)

\u9519\u8bef\u5904\u7406\uff1a\u7565

"},{"location":"programming_lecture/lecture3/lecture3/#_13","title":"\u6d41\u548c\u6587\u4ef6","text":"

C \u6807\u51c6\u662f\u8fd9\u6837\u63cf\u8ff0\u4e24\u79cd\u6d41\u7684\uff1a

  • \u6587\u672c\u6d41\uff1a\u7ec4\u6210\u6587\u672c\u884c\u7684\u6709\u5e8f\u5b57\u7b26\u5e8f\u5217\uff0c\u6bcf\u4e00\u884c\u7531\u96f6\u4e2a\u6216\u591a\u4e2a\u5b57\u7b26\u52a0\u4e0a\u6807\u5fd7\u7ed3\u675f\u7684\u6362\u884c\u7b26\u7ec4\u6210\u3002
    • \u5b9e\u73b0\u5b9a\u4e49\uff1a\u6700\u540e\u4e00\u884c\u662f\u5426\u9700\u8981\u6362\u884c\u7b26\u3001\u6362\u884c\u7b26\u6b63\u524d\u9762\u7684\u7a7a\u683c\u662f\u5426\u5728\u8bfb\u53d6\u65f6\u51fa\u73b0\u7b49\u3002
  • \u4e8c\u8fdb\u5236\u6d41\uff1a\u5b57\u7b26\u7684\u6709\u5e8f\u5e8f\u5217\u3002

\u5173\u4e8e\u6587\u4ef6\u52a8\u4f5c\uff1a

  • \u6253\u5f00\u6587\u4ef6\uff1a\u6d41\u6253\u5f00\u4e00\u4e2a\u6587\u4ef6\uff0c\u5c31\u662f\u4e0e\u8be5\u6587\u4ef6\u5173\u8054\u3002
    • \u521b\u5efa\u6587\u4ef6\u4f1a\u4e22\u5f03\u5185\u5bb9\u3002
    • \u548c\u6d41\u76f8\u5173\u7684\u6587\u4ef6\u5b9a\u4f4d\u7b26\u5b9a\u4f4d\u5728\u6587\u4ef6\u8d77\u59cb\u4f4d\u7f6e\u3002
    • \u9644\u52a0\u6a21\u5f0f\u4e0b\u5b9a\u4f4d\u4f4d\u7f6e\u7531\u5b9e\u73b0\u51b3\u5b9a\u3002
"},{"location":"programming_lecture/lecture3/lecture3/#_14","title":"\u5728\u6587\u4ef6\u4e2d\u79fb\u52a8","text":"
  • offset \u5e94\u8be5\u7531 ftell \u6765\u51b3\u5b9a\u3002
"},{"location":"programming_lecture/lecture3/lecture3/#_15","title":"\u4e8c\u8fdb\u5236\u6587\u4ef6","text":""},{"location":"programming_lecture/lecture4/lecture4/","title":"C \u6807\u51c6\u5e93","text":"

\u65bd\u5de5\u4e2d

\u672c\u9875\u9762\u6b63\u5728\u7f16\u8f91\u4e2d\u3002

"},{"location":"programming_lecture/lecture5/lecture5/","title":"\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5","text":"

\u65bd\u5de5\u4e2d

\u672c\u9875\u9762\u6b63\u5728\u7f16\u8f91\u4e2d\u3002

"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..65163f6 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,113 @@ + + + + https://ckc-agc.pages.zjusct.io/study-assist/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/test/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/algebra/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/analysis/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/analysis/exam/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/analysis/2023/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/analysis/2024/analysis_lecture1_sequence_limits/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/calculus/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/chemistry/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/lalu/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/physics/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming/faq/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming/exam/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming/exam/lectures_on_c_programming/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture1/lecture1/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture1/pre_class/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture2/lecture2/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture3/lecture3/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture4/lecture4/ + 2023-10-12 + daily + + + https://ckc-agc.pages.zjusct.io/study-assist/programming_lecture/lecture5/lecture5/ + 2023-10-12 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000..f6569a3 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/custom.css b/stylesheets/custom.css new file mode 100644 index 0000000..4dc6935 --- /dev/null +++ b/stylesheets/custom.css @@ -0,0 +1,47 @@ +h1 { + counter-reset: h2; +} +h2 { + counter-reset: h3; +} +h3 { + counter-reset: h4; +} +h4 { + counter-reset: h5; +} +h5 { + counter-reset: h6; +} +h2:before { + counter-increment: h2; + content: counter(h2); + margin-right: 0.8rem; +} +h3:before { + counter-increment: h3; + content: counter(h2) "." counter(h3); + margin-right: 0.8rem; +} +h4:before { + counter-increment: h4; + content: counter(h2) "." counter(h3) "." counter(h4); + margin-right: 0.8rem; +} +h5:before { + counter-increment: h5; + content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5); + margin-right: 0.8rem; +} +h6:before { + counter-increment: h6; + content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6); + margin-right: 0.8rem; +} +.md-typeset h1, .md-typeset h2 { + font-weight: 600; +} +.md-typeset h3 { + font-weight: 500; +} + diff --git a/stylesheets/neoteroi-mkdocs.css b/stylesheets/neoteroi-mkdocs.css new file mode 100644 index 0000000..29e9736 --- /dev/null +++ b/stylesheets/neoteroi-mkdocs.css @@ -0,0 +1 @@ +:root{--nt-color-0: #CD853F;--nt-color-1: #B22222;--nt-color-2: #000080;--nt-color-3: #4B0082;--nt-color-4: #3CB371;--nt-color-5: #D2B48C;--nt-color-6: #FF00FF;--nt-color-7: #98FB98;--nt-color-8: #FFEBCD;--nt-color-9: #2E8B57;--nt-color-10: #6A5ACD;--nt-color-11: #48D1CC;--nt-color-12: #FFA500;--nt-color-13: #F4A460;--nt-color-14: #A52A2A;--nt-color-15: #FFE4C4;--nt-color-16: #FF4500;--nt-color-17: #AFEEEE;--nt-color-18: #FA8072;--nt-color-19: #2F4F4F;--nt-color-20: #FFDAB9;--nt-color-21: #BC8F8F;--nt-color-22: #FFC0CB;--nt-color-23: #00FA9A;--nt-color-24: #F0FFF0;--nt-color-25: #FFFACD;--nt-color-26: #F5F5F5;--nt-color-27: #FF6347;--nt-color-28: #FFFFF0;--nt-color-29: #7FFFD4;--nt-color-30: #E9967A;--nt-color-31: #7B68EE;--nt-color-32: #FFF8DC;--nt-color-33: #0000CD;--nt-color-34: #D2691E;--nt-color-35: #708090;--nt-color-36: #5F9EA0;--nt-color-37: #008080;--nt-color-38: #008000;--nt-color-39: #FFE4E1;--nt-color-40: #FFFF00;--nt-color-41: #FFFAF0;--nt-color-42: #DCDCDC;--nt-color-43: #ADFF2F;--nt-color-44: #ADD8E6;--nt-color-45: #8B008B;--nt-color-46: #7FFF00;--nt-color-47: #800000;--nt-color-48: #20B2AA;--nt-color-49: #556B2F;--nt-color-50: #778899;--nt-color-51: #E6E6FA;--nt-color-52: #FFFAFA;--nt-color-53: #FF7F50;--nt-color-54: #FF0000;--nt-color-55: #F5DEB3;--nt-color-56: #008B8B;--nt-color-57: #66CDAA;--nt-color-58: #808000;--nt-color-59: #FAF0E6;--nt-color-60: #00BFFF;--nt-color-61: #C71585;--nt-color-62: #00FFFF;--nt-color-63: #8B4513;--nt-color-64: #F0F8FF;--nt-color-65: #FAEBD7;--nt-color-66: #8B0000;--nt-color-67: #4682B4;--nt-color-68: #F0E68C;--nt-color-69: #BDB76B;--nt-color-70: #A0522D;--nt-color-71: #FAFAD2;--nt-color-72: #FFD700;--nt-color-73: #DEB887;--nt-color-74: #E0FFFF;--nt-color-75: #8A2BE2;--nt-color-76: #32CD32;--nt-color-77: #87CEFA;--nt-color-78: #00CED1;--nt-color-79: #696969;--nt-color-80: #DDA0DD;--nt-color-81: #EE82EE;--nt-color-82: #FFB6C1;--nt-color-83: #8FBC8F;--nt-color-84: #D8BFD8;--nt-color-85: #9400D3;--nt-color-86: #A9A9A9;--nt-color-87: #FFFFE0;--nt-color-88: #FFF5EE;--nt-color-89: #FFF0F5;--nt-color-90: #FFDEAD;--nt-color-91: #800080;--nt-color-92: #B0E0E6;--nt-color-93: #9932CC;--nt-color-94: #DAA520;--nt-color-95: #F0FFFF;--nt-color-96: #40E0D0;--nt-color-97: #00FF7F;--nt-color-98: #006400;--nt-color-99: #808080;--nt-color-100: #87CEEB;--nt-color-101: #0000FF;--nt-color-102: #6495ED;--nt-color-103: #FDF5E6;--nt-color-104: #B8860B;--nt-color-105: #BA55D3;--nt-color-106: #C0C0C0;--nt-color-107: #000000;--nt-color-108: #F08080;--nt-color-109: #B0C4DE;--nt-color-110: #00008B;--nt-color-111: #6B8E23;--nt-color-112: #FFE4B5;--nt-color-113: #FFA07A;--nt-color-114: #9ACD32;--nt-color-115: #FFFFFF;--nt-color-116: #F5F5DC;--nt-color-117: #90EE90;--nt-color-118: #1E90FF;--nt-color-119: #7CFC00;--nt-color-120: #FF69B4;--nt-color-121: #F8F8FF;--nt-color-122: #F5FFFA;--nt-color-123: #00FF00;--nt-color-124: #D3D3D3;--nt-color-125: #DB7093;--nt-color-126: #DA70D6;--nt-color-127: #FF1493;--nt-color-128: #228B22;--nt-color-129: #FFEFD5;--nt-color-130: #4169E1;--nt-color-131: #191970;--nt-color-132: #9370DB;--nt-color-133: #483D8B;--nt-color-134: #FF8C00;--nt-color-135: #EEE8AA;--nt-color-136: #CD5C5C;--nt-color-137: #DC143C}:root{--nt-group-0-main: #000000;--nt-group-0-dark: #FFFFFF;--nt-group-0-light: #000000;--nt-group-0-main-bg: #F44336;--nt-group-0-dark-bg: #BA000D;--nt-group-0-light-bg: #FF7961;--nt-group-1-main: #000000;--nt-group-1-dark: #FFFFFF;--nt-group-1-light: #000000;--nt-group-1-main-bg: #E91E63;--nt-group-1-dark-bg: #B0003A;--nt-group-1-light-bg: #FF6090;--nt-group-2-main: #FFFFFF;--nt-group-2-dark: #FFFFFF;--nt-group-2-light: #000000;--nt-group-2-main-bg: #9C27B0;--nt-group-2-dark-bg: #6A0080;--nt-group-2-light-bg: #D05CE3;--nt-group-3-main: #FFFFFF;--nt-group-3-dark: #FFFFFF;--nt-group-3-light: #000000;--nt-group-3-main-bg: #673AB7;--nt-group-3-dark-bg: #320B86;--nt-group-3-light-bg: #9A67EA;--nt-group-4-main: #FFFFFF;--nt-group-4-dark: #FFFFFF;--nt-group-4-light: #000000;--nt-group-4-main-bg: #3F51B5;--nt-group-4-dark-bg: #002984;--nt-group-4-light-bg: #757DE8;--nt-group-5-main: #000000;--nt-group-5-dark: #FFFFFF;--nt-group-5-light: #000000;--nt-group-5-main-bg: #2196F3;--nt-group-5-dark-bg: #0069C0;--nt-group-5-light-bg: #6EC6FF;--nt-group-6-main: #000000;--nt-group-6-dark: #FFFFFF;--nt-group-6-light: #000000;--nt-group-6-main-bg: #03A9F4;--nt-group-6-dark-bg: #007AC1;--nt-group-6-light-bg: #67DAFF;--nt-group-7-main: #000000;--nt-group-7-dark: #000000;--nt-group-7-light: #000000;--nt-group-7-main-bg: #00BCD4;--nt-group-7-dark-bg: #008BA3;--nt-group-7-light-bg: #62EFFF;--nt-group-8-main: #000000;--nt-group-8-dark: #FFFFFF;--nt-group-8-light: #000000;--nt-group-8-main-bg: #009688;--nt-group-8-dark-bg: #00675B;--nt-group-8-light-bg: #52C7B8;--nt-group-9-main: #000000;--nt-group-9-dark: #FFFFFF;--nt-group-9-light: #000000;--nt-group-9-main-bg: #4CAF50;--nt-group-9-dark-bg: #087F23;--nt-group-9-light-bg: #80E27E;--nt-group-10-main: #000000;--nt-group-10-dark: #000000;--nt-group-10-light: #000000;--nt-group-10-main-bg: #8BC34A;--nt-group-10-dark-bg: #5A9216;--nt-group-10-light-bg: #BEF67A;--nt-group-11-main: #000000;--nt-group-11-dark: #000000;--nt-group-11-light: #000000;--nt-group-11-main-bg: #CDDC39;--nt-group-11-dark-bg: #99AA00;--nt-group-11-light-bg: #FFFF6E;--nt-group-12-main: #000000;--nt-group-12-dark: #000000;--nt-group-12-light: #000000;--nt-group-12-main-bg: #FFEB3B;--nt-group-12-dark-bg: #C8B900;--nt-group-12-light-bg: #FFFF72;--nt-group-13-main: #000000;--nt-group-13-dark: #000000;--nt-group-13-light: #000000;--nt-group-13-main-bg: #FFC107;--nt-group-13-dark-bg: #C79100;--nt-group-13-light-bg: #FFF350;--nt-group-14-main: #000000;--nt-group-14-dark: #000000;--nt-group-14-light: #000000;--nt-group-14-main-bg: #FF9800;--nt-group-14-dark-bg: #C66900;--nt-group-14-light-bg: #FFC947;--nt-group-15-main: #000000;--nt-group-15-dark: #FFFFFF;--nt-group-15-light: #000000;--nt-group-15-main-bg: #FF5722;--nt-group-15-dark-bg: #C41C00;--nt-group-15-light-bg: #FF8A50;--nt-group-16-main: #FFFFFF;--nt-group-16-dark: #FFFFFF;--nt-group-16-light: #000000;--nt-group-16-main-bg: #795548;--nt-group-16-dark-bg: #4B2C20;--nt-group-16-light-bg: #A98274;--nt-group-17-main: #000000;--nt-group-17-dark: #FFFFFF;--nt-group-17-light: #000000;--nt-group-17-main-bg: #9E9E9E;--nt-group-17-dark-bg: #707070;--nt-group-17-light-bg: #CFCFCF;--nt-group-18-main: #000000;--nt-group-18-dark: #FFFFFF;--nt-group-18-light: #000000;--nt-group-18-main-bg: #607D8B;--nt-group-18-dark-bg: #34515E;--nt-group-18-light-bg: #8EACBB}.nt-pastello{--nt-group-0-main: #000000;--nt-group-0-dark: #000000;--nt-group-0-light: #000000;--nt-group-0-main-bg: #EF9A9A;--nt-group-0-dark-bg: #BA6B6C;--nt-group-0-light-bg: #FFCCCB;--nt-group-1-main: #000000;--nt-group-1-dark: #000000;--nt-group-1-light: #000000;--nt-group-1-main-bg: #F48FB1;--nt-group-1-dark-bg: #BF5F82;--nt-group-1-light-bg: #FFC1E3;--nt-group-2-main: #000000;--nt-group-2-dark: #000000;--nt-group-2-light: #000000;--nt-group-2-main-bg: #CE93D8;--nt-group-2-dark-bg: #9C64A6;--nt-group-2-light-bg: #FFC4FF;--nt-group-3-main: #000000;--nt-group-3-dark: #000000;--nt-group-3-light: #000000;--nt-group-3-main-bg: #B39DDB;--nt-group-3-dark-bg: #836FA9;--nt-group-3-light-bg: #E6CEFF;--nt-group-4-main: #000000;--nt-group-4-dark: #000000;--nt-group-4-light: #000000;--nt-group-4-main-bg: #9FA8DA;--nt-group-4-dark-bg: #6F79A8;--nt-group-4-light-bg: #D1D9FF;--nt-group-5-main: #000000;--nt-group-5-dark: #000000;--nt-group-5-light: #000000;--nt-group-5-main-bg: #90CAF9;--nt-group-5-dark-bg: #5D99C6;--nt-group-5-light-bg: #C3FDFF;--nt-group-6-main: #000000;--nt-group-6-dark: #000000;--nt-group-6-light: #000000;--nt-group-6-main-bg: #81D4FA;--nt-group-6-dark-bg: #4BA3C7;--nt-group-6-light-bg: #B6FFFF;--nt-group-7-main: #000000;--nt-group-7-dark: #000000;--nt-group-7-light: #000000;--nt-group-7-main-bg: #80DEEA;--nt-group-7-dark-bg: #4BACB8;--nt-group-7-light-bg: #B4FFFF;--nt-group-8-main: #000000;--nt-group-8-dark: #000000;--nt-group-8-light: #000000;--nt-group-8-main-bg: #80CBC4;--nt-group-8-dark-bg: #4F9A94;--nt-group-8-light-bg: #B2FEF7;--nt-group-9-main: #000000;--nt-group-9-dark: #000000;--nt-group-9-light: #000000;--nt-group-9-main-bg: #A5D6A7;--nt-group-9-dark-bg: #75A478;--nt-group-9-light-bg: #D7FFD9;--nt-group-10-main: #000000;--nt-group-10-dark: #000000;--nt-group-10-light: #000000;--nt-group-10-main-bg: #C5E1A5;--nt-group-10-dark-bg: #94AF76;--nt-group-10-light-bg: #F8FFD7;--nt-group-11-main: #000000;--nt-group-11-dark: #000000;--nt-group-11-light: #000000;--nt-group-11-main-bg: #E6EE9C;--nt-group-11-dark-bg: #B3BC6D;--nt-group-11-light-bg: #FFFFCE;--nt-group-12-main: #000000;--nt-group-12-dark: #000000;--nt-group-12-light: #000000;--nt-group-12-main-bg: #FFF59D;--nt-group-12-dark-bg: #CBC26D;--nt-group-12-light-bg: #FFFFCF;--nt-group-13-main: #000000;--nt-group-13-dark: #000000;--nt-group-13-light: #000000;--nt-group-13-main-bg: #FFE082;--nt-group-13-dark-bg: #CAAE53;--nt-group-13-light-bg: #FFFFB3;--nt-group-14-main: #000000;--nt-group-14-dark: #000000;--nt-group-14-light: #000000;--nt-group-14-main-bg: #FFCC80;--nt-group-14-dark-bg: #CA9B52;--nt-group-14-light-bg: #FFFFB0;--nt-group-15-main: #000000;--nt-group-15-dark: #000000;--nt-group-15-light: #000000;--nt-group-15-main-bg: #FFAB91;--nt-group-15-dark-bg: #C97B63;--nt-group-15-light-bg: #FFDDC1;--nt-group-16-main: #000000;--nt-group-16-dark: #000000;--nt-group-16-light: #000000;--nt-group-16-main-bg: #BCAAA4;--nt-group-16-dark-bg: #8C7B75;--nt-group-16-light-bg: #EFDCD5;--nt-group-17-main: #000000;--nt-group-17-dark: #000000;--nt-group-17-light: #000000;--nt-group-17-main-bg: #EEEEEE;--nt-group-17-dark-bg: #BCBCBC;--nt-group-17-light-bg: #FFFFFF;--nt-group-18-main: #000000;--nt-group-18-dark: #000000;--nt-group-18-light: #000000;--nt-group-18-main-bg: #B0BEC5;--nt-group-18-dark-bg: #808E95;--nt-group-18-light-bg: #E2F1F8}.nt-group-0 .nt-plan-group-summary,.nt-group-0 .nt-timeline-dot{color:var(--nt-group-0-dark);background-color:var(--nt-group-0-dark-bg)}.nt-group-0 .period{color:var(--nt-group-0-main);background-color:var(--nt-group-0-main-bg)}.nt-group-1 .nt-plan-group-summary,.nt-group-1 .nt-timeline-dot{color:var(--nt-group-1-dark);background-color:var(--nt-group-1-dark-bg)}.nt-group-1 .period{color:var(--nt-group-1-main);background-color:var(--nt-group-1-main-bg)}.nt-group-2 .nt-plan-group-summary,.nt-group-2 .nt-timeline-dot{color:var(--nt-group-2-dark);background-color:var(--nt-group-2-dark-bg)}.nt-group-2 .period{color:var(--nt-group-2-main);background-color:var(--nt-group-2-main-bg)}.nt-group-3 .nt-plan-group-summary,.nt-group-3 .nt-timeline-dot{color:var(--nt-group-3-dark);background-color:var(--nt-group-3-dark-bg)}.nt-group-3 .period{color:var(--nt-group-3-main);background-color:var(--nt-group-3-main-bg)}.nt-group-4 .nt-plan-group-summary,.nt-group-4 .nt-timeline-dot{color:var(--nt-group-4-dark);background-color:var(--nt-group-4-dark-bg)}.nt-group-4 .period{color:var(--nt-group-4-main);background-color:var(--nt-group-4-main-bg)}.nt-group-5 .nt-plan-group-summary,.nt-group-5 .nt-timeline-dot{color:var(--nt-group-5-dark);background-color:var(--nt-group-5-dark-bg)}.nt-group-5 .period{color:var(--nt-group-5-main);background-color:var(--nt-group-5-main-bg)}.nt-group-6 .nt-plan-group-summary,.nt-group-6 .nt-timeline-dot{color:var(--nt-group-6-dark);background-color:var(--nt-group-6-dark-bg)}.nt-group-6 .period{color:var(--nt-group-6-main);background-color:var(--nt-group-6-main-bg)}.nt-group-7 .nt-plan-group-summary,.nt-group-7 .nt-timeline-dot{color:var(--nt-group-7-dark);background-color:var(--nt-group-7-dark-bg)}.nt-group-7 .period{color:var(--nt-group-7-main);background-color:var(--nt-group-7-main-bg)}.nt-group-8 .nt-plan-group-summary,.nt-group-8 .nt-timeline-dot{color:var(--nt-group-8-dark);background-color:var(--nt-group-8-dark-bg)}.nt-group-8 .period{color:var(--nt-group-8-main);background-color:var(--nt-group-8-main-bg)}.nt-group-9 .nt-plan-group-summary,.nt-group-9 .nt-timeline-dot{color:var(--nt-group-9-dark);background-color:var(--nt-group-9-dark-bg)}.nt-group-9 .period{color:var(--nt-group-9-main);background-color:var(--nt-group-9-main-bg)}.nt-group-10 .nt-plan-group-summary,.nt-group-10 .nt-timeline-dot{color:var(--nt-group-10-dark);background-color:var(--nt-group-10-dark-bg)}.nt-group-10 .period{color:var(--nt-group-10-main);background-color:var(--nt-group-10-main-bg)}.nt-group-11 .nt-plan-group-summary,.nt-group-11 .nt-timeline-dot{color:var(--nt-group-11-dark);background-color:var(--nt-group-11-dark-bg)}.nt-group-11 .period{color:var(--nt-group-11-main);background-color:var(--nt-group-11-main-bg)}.nt-group-12 .nt-plan-group-summary,.nt-group-12 .nt-timeline-dot{color:var(--nt-group-12-dark);background-color:var(--nt-group-12-dark-bg)}.nt-group-12 .period{color:var(--nt-group-12-main);background-color:var(--nt-group-12-main-bg)}.nt-group-13 .nt-plan-group-summary,.nt-group-13 .nt-timeline-dot{color:var(--nt-group-13-dark);background-color:var(--nt-group-13-dark-bg)}.nt-group-13 .period{color:var(--nt-group-13-main);background-color:var(--nt-group-13-main-bg)}.nt-group-14 .nt-plan-group-summary,.nt-group-14 .nt-timeline-dot{color:var(--nt-group-14-dark);background-color:var(--nt-group-14-dark-bg)}.nt-group-14 .period{color:var(--nt-group-14-main);background-color:var(--nt-group-14-main-bg)}.nt-group-15 .nt-plan-group-summary,.nt-group-15 .nt-timeline-dot{color:var(--nt-group-15-dark);background-color:var(--nt-group-15-dark-bg)}.nt-group-15 .period{color:var(--nt-group-15-main);background-color:var(--nt-group-15-main-bg)}.nt-group-16 .nt-plan-group-summary,.nt-group-16 .nt-timeline-dot{color:var(--nt-group-16-dark);background-color:var(--nt-group-16-dark-bg)}.nt-group-16 .period{color:var(--nt-group-16-main);background-color:var(--nt-group-16-main-bg)}.nt-group-17 .nt-plan-group-summary,.nt-group-17 .nt-timeline-dot{color:var(--nt-group-17-dark);background-color:var(--nt-group-17-dark-bg)}.nt-group-17 .period{color:var(--nt-group-17-main);background-color:var(--nt-group-17-main-bg)}.nt-group-18 .nt-plan-group-summary,.nt-group-18 .nt-timeline-dot{color:var(--nt-group-18-dark);background-color:var(--nt-group-18-dark-bg)}.nt-group-18 .period{color:var(--nt-group-18-main);background-color:var(--nt-group-18-main-bg)}.nt-error{border:2px dashed darkred;padding:0 1rem;background:#faf9ba;color:darkred}.nt-timeline{margin-top:30px}.nt-timeline .nt-timeline-title{font-size:1.1rem;margin-top:0}.nt-timeline .nt-timeline-sub-title{margin-top:0}.nt-timeline .nt-timeline-content{font-size:.8rem;border-bottom:2px dashed #ccc;padding-bottom:1.2rem}.nt-timeline.horizontal .nt-timeline-items{flex-direction:row;overflow-x:scroll}.nt-timeline.horizontal .nt-timeline-items>div{min-width:400px;margin-right:50px}.nt-timeline.horizontal.reverse .nt-timeline-items{flex-direction:row-reverse}.nt-timeline.horizontal.center .nt-timeline-before{background-image:linear-gradient(rgba(252, 70, 107, 0) 0%, rgb(252, 70, 107) 100%);background-repeat:no-repeat;background-size:100% 2px;background-position:0 center}.nt-timeline.horizontal.center .nt-timeline-after{background-image:linear-gradient(180deg, rgb(252, 70, 107) 0%, rgba(252, 70, 107, 0) 100%);background-repeat:no-repeat;background-size:100% 2px;background-position:0 center}.nt-timeline.horizontal.center .nt-timeline-items{background-image:radial-gradient(circle, rgb(63, 94, 251) 0%, rgb(252, 70, 107) 100%);background-repeat:no-repeat;background-size:100% 2px;background-position:0 center}.nt-timeline.horizontal .nt-timeline-dot{left:50%}.nt-timeline.horizontal .nt-timeline-dot:not(.bigger){top:calc(50% - 4px)}.nt-timeline.horizontal .nt-timeline-dot.bigger{top:calc(50% - 15px)}.nt-timeline.vertical .nt-timeline-items{flex-direction:column}.nt-timeline.vertical.reverse .nt-timeline-items{flex-direction:column-reverse}.nt-timeline.vertical.center .nt-timeline-before{background:linear-gradient(rgba(252, 70, 107, 0) 0%, rgb(252, 70, 107) 100%) no-repeat center/2px 100%}.nt-timeline.vertical.center .nt-timeline-after{background:linear-gradient(rgb(252, 70, 107) 0%, rgba(252, 70, 107, 0) 100%) no-repeat center/2px 100%}.nt-timeline.vertical.center .nt-timeline-items{background:radial-gradient(circle, rgb(63, 94, 251) 0%, rgb(252, 70, 107) 100%) no-repeat center/2px 100%}.nt-timeline.vertical.center .nt-timeline-dot{left:calc(50% - 10px)}.nt-timeline.vertical.center .nt-timeline-dot:not(.bigger){top:10px}.nt-timeline.vertical.center .nt-timeline-dot.bigger{left:calc(50% - 20px)}.nt-timeline.vertical.left{padding-left:100px}.nt-timeline.vertical.left .nt-timeline-item{padding-left:70px}.nt-timeline.vertical.left .nt-timeline-sub-title{left:-100px;width:100px}.nt-timeline.vertical.left .nt-timeline-before{background:linear-gradient(rgba(252, 70, 107, 0) 0%, rgb(252, 70, 107) 100%) no-repeat 30px/2px 100%}.nt-timeline.vertical.left .nt-timeline-after{background:linear-gradient(rgb(252, 70, 107) 0%, rgba(252, 70, 107, 0) 100%) no-repeat 30px/2px 100%}.nt-timeline.vertical.left .nt-timeline-items{background:radial-gradient(circle, rgb(63, 94, 251) 0%, rgb(252, 70, 107) 100%) no-repeat 30px/2px 100%}.nt-timeline.vertical.left .nt-timeline-dot{left:21px;top:8px}.nt-timeline.vertical.left .nt-timeline-dot.bigger{top:0px;left:10px}.nt-timeline.vertical.right{padding-right:100px}.nt-timeline.vertical.right .nt-timeline-sub-title{right:-100px;text-align:left;width:100px}.nt-timeline.vertical.right .nt-timeline-item{padding-right:70px}.nt-timeline.vertical.right .nt-timeline-before{background:linear-gradient(rgba(252, 70, 107, 0) 0%, rgb(252, 70, 107) 100%) no-repeat calc(100% - 30px)/2px 100%}.nt-timeline.vertical.right .nt-timeline-after{background:linear-gradient(rgb(252, 70, 107) 0%, rgba(252, 70, 107, 0) 100%) no-repeat calc(100% - 30px)/2px 100%}.nt-timeline.vertical.right .nt-timeline-items{background:radial-gradient(circle, rgb(63, 94, 251) 0%, rgb(252, 70, 107) 100%) no-repeat calc(100% - 30px)/2px 100%}.nt-timeline.vertical.right .nt-timeline-dot{right:21px;top:8px}.nt-timeline.vertical.right .nt-timeline-dot.bigger{top:10px;right:10px}.nt-timeline-items{display:flex;position:relative}.nt-timeline-items>div{min-height:100px;padding-top:2px;padding-bottom:20px}.nt-timeline-before{content:"";height:15px}.nt-timeline-after{content:"";height:60px;margin-bottom:20px}.nt-timeline-sub-title{position:absolute;width:50%;top:4px;font-size:18px;color:var(--nt-color-50)}[data-md-color-scheme=slate] .nt-timeline-sub-title{color:var(--nt-color-51)}.nt-timeline-item{position:relative}.nt-timeline.vertical.center:not(.alternate) .nt-timeline-item{padding-left:calc(50% + 40px)}.nt-timeline.vertical.center:not(.alternate) .nt-timeline-item .nt-timeline-sub-title{left:0;padding-right:40px;text-align:right}.nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(odd){padding-left:calc(50% + 40px)}.nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(odd) .nt-timeline-sub-title{left:0;padding-right:40px;text-align:right}.nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(even){text-align:right;padding-right:calc(50% + 40px)}.nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(even) .nt-timeline-sub-title{right:0;padding-left:40px;text-align:left}.nt-timeline-dot{position:relative;width:20px;height:20px;border-radius:100%;background-color:#fc5b5b;position:absolute;top:0px;z-index:2;display:flex;justify-content:center;align-items:center;box-shadow:0 2px 1px -1px rgba(0,0,0,.2),0 1px 1px 0 rgba(0,0,0,.14),0 1px 3px 0 rgba(0,0,0,.12);border:3px solid #fff}.nt-timeline-dot:not(.bigger) .icon{font-size:10px}.nt-timeline-dot.bigger{width:40px;height:40px;padding:3px}.nt-timeline-dot .icon{color:#fff;position:relative;top:1px}@supports not (-moz-appearance: none){details .nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(odd) .nt-timeline-sub-title,details .nt-timeline.vertical.center:not(.alternate) .nt-timeline-item .nt-timeline-sub-title{left:-40px}details .nt-timeline.vertical.center.alternate .nt-timeline-item:nth-child(even) .nt-timeline-sub-title{right:-40px}details .nt-timeline.vertical.center .nt-timeline-dot{left:calc(50% - 12px)}details .nt-timeline-dot.bigger{font-size:1rem !important}}.nt-timeline-item:nth-child(0) .nt-timeline-dot{background-color:var(--nt-color-0)}.nt-timeline-item:nth-child(1) .nt-timeline-dot{background-color:var(--nt-color-1)}.nt-timeline-item:nth-child(2) .nt-timeline-dot{background-color:var(--nt-color-2)}.nt-timeline-item:nth-child(3) .nt-timeline-dot{background-color:var(--nt-color-3)}.nt-timeline-item:nth-child(4) .nt-timeline-dot{background-color:var(--nt-color-4)}.nt-timeline-item:nth-child(5) .nt-timeline-dot{background-color:var(--nt-color-5)}.nt-timeline-item:nth-child(6) .nt-timeline-dot{background-color:var(--nt-color-6)}.nt-timeline-item:nth-child(7) .nt-timeline-dot{background-color:var(--nt-color-7)}.nt-timeline-item:nth-child(8) .nt-timeline-dot{background-color:var(--nt-color-8)}.nt-timeline-item:nth-child(9) .nt-timeline-dot{background-color:var(--nt-color-9)}.nt-timeline-item:nth-child(10) .nt-timeline-dot{background-color:var(--nt-color-10)}.nt-timeline-item:nth-child(11) .nt-timeline-dot{background-color:var(--nt-color-11)}.nt-timeline-item:nth-child(12) .nt-timeline-dot{background-color:var(--nt-color-12)}.nt-timeline-item:nth-child(13) .nt-timeline-dot{background-color:var(--nt-color-13)}.nt-timeline-item:nth-child(14) .nt-timeline-dot{background-color:var(--nt-color-14)}.nt-timeline-item:nth-child(15) .nt-timeline-dot{background-color:var(--nt-color-15)}.nt-timeline-item:nth-child(16) .nt-timeline-dot{background-color:var(--nt-color-16)}.nt-timeline-item:nth-child(17) .nt-timeline-dot{background-color:var(--nt-color-17)}.nt-timeline-item:nth-child(18) .nt-timeline-dot{background-color:var(--nt-color-18)}.nt-timeline-item:nth-child(19) .nt-timeline-dot{background-color:var(--nt-color-19)}.nt-timeline-item:nth-child(20) .nt-timeline-dot{background-color:var(--nt-color-20)}:root{--nt-scrollbar-color: #2751b0;--nt-plan-actions-height: 24px;--nt-units-background: #ff9800;--nt-months-background: #2751b0;--nt-plan-vertical-line-color: #a3a3a3ad}.nt-pastello{--nt-scrollbar-color: #9fb8f4;--nt-units-background: #f5dc82;--nt-months-background: #5b7fd1}[data-md-color-scheme=slate]{--nt-units-background: #003773}[data-md-color-scheme=slate] .nt-pastello{--nt-units-background: #3f4997}.nt-plan-root{min-height:200px;scrollbar-width:20px;scrollbar-color:var(--nt-scrollbar-color);display:flex}.nt-plan-root ::-webkit-scrollbar{width:20px}.nt-plan-root ::-webkit-scrollbar-track{box-shadow:inset 0 0 5px gray;border-radius:10px}.nt-plan-root ::-webkit-scrollbar-thumb{background:var(--nt-scrollbar-color);border-radius:10px}.nt-plan-root .nt-plan{flex:80%}.nt-plan-root.no-groups .nt-plan-periods{padding-left:0}.nt-plan-root.no-groups .nt-plan-group-summary{display:none}.nt-plan-root .nt-timeline-dot.bigger{top:-10px}.nt-plan-root .nt-timeline-dot.bigger[title]{cursor:help}.nt-plan{white-space:nowrap;overflow-x:auto;display:flex}.nt-plan .ug-timeline-dot{left:368px;top:-8px;cursor:help}.months{display:flex}.month{flex:auto;display:inline-block;box-shadow:rgba(0,0,0,.2) 0px 3px 1px -2px,rgba(0,0,0,.14) 0px 2px 2px 0px,rgba(0,0,0,.12) 0px 1px 5px 0px inset;background-color:var(--nt-months-background);color:#fff;text-transform:uppercase;font-family:Roboto,Helvetica,Arial,sans-serif;padding:2px 5px;font-size:12px;border:1px solid #000;width:150px;border-radius:8px}.nt-plan-group-activities{flex:auto;position:relative}.nt-vline{border-left:1px dashed var(--nt-plan-vertical-line-color);height:100%;left:0;position:absolute;margin-left:-0.5px;top:0;-webkit-transition:all .5s linear !important;-moz-transition:all .5s linear !important;-ms-transition:all .5s linear !important;-o-transition:all .5s linear !important;transition:all .5s linear !important;z-index:-2}.nt-plan-activity{display:flex;margin:2px 0;background-color:rgba(187,187,187,.2509803922)}.actions{height:var(--nt-plan-actions-height)}.actions{position:relative}.period{display:inline-block;height:var(--nt-plan-actions-height);width:120px;position:absolute;left:0px;background:#1da1f2;border-radius:5px;transition:all .5s;cursor:help;-webkit-transition:width 1s ease-in-out;-moz-transition:width 1s ease-in-out;-o-transition:width 1s ease-in-out;transition:width 1s ease-in-out}.period .nt-tooltip{display:none;top:30px;position:relative;padding:1rem;text-align:center;font-size:12px}.period:hover .nt-tooltip{display:inline-block}.period-0{left:340px;visibility:visible;background-color:#456165}.period-1{left:40px;visibility:visible;background-color:green}.period-2{left:120px;visibility:visible;background-color:pink;width:80px}.period-3{left:190px;visibility:visible;background-color:darkred;width:150px}.weeks>span,.days>span{height:25px}.weeks>span{display:inline-block;margin:0;padding:0;font-weight:bold}.weeks>span .week-text{font-size:10px;position:absolute;display:inline-block;padding:3px 4px}.days{z-index:-2;position:relative}.day-text{font-size:10px;position:absolute;display:inline-block;padding:3px 4px}.period span{font-size:12px;vertical-align:top;margin-left:4px;color:#000;background:rgba(255,255,255,.6588235294);border-radius:6px;padding:0 4px}.weeks,.days{height:20px;display:flex;box-sizing:content-box}.months{display:flex}.week,.day{height:20px;position:relative;border:1;flex:auto;border:2px solid #fff;border-radius:4px;background-color:var(--nt-units-background);cursor:help}.years{display:flex}.year{text-align:center;border-right:1px solid var(--nt-plan-vertical-line-color);font-weight:bold}.year:first-child{border-left:1px solid var(--nt-plan-vertical-line-color)}.year:first-child:last-child{width:100%}.quarters{display:flex}.quarter{width:12.5%;text-align:center;border-right:1px solid var(--nt-plan-vertical-line-color);font-weight:bold}.quarter:first-child{border-left:1px solid var(--nt-plan-vertical-line-color)}.nt-plan-group{margin:20px 0;position:relative}.nt-plan-group{display:flex}.nt-plan-group-summary{background:#2751b0;width:150px;white-space:normal;padding:.1rem .5rem;border-radius:5px;color:#fff;z-index:3}.nt-plan-group-summary p{margin:0;padding:0;font-size:.6rem;color:#fff}.nt-plan-group-summary,.month,.period,.week,.day,.nt-tooltip{border:3px solid #fff;box-shadow:0 2px 3px -1px rgba(0,0,0,.2),0 3px 3px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}.nt-plan-periods{padding-left:150px}.months{z-index:2;position:relative}.weeks{position:relative;top:-2px;z-index:0}.month,.quarter,.year,.week,.day,.nt-tooltip{font-family:Roboto,Helvetica,Arial,sans-serif;box-sizing:border-box}.nt-cards.nt-grid{display:grid;grid-auto-columns:1fr;gap:.5rem;max-width:100vw;overflow-x:auto;padding:1px}.nt-cards.nt-grid.cols-1{grid-template-columns:repeat(1, 1fr)}.nt-cards.nt-grid.cols-2{grid-template-columns:repeat(2, 1fr)}.nt-cards.nt-grid.cols-3{grid-template-columns:repeat(3, 1fr)}.nt-cards.nt-grid.cols-4{grid-template-columns:repeat(4, 1fr)}.nt-cards.nt-grid.cols-5{grid-template-columns:repeat(5, 1fr)}.nt-cards.nt-grid.cols-6{grid-template-columns:repeat(6, 1fr)}@media only screen and (max-width: 400px){.nt-cards.nt-grid{grid-template-columns:repeat(1, 1fr) !important}}.nt-card{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)}.nt-card:hover{box-shadow:0 2px 2px 0 rgba(0,0,0,.24),0 3px 1px -2px rgba(0,0,0,.3),0 1px 5px 0 rgba(0,0,0,.22)}[data-md-color-scheme=slate] .nt-card{box-shadow:0 2px 2px 0 rgba(4,40,33,.14),0 3px 1px -2px rgba(40,86,94,.47),0 1px 5px 0 rgba(139,252,255,.64)}[data-md-color-scheme=slate] .nt-card:hover{box-shadow:0 2px 2px 0 rgba(0,255,206,.14),0 3px 1px -2px rgba(33,156,177,.47),0 1px 5px 0 rgba(96,251,255,.64)}.nt-card>a{color:var(--md-default-fg-color)}.nt-card>a>div{cursor:pointer}.nt-card{padding:5px;margin-bottom:.5rem}.nt-card-title{font-size:1rem;font-weight:bold;margin:4px 0 8px 0;line-height:22px}.nt-card-content{padding:.4rem .8rem .8rem .8rem}.nt-card-text{font-size:14px;padding:0;margin:0}.nt-card .nt-card-image{text-align:center;border-radius:2px;background-position:center center;background-size:cover;background-repeat:no-repeat;min-height:120px}.nt-card .nt-card-image.tags img{margin-top:12px}.nt-card .nt-card-image img{height:105px;margin-top:5px}.nt-card a:hover,.nt-card a:focus{color:var(--md-accent-fg-color)}.nt-card h2{margin:0}.span-table-wrapper table{border-collapse:collapse;margin-bottom:2rem;border-radius:.1rem}.span-table td,.span-table th{padding:.2rem;background-color:var(--md-default-bg-color);font-size:.64rem;max-width:100%;overflow:auto;touch-action:auto;border-top:.05rem solid var(--md-typeset-table-color);padding:.9375em 1.25em;vertical-align:top}.span-table tr:first-child td{font-weight:700;min-width:5rem;padding:.9375em 1.25em;vertical-align:top}.span-table td:first-child{border-left:.05rem solid var(--md-typeset-table-color)}.span-table td:last-child{border-right:.05rem solid var(--md-typeset-table-color)}.span-table tr:last-child{border-bottom:.05rem solid var(--md-typeset-table-color)}.span-table [colspan],.span-table [rowspan]{font-weight:bold;border:.05rem solid var(--md-typeset-table-color)}.span-table tr:not(:first-child):hover td:not([colspan]):not([rowspan]),.span-table td[colspan]:hover,.span-table td[rowspan]:hover{background-color:rgba(0,0,0,.035);box-shadow:0 .05rem 0 var(--md-default-bg-color) inset;transition:background-color 125ms}.nt-contribs{margin-top:2rem;font-size:small;border-top:1px dotted #d3d3d3;padding-top:.5rem}.nt-contribs .nt-contributors{padding-top:.5rem;display:flex;flex-wrap:wrap}.nt-contribs .nt-contributor{background:#d3d3d3;background-size:cover;width:40px;height:40px;border-radius:100%;margin:0 6px 6px 0;cursor:help;opacity:.7}.nt-contribs .nt-contributor:hover{opacity:1}.nt-contribs .nt-contributors-title{font-style:italic;margin-bottom:0}.nt-contribs .nt-initials{text-transform:uppercase;font-size:20px;text-align:center;width:40px;height:40px;display:inline-block;vertical-align:middle;position:relative;top:4px;color:inherit;font-weight:bold}.nt-contribs .nt-group-0{background-color:var(--nt-color-0)}.nt-contribs .nt-group-1{background-color:var(--nt-color-1)}.nt-contribs .nt-group-2{background-color:var(--nt-color-2)}.nt-contribs .nt-group-3{background-color:var(--nt-color-3)}.nt-contribs .nt-group-4{background-color:var(--nt-color-4)}.nt-contribs .nt-group-5{background-color:var(--nt-color-5)}.nt-contribs .nt-group-6{background-color:var(--nt-color-6)}.nt-contribs .nt-group-7{color:#000;background-color:var(--nt-color-7)}.nt-contribs .nt-group-8{color:#000;background-color:var(--nt-color-8)}.nt-contribs .nt-group-9{background-color:var(--nt-color-9)}.nt-contribs .nt-group-10{background-color:var(--nt-color-10)}.nt-contribs .nt-group-11{background-color:var(--nt-color-11)}.nt-contribs .nt-group-12{background-color:var(--nt-color-12)}.nt-contribs .nt-group-13{background-color:var(--nt-color-13)}.nt-contribs .nt-group-14{background-color:var(--nt-color-14)}.nt-contribs .nt-group-15{color:#000;background-color:var(--nt-color-15)}.nt-contribs .nt-group-16{background-color:var(--nt-color-16)}.nt-contribs .nt-group-17{color:#000;background-color:var(--nt-color-17)}.nt-contribs .nt-group-18{background-color:var(--nt-color-18)}.nt-contribs .nt-group-19{background-color:var(--nt-color-19)}.nt-contribs .nt-group-20{color:#000;background-color:var(--nt-color-20)}.nt-contribs .nt-group-21{color:#000;background-color:var(--nt-color-21)}.nt-contribs .nt-group-22{color:#000;background-color:var(--nt-color-22)}.nt-contribs .nt-group-23{color:#000;background-color:var(--nt-color-23)}.nt-contribs .nt-group-24{color:#000;background-color:var(--nt-color-24)}.nt-contribs .nt-group-25{color:#000;background-color:var(--nt-color-25)}.nt-contribs .nt-group-26{color:#000;background-color:var(--nt-color-26)}.nt-contribs .nt-group-27{background-color:var(--nt-color-27)}.nt-contribs .nt-group-28{color:#000;background-color:var(--nt-color-28)}.nt-contribs .nt-group-29{color:#000;background-color:var(--nt-color-29)}.nt-contribs .nt-group-30{background-color:var(--nt-color-30)}.nt-contribs .nt-group-31{background-color:var(--nt-color-31)}.nt-contribs .nt-group-32{color:#000;background-color:var(--nt-color-32)}.nt-contribs .nt-group-33{background-color:var(--nt-color-33)}.nt-contribs .nt-group-34{background-color:var(--nt-color-34)}.nt-contribs .nt-group-35{background-color:var(--nt-color-35)}.nt-contribs .nt-group-36{background-color:var(--nt-color-36)}.nt-contribs .nt-group-37{background-color:var(--nt-color-37)}.nt-contribs .nt-group-38{background-color:var(--nt-color-38)}.nt-contribs .nt-group-39{color:#000;background-color:var(--nt-color-39)}.nt-contribs .nt-group-40{color:#000;background-color:var(--nt-color-40)}.nt-contribs .nt-group-41{color:#000;background-color:var(--nt-color-41)}.nt-contribs .nt-group-42{color:#000;background-color:var(--nt-color-42)}.nt-contribs .nt-group-43{color:#000;background-color:var(--nt-color-43)}.nt-contribs .nt-group-44{color:#000;background-color:var(--nt-color-44)}.nt-contribs .nt-group-45{background-color:var(--nt-color-45)}.nt-contribs .nt-group-46{color:#000;background-color:var(--nt-color-46)}.nt-contribs .nt-group-47{background-color:var(--nt-color-47)}.nt-contribs .nt-group-48{background-color:var(--nt-color-48)}.nt-contribs .nt-group-49{background-color:var(--nt-color-49)} diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..76ec679 --- /dev/null +++ b/test/index.html @@ -0,0 +1,628 @@ + + + + + + + + + + + + +测试 - 浙江大学竺可桢学院辅学计划站点 + + + + + + + + + + + + + + + + +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + + +

LaTeX 数学公式测试

+

本页面用于测试各类 LaTeX 公式是否能正常显示。

+

simple

+
\[ +x ={-b \pm \sqrt{b^2-4ac}\over 2a} +\]
+

matrix

+
\[ +\left\{\begin{matrix} + x=a + r\text{cos}\theta \\ + y=b + r\text{sin}\theta +\end{matrix}\right. +\]
+

array

+
\[ +\begin{array}{l} + a\mathop{{x}}\nolimits^{{2}}+bx+c=0 \\ + \Delta =\mathop{{b}}\nolimits^{{2}}-4ac \\ + \mathop{{x}}\nolimits_{{1,2}}=\frac{{-b \pm + \sqrt{{\mathop{{b}}\nolimits^{{2}}-4ac}}}}{{2a}} \\ + \mathop{{x}}\nolimits_{{1}}+\mathop{{x}}\nolimits_{{2}}=-\frac{{b}}{{a}} \\ + \mathop{{x}}\nolimits_{{1}}\mathop{{x}}\nolimits_{{2}}=\frac{{c}}{{a}} +\end{array} +\]
+

calculus

+
\[ +\int \frac{1}{\sqrt{1-x^{2}}}\mathrm{d}x= \arcsin x +C +\]
+

algebra

+
\[ +\begin{vmatrix} + \mathbf{i}& \mathbf{j}& \mathbf{k} \\ + \frac{\partial X}{\partial u}& \frac{\partial Y}{\partial u}& 0 \\ + \frac{\partial X}{\partial v}& \frac{\partial Y}{\partial v}& 0 \\ +\end{vmatrix} +\]
+

physics

+
\[ +\mathop \Phi \nolimits_e = \oint { \mathord{ \buildrel{ \lower3pt \hbox{$ \scriptscriptstyle \rightharpoonup$}} \over E} \cdot {d \mathord{ \buildrel{ \lower3pt \hbox{$ \scriptscriptstyle \rightharpoonup$}} \over S}} = {1 \over {{\varepsilon _0}}}\sum {q} } +\]
+

Unicode

+
\[ +%此公式需要在设置中开启unicode扩展支持 +\begin{array}{l} + {\huge \unicode{8751}}_\mathbb{S} \mathbf{E} \cdot\mathrm{d}s= \cfrac{Q}{\varepsilon_0} \\ + {\huge \unicode{8751}}_\mathbb{S} \mathbf{B} \cdot\mathrm{d}s= 0 \\ + {\huge \oint}_{\mathbb{L}}^{} \mathbf{E} \cdot \mathrm{d}l=-\cfrac{\mathrm{d}\Phi _{\mathbf{B}}}{\mathrm{d}t } \\ + {\huge \oint}_{\mathbb{L}}^{} \mathbf{B} \cdot \mathrm{d}l=\mu_0I+ \mu_0 \varepsilon_0\cfrac{\mathrm{d}\Phi _{\mathbf{E}}}{\mathrm{d}t } +\end{array} +\]
+

mhchem

+
\[ +%此公式需要在【设置】中开启mhchem扩展支持 具体用法请参考【帮助】2.11.2 +\ce{SO4^2- + Ba^2+ -> BaSO4 v} +\]
+
+
+ + + Last update: + October 12, 2023 + +
+
+
+
+
+ +
+
+
+
+ + + + + + + \ No newline at end of file