[SPCA] Restructure, intro to C continued

This commit is contained in:
2026-01-05 16:48:36 +01:00
parent 4a02e20218
commit 433111833c
16 changed files with 154 additions and 9 deletions

View File

@@ -13,3 +13,5 @@ This of course leads to \texttt{C} performing excellently and there are many pro
but instead optimized \texttt{C} code that is then compiled into machine code using a \texttt{C} compiler.
This has a number of benefits, most notably that \texttt{C} compilers can produce very efficient assembly,
as lots of effort is put into the \texttt{C} compilers by the hardware manufacturers.
There are many great \lC\ tutorials out there, a simple one (as for many other languages too) can be found \hlhref{https://www.w3schools.com/c/index.php}{here}

View File

@@ -1,4 +1,4 @@
\subsection{The Syntax}
\subsection{Basics}
\texttt{C} uses a very similar syntax as many other programming languages, like \texttt{Java}, \texttt{JavaScript} and many more\dots
to be precise, it is \textit{them} that use the \texttt{C} syntax, not the other way around. So:
\inputcodewithfilename{c}{code-examples/00_c/}{00_intro.c}
@@ -7,7 +7,6 @@ In \texttt{C} we are referring to the implementation of a function as a \bi{(fun
and to the definition of the function signature (or variables, without initializing them) as the \bi{(function) declaration} (or, correspondingly, \textit{variable declaration}).
\texttt{C} code is usuallt split into the source files, ending in \texttt{.c} (where the local functions and variables are declared, as well as all function definitions)
and the header files, ending in \texttt{.h}, where the external declarations are defined. Usually, no definition of functions are in the \texttt{.h} files
and the header files, ending in \texttt{.h}, usually sharing the filename of the source file, where the external declarations are defined.
By convention, no definition of functions are in the \texttt{.h} files, and neither variables, but there is nothing preventing you from putting them there.
\inputcodewithfilename{c}{code-examples/00_c/}{01_func.h}
\inputcodewithfilename{c}{code-examples/00_c/}{01_func.c}

View File

@@ -0,0 +1,14 @@
\newpage
\subsubsection{Control Flow}
Many of the control-flow structures of \texttt{C} can be found in the below code snippet.
A note of caution when using goto: It is almost never a good idea (can lead to unexpected behaviour, is hard to maintain, etc).
Where it however is very handy is for error recovery (and cleanup functions) and early termination of multiple loops (jumping out of a loop).
So, for example, if you have to run multiple functions to set something up and one of them fails,
you can jump to a label and have all cleanup code execute that you have specified there.
And because the labels are (as in Assembly) simply skipped over during execution, you can make very nice cleanup code.
We can also use \texttt{continue} and \texttt{break} statements similarly to \texttt{Java}, they do not however accept labels.
(Reminder: \texttt{continue} skips the loop body and goes to the next iteration)
\inputcodewithfilename{c}{code-examples/00_c/}{01_func.c}

View File

@@ -0,0 +1,37 @@
\newpage
\subsubsection{Declarations}
We have already seen a few examples for how \texttt{C} handles declarations.
In concept they are similar (and scoping works the same) to most other \texttt{C}-like programming languages, including \texttt{Java}.
\inputcodewithfilename{c}{code-examples/00_c/}{02_declarations.c}
A peculiarity of \texttt{C} is that the bit-count is not defined by the language, but rather the hardware it is compiled for.
\begin{fullTable}{llll}{\texttt{C} data type & typical 32-bit & ia32 & x86-64}{Comparison of byte-sizes for each datatype on different architectures}
\texttt{char} & 1 & 1 & 1 \\
\texttt{short} & 2 & 2 & 2 \\
\texttt{int} & 4 & 4 & 4 \\
\texttt{long} & 4 & 4 & 8 \\
\texttt{long long} & 8 & 8 & 8 \\
\texttt{float} & 4 & 4 & 4 \\
\texttt{double} & 4 & 8 & 8 \\
\texttt{long double} & 8 & 10/12 & 16 \\
\end{fullTable}
\drmvspace
By default, integers in \lC\ are \texttt{signed}, to declare an unsigned integer, use \texttt{unsigned int}.
Since it is hard and annoying to remember the number of bytes that are in each data type, \texttt{C99} has introduced the extended integer types,
which can be imported from \texttt{stdint.h} and are of form \texttt{int<bit count>\_t} and \texttt{uint<bit count>\_t},
where we substitute the \texttt{<bit count>} with the number of bits (have to correspond to a valid type of course).
Another notable difference of \texttt{C} compared to other languages is that \texttt{C} doesn't natively have a \texttt{boolean} type,
by convention a \texttt{short} is used to represent it, where any non-zero value means \texttt{true} and \texttt{0} means \texttt{false}.
Since boolean types are quite handy, the \texttt{!} syntax for negation turns any non-zero value of any integer type into zero and vice-versa.
\texttt{C99} has added support for a bool type via \texttt{stdbool.h}, which however is still an integer.
Notably, \texttt{C} doesn't have a very rigid type system and lower bit-count types are implicitly cast to higher bit-count data types, i.e.
if you add a \texttt{short} and an \texttt{int}, the \texttt{short} is cast to \texttt{short} (bits 16-31 are set to $0$) and the two are added.
Explicit casting between almost all types is also supported.
Some will force a change of bit representation, but most won't (notably, when casting to and from \texttt{float}-like types, minus to \texttt{void})
Another important feature is that every \lC\ statement is also an expression, see above code block for example.
The \texttt{void} type has \bi{no} value and is used for untyped pointers and declaring functions with no return value

View File

@@ -0,0 +1,43 @@
\subsubsection{Operators}
The list of operators in \lC\ is similar to the one of \texttt{Java}, etc.
In Table \ref{tab:c-operators}, you can see an overview of the operators, sorted by precedence in descending order.
You may notice that the \verb|&| and \verb|*| operators appear twice. The higher precedence occurrence is the address operator and dereference, respectively,
and the lower precedence is \texttt{bitwise and} and \texttt{multiplication}, respectively.
Very low precedence belongs to boolean operators \verb|&&| and \texttt{||}, as well as the ternary operator and assignment operators
\begin{table}[h!]
\begin{tables}{ll}{Operator & Associativity}
\texttt{() [] -> .} & Left-to-right \\
\verb|! ~ ++ -- + - * & (type) sizeof| & Right-to-left \\
\verb|* / %| & Left-to-right \\
\verb|+ -| & Left-to-right \\
\verb|<< >>| & Left-to-right \\
\verb|< <= >= >| & Left-to-right \\
\verb|== !=| & Left-to-right \\
\verb|&| (logical and) & Left-to-right \\
\verb|^| (logical xor) & Left-to-right \\
\texttt{|} (logical or) & Left-to-right \\
\verb|&&| (boolean and) & Left-to-right \\
\texttt{||} (boolean or) & Left-to-right \\
\texttt{? :} (ternary) & Right-to-left \\
\verb|= += -= *= /= %= &= ^=||\verb|= <<= >>=| & Right-to-left \\
\verb|,| & Left-to-right \\
\end{tables}
\caption{\lC\ operators ordered in descending order by precedence}
\label{tab:c-operators}
\end{table}
\shade{blue}{Associativity}
\begin{itemize}
\item Left-to-right: $A + B + C \mapsto (A + B) + C$
\item Right-to-left: \texttt{A += B += C} $\mapsto$ \texttt{(A += B) += C}
\end{itemize}
As it should be, boolean and, as well as boolean or support early termination.
The ternary operator works as in other programming languages \verb|result = expr ? res_true : res_false;|
As previously touched on, every statement is also an expression, i.e. the following works
\mint{c}|printf("%s", x = foo(y)); // prints output of foo(y) and x has that value|
Pre-increment (\texttt{++i}, new value returned) and post-increment (\texttt{i++}, old value returned) are also supported by \lC.