draft
This commit is contained in:
BIN
assets/calc-1.png
Normal file
BIN
assets/calc-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 910 KiB |
BIN
assets/calc-2.png
Normal file
BIN
assets/calc-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 481 KiB |
BIN
assets/calc.png
Normal file
BIN
assets/calc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
assets/p312.png
Normal file
BIN
assets/p312.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 478 KiB |
BIN
assets/p313.png
Normal file
BIN
assets/p313.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 851 KiB |
@@ -31,5 +31,10 @@ paper_config:
|
|||||||
# - { name: "pkg-wo-opt", options: "" }
|
# - { name: "pkg-wo-opt", options: "" }
|
||||||
|
|
||||||
sections:
|
sections:
|
||||||
- { path: 'section/introduction.tex', newpg: true }
|
- { path: 'section/introduction.tex', newpg: false }
|
||||||
|
- { path: 'section/syntax.tex', newpg: true }
|
||||||
|
- { path: 'section/p312.tex', newpg: true }
|
||||||
|
- { path: 'section/p313.tex', newpg: true }
|
||||||
|
- { path: 'section/calc.tex', newpg: true }
|
||||||
|
- { path: 'section/appendix.tex', newpg: true }
|
||||||
|
|
||||||
|
|||||||
43
main.tex
Normal file
43
main.tex
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
\documentclass{class/nitreport}
|
||||||
|
|
||||||
|
\reporttitle{第10回課題}
|
||||||
|
\reportauthor{柴田 健琉}
|
||||||
|
\studentid{2024D14}
|
||||||
|
\seatingnum{15}
|
||||||
|
\reportdate{令和7年}{06月}{19日}
|
||||||
|
\turnindate{令和7年}{06月}{19日}
|
||||||
|
\schoolname{岐阜工業高等専門学校}
|
||||||
|
\department{電子制御工学科}
|
||||||
|
\subject{情報処理I}
|
||||||
|
\professor{岡崎憲一}
|
||||||
|
|
||||||
|
\pagenumbering{roman}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\coverpage
|
||||||
|
|
||||||
|
\tableofcontents
|
||||||
|
\newpage
|
||||||
|
\pagenumbering{arabic}
|
||||||
|
|
||||||
|
\input{section/introduction.tex}
|
||||||
|
|
||||||
|
\input{section/syntax.tex}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\input{section/p312.tex}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\input{section/p313.tex}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\input{section/calc.tex}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\input{section/appendix.tex}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\printbibliography[heading=bibintoc,title={参考文献}]
|
||||||
|
|
||||||
|
\compiledTime
|
||||||
|
\end{document}
|
||||||
BIN
output/main.pdf
Normal file
BIN
output/main.pdf
Normal file
Binary file not shown.
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"language": "",
|
"language": "C",
|
||||||
"name": "",
|
"name": "簡易電卓",
|
||||||
"description": "",
|
"description": "2つの実数を入力し、四則演算を指定し、小数点6桁で結果を表示する。0 divも考慮すること。",
|
||||||
"output": {
|
"output": {
|
||||||
"type": "screenshot | text",
|
"type": "screenshot",
|
||||||
"content": ""
|
"content": "./assets/calc.png"
|
||||||
},
|
},
|
||||||
"note": ""
|
"note": ""
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
programs/calc/main
Executable file
BIN
programs/calc/main
Executable file
Binary file not shown.
@@ -0,0 +1,48 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define ADD 1
|
||||||
|
#define SUB 2
|
||||||
|
#define MUL 3
|
||||||
|
#define DIV 4
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
double a, b;
|
||||||
|
int op;
|
||||||
|
|
||||||
|
printf("Input first number: ");
|
||||||
|
scanf("%lf", &a);
|
||||||
|
printf("Input second number: ");
|
||||||
|
scanf("%lf", &b);
|
||||||
|
|
||||||
|
printf("Select Operation:\n"
|
||||||
|
"[1]: Addition\n"
|
||||||
|
"[2]: Subtraction\n"
|
||||||
|
"[3]: Multiplication\n"
|
||||||
|
"[4]: Division\n"
|
||||||
|
"> ");
|
||||||
|
scanf("%d", &op);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case ADD:
|
||||||
|
printf("ANS: %lf\n", a + b);
|
||||||
|
break;
|
||||||
|
case SUB:
|
||||||
|
printf("ANS: %lf\n", a - b);
|
||||||
|
break;
|
||||||
|
case MUL:
|
||||||
|
printf("ANS: %lf\n", a * b);
|
||||||
|
break;
|
||||||
|
case DIV:
|
||||||
|
if (b == 0.0) {
|
||||||
|
puts("Zero Division");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
printf("ANS: %lf\n", a / b);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("Undefined Operation");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
8
programs/ifvswitch/gen-if.py
Normal file
8
programs/ifvswitch/gen-if.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
with open("./ifs.c", mode='w') as file:
|
||||||
|
num = 100000
|
||||||
|
file.write("int comp(int x) {\n if (x == 0) {\n return 0;\n } ")
|
||||||
|
for i in range(1,num-1):
|
||||||
|
s = f"else if (x == {i}) {{\n return {i};\n }} "
|
||||||
|
file.write(s)
|
||||||
|
file.write(f"else {{\n return {num-1};\n }}\n}}")
|
||||||
|
file.write(f"\n\nint main(void) {{\n for (int i = 0; i < {num}; i++) {{ \n comp(i);\n }}\n return 0;\n}}\n")
|
||||||
8
programs/ifvswitch/gen-switch.py
Normal file
8
programs/ifvswitch/gen-switch.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
with open("./switch-case.c", mode='w') as file:
|
||||||
|
num = 100000
|
||||||
|
file.write("int comp(int x) {\n switch (x) {\n")
|
||||||
|
for i in range(num):
|
||||||
|
s = f" case {i}: return {i};\n"
|
||||||
|
file.write(s)
|
||||||
|
file.write(" }\n}")
|
||||||
|
file.write(f"\n\nint main(void) {{\n for (int i = 0; i < {num}; i++) {{\n comp(i);\n }}\n return 0;\n}}\n")
|
||||||
BIN
programs/ifvswitch/progs.tar.xz
Normal file
BIN
programs/ifvswitch/progs.tar.xz
Normal file
Binary file not shown.
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"language": "",
|
"language": "C",
|
||||||
"name": "",
|
"name": "演習 3-12",
|
||||||
"description": "",
|
"description": "教科書のList 3-4をSwitch文で書き換えたプログラム。",
|
||||||
"output": {
|
"output": {
|
||||||
"type": "screenshot | text",
|
"type": "screenshot",
|
||||||
"content": ""
|
"content": "./assets/p312.png"
|
||||||
},
|
},
|
||||||
"note": ""
|
"note": ""
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
programs/p312/main
Executable file
BIN
programs/p312/main
Executable file
Binary file not shown.
@@ -0,0 +1,21 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int n;
|
||||||
|
|
||||||
|
printf("Input Integer: ");
|
||||||
|
scanf("%d", &n);
|
||||||
|
|
||||||
|
switch (n % 2) {
|
||||||
|
case 0:
|
||||||
|
puts("The number is even.");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
puts("The number is odd.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("Unknown Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"language": "",
|
"language": "C",
|
||||||
"name": "",
|
"name": "演習 3-13",
|
||||||
"description": "",
|
"description": "教科書のList 3-18 をSwitch文で書き換えたプログラム。",
|
||||||
"output": {
|
"output": {
|
||||||
"type": "screenshot | text",
|
"type": "screenshot",
|
||||||
"content": ""
|
"content": "./assets/p313.png"
|
||||||
},
|
},
|
||||||
"note": ""
|
"note": ""
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
programs/p313/main
Executable file
BIN
programs/p313/main
Executable file
Binary file not shown.
@@ -0,0 +1,35 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int month;
|
||||||
|
|
||||||
|
printf("Input month: ");
|
||||||
|
scanf("%d", &month);
|
||||||
|
|
||||||
|
switch (month) {
|
||||||
|
case 12:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
puts("It is winter.");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
puts("It is spring.");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
puts("It is summer.");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
puts("It is autumn.");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
puts("Unknown month.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
@online{example,
|
@online{switch_cppref,
|
||||||
title = {Example Entry},
|
title = {switch statement},
|
||||||
author = {Inc., Example},
|
author = {cppreference},
|
||||||
organization = {Example, Inc.},
|
url = {https://en.cppreference.com/w/c/language/switch.html},
|
||||||
url = {https://www.example.com},
|
year = {2018},
|
||||||
year = {1970},
|
|
||||||
month = {01},
|
month = {01},
|
||||||
urldate = {1970-01-01}
|
urldate = {2025-06-19}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,67 @@
|
|||||||
|
|
||||||
\subsection{Deep Dive - if と switch の根本的な違い}
|
\subsection{Deep Dive - if と switch の根本的な違い}
|
||||||
|
|
||||||
|
初学者は\texttt{if}文と\texttt{switch}文の使い分けで困まる時があるようだ。
|
||||||
|
前述したとおり、どちらも条件分岐を行うことができる。
|
||||||
|
|
||||||
|
しかし、2つには文法以外に明確な違いがある。それは、\texttt{switch}文のほうが「圧倒的」に\\処理速度が速いというところである。
|
||||||
|
まず、その処理速度の違いを見てみる。
|
||||||
|
|
||||||
|
以下のPythonスクリプトで10万個の条件文を含むCソースコードを生成する:
|
||||||
|
|
||||||
|
\defaultlistingstyle
|
||||||
|
\lstinputlisting[language=Python,title={\texttt{if}文10万個}]{../programs/ifvswitch/gen-if.py}
|
||||||
|
\lstinputlisting[language=Python,title={\texttt{switch}文10万個}]{../programs/ifvswitch/gen-switch.py}
|
||||||
|
|
||||||
|
これらを実行し、Cソースコードを生成する:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
$ python gen-if.py
|
||||||
|
$ python gen-switch.py
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
以下が生成されたソースコードの一部始終:
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={\texttt{if}文10万個のソースコード},consecutivenumbers=false,linerange={1-8,199996-200010}]{../programs/ifvswitch/ifs.c}
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={\texttt{switch}文10万個のソースコード},consecutivenumbers=false,linerange={1-8,99998-100011}]{../programs/ifvswitch/switch-case.c}
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
// 検証に影響する最適化を無効にしてコンパイルする
|
||||||
|
$ gcc -O0 ifs.c -o ifs
|
||||||
|
$ gcc -O0 switch-case.c -o switch-case
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
生成物をタイマに通して実行する:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
$ time ./ifs
|
||||||
|
|
||||||
|
real 0m59.045s
|
||||||
|
user 0m58.444s
|
||||||
|
sys 0m0.001s
|
||||||
|
|
||||||
|
$ time ./switch-case
|
||||||
|
|
||||||
|
real 0m0.006s
|
||||||
|
user 0m0.004s
|
||||||
|
sys 0m0.002s
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
実行結果から\texttt{switch}文の方が\texttt{if}文の約9840倍も高速であると分かる。
|
||||||
|
|
||||||
|
では、なぜ\texttt{switch}文の方が速いのか。それは、比較演算の数にある。
|
||||||
|
|
||||||
|
\texttt{if}文はその数と同じ数の比較演算が使われている。
|
||||||
|
一方、\texttt{switch}文は比較に関する演算は一度しか行われない。
|
||||||
|
|
||||||
|
それぞれのバイナリを逆アセンブルする:
|
||||||
|
|
||||||
|
\begin{lstlisting}
|
||||||
|
$ objdump -Mintel -d ifs
|
||||||
|
$ objdump -Mintel -d switch-case
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
section/calc.tex
Normal file
17
section/calc.tex
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
\section{簡易電卓}
|
||||||
|
|
||||||
|
2つの実数を入力し、四則演算を指定し、小数点6桁で結果を表示する。0 divも考慮すること。
|
||||||
|
|
||||||
|
\subsection{コードリスティング}
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={簡易電卓}]{../programs/calc/main.c}
|
||||||
|
|
||||||
|
\subsection{実行結果}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=\textwidth]{./assets/calc-1.png}
|
||||||
|
\end{center}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=\textwidth]{./assets/calc-2.png}
|
||||||
|
\end{center}
|
||||||
@@ -8,5 +8,5 @@
|
|||||||
\item OS: Arch Linux
|
\item OS: Arch Linux
|
||||||
\item CPU アーキテクチャ: \texttt{x86\_64}
|
\item CPU アーキテクチャ: \texttt{x86\_64}
|
||||||
\item C コンパイラ: \texttt{gcc バージョン 14.2.1 20250322 (GCC)}
|
\item C コンパイラ: \texttt{gcc バージョン 14.2.1 20250322 (GCC)}
|
||||||
\item C コンパイラオプション: \texttt{}
|
\item C コンパイラオプション: \texttt{-Wall}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|||||||
13
section/p312.tex
Normal file
13
section/p312.tex
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
\section{演習 3-12}
|
||||||
|
|
||||||
|
教科書のList 3-4をSwitch文で書き換えたプログラム。
|
||||||
|
|
||||||
|
\subsection{コードリスティング}
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={演習 3-12}]{../programs/p312/main.c}
|
||||||
|
|
||||||
|
\subsection{実行結果}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=\textwidth]{./assets/p312.png}
|
||||||
|
\end{center}
|
||||||
13
section/p313.tex
Normal file
13
section/p313.tex
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
\section{演習 3-13}
|
||||||
|
|
||||||
|
教科書のList 3-18 をSwitch文で書き換えたプログラム。
|
||||||
|
|
||||||
|
\subsection{コードリスティング}
|
||||||
|
|
||||||
|
\lstinputlisting[language=C,title={演習 3-13}]{../programs/p313/main.c}
|
||||||
|
|
||||||
|
\subsection{実行結果}
|
||||||
|
|
||||||
|
\begin{center}
|
||||||
|
\includegraphics[width=\textwidth]{./assets/p313.png}
|
||||||
|
\end{center}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
\section{今回の構文}
|
||||||
|
|
||||||
|
\subsection{\texttt{switch}文}
|
||||||
|
|
||||||
|
\texttt{switch}文は\texttt{if}文と同じように条件分岐を行う文である。
|
||||||
|
if文と違い、論理式・論理値による分岐ではなく、評価後の整数値によって分岐する。
|
||||||
|
それぞれの条件は\texttt{case}ラベルで記載され、コロン(\texttt{:})の後に処理を記述する。
|
||||||
|
処理の終わりは\texttt{break}文を書く。
|
||||||
|
ケースは縦落ちすることができ、\texttt{break}文を書かずにしておくことで複数の値に同じ処理を割り当てることができる。
|
||||||
|
\texttt{if}文における最後の\texttt{else}は\texttt{switch}文では\texttt{default}ラベルとなっている。\cite{switch_cppref}
|
||||||
|
|
||||||
|
\defaultlistingstyle
|
||||||
|
\begin{lstlisting}[language=C,title={\texttt{switch}文}]
|
||||||
|
switch (式) {
|
||||||
|
case <値1>:
|
||||||
|
<処理>... // 値1の場合の処理
|
||||||
|
break;
|
||||||
|
case <値2>:
|
||||||
|
<処理>... // 値1の場合の処理
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
<処理>... // それ以外の場合の処理
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
\begin{lstlisting}[language=C,title={縦落ち(Fall-through)する\texttt{switch}文}]
|
||||||
|
switch (式) {
|
||||||
|
case <値1>:
|
||||||
|
<処理>... // 値1の場合の処理
|
||||||
|
break;
|
||||||
|
case <値2>:
|
||||||
|
case <値3>:
|
||||||
|
<処理>... // 値2と値3の場合の処理
|
||||||
|
break;
|
||||||
|
case <値4>:
|
||||||
|
<処理>... // 値4の場合の処理
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
<処理>... // それ以外の場合の処理
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|||||||
Reference in New Issue
Block a user