diff --git a/semester3/spca/code-examples/00_c/00_intro.c b/semester3/spca/code-examples/00_c/00_basics/00_intro.c similarity index 100% rename from semester3/spca/code-examples/00_c/00_intro.c rename to semester3/spca/code-examples/00_c/00_basics/00_intro.c diff --git a/semester3/spca/code-examples/00_c/01_func.c b/semester3/spca/code-examples/00_c/00_basics/01_func.c similarity index 100% rename from semester3/spca/code-examples/00_c/01_func.c rename to semester3/spca/code-examples/00_c/00_basics/01_func.c diff --git a/semester3/spca/code-examples/00_c/01_func.h b/semester3/spca/code-examples/00_c/00_basics/01_func.h similarity index 100% rename from semester3/spca/code-examples/00_c/01_func.h rename to semester3/spca/code-examples/00_c/00_basics/01_func.h diff --git a/semester3/spca/code-examples/00_c/02_declarations.c b/semester3/spca/code-examples/00_c/00_basics/02_declarations.c similarity index 95% rename from semester3/spca/code-examples/00_c/02_declarations.c rename to semester3/spca/code-examples/00_c/00_basics/02_declarations.c index add64e3..6ba93f9 100644 --- a/semester3/spca/code-examples/00_c/02_declarations.c +++ b/semester3/spca/code-examples/00_c/00_basics/02_declarations.c @@ -1,6 +1,7 @@ int my_int; // Allocates memory on the stack. // Variable is global (read / writable by entire program) static int my_local_int; // only available locally (in this file) +extern const char *var; // Defined in some other file const int MY_CONST = 10; // constant (immutable), convention: SCREAM_CASE enum { ONE, TWO } num; // Enum. ONE will get value 0, TWO has value 1 diff --git a/semester3/spca/code-examples/00_c/03_arrays.c b/semester3/spca/code-examples/00_c/00_basics/03_arrays.c similarity index 100% rename from semester3/spca/code-examples/00_c/03_arrays.c rename to semester3/spca/code-examples/00_c/00_basics/03_arrays.c diff --git a/semester3/spca/code-examples/00_c/04_strings.c b/semester3/spca/code-examples/00_c/00_basics/04_strings.c similarity index 100% rename from semester3/spca/code-examples/00_c/04_strings.c rename to semester3/spca/code-examples/00_c/00_basics/04_strings.c diff --git a/semester3/spca/code-examples/00_c/05_integers.c b/semester3/spca/code-examples/00_c/00_basics/05_integers.c similarity index 100% rename from semester3/spca/code-examples/00_c/05_integers.c rename to semester3/spca/code-examples/00_c/00_basics/05_integers.c diff --git a/semester3/spca/code-examples/00_c/06_pointers.c b/semester3/spca/code-examples/00_c/00_basics/06_pointers.c similarity index 100% rename from semester3/spca/code-examples/00_c/06_pointers.c rename to semester3/spca/code-examples/00_c/00_basics/06_pointers.c diff --git a/semester3/spca/code-examples/00_c/01_preprocessor/00_macros.c b/semester3/spca/code-examples/00_c/01_preprocessor/00_macros.c new file mode 100644 index 0000000..b1ba3c9 --- /dev/null +++ b/semester3/spca/code-examples/00_c/01_preprocessor/00_macros.c @@ -0,0 +1,28 @@ +#include +#include +#define FOO BAZ +#define BAR( x ) ( x + 3 ) +#define SKIP_SPACES( p ) \ + do { \ + while ( p > 0 ) { p--; } \ + } while ( 0 ) +#define COMMAND( c ) { #c, c##_command } // Produces { "", "_command" } + +#ifdef FOO // If macro is defined, ifndef for if not defined + #define COURSE "SPCA" +#else + #define COURSE "Systems Programming and Computer Architecture" +#endif + +#if 1 + #define OUT HELLO // if statement +#endif + +int main( int argc, char *argv[] ) { + int i = 10; + SKIP_SPACES( i ); + + printf( "%s", COURSE ); + + return EXIT_SUCCESS; +} diff --git a/semester3/spca/parts/00_c/01_basics/00_intro.tex b/semester3/spca/parts/00_c/01_basics/00_intro.tex index 5d907ab..8e07f16 100644 --- a/semester3/spca/parts/00_c/01_basics/00_intro.tex +++ b/semester3/spca/parts/00_c/01_basics/00_intro.tex @@ -1,7 +1,7 @@ \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} +\inputcodewithfilename{c}{code-examples/00_c/00_basics/}{00_intro.c} In \texttt{C} we are referring to the implementation of a function as a \bi{(function) definition} (correspondingly, \textit{variable definition}, if the variable is initialized) and to the definition of the function signature (or variables, without initializing them) as the \bi{(function) declaration} (or, correspondingly, \textit{variable declaration}). @@ -9,4 +9,4 @@ and to the definition of the function signature (or variables, without initializ \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}, 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/00_basics/}{01_func.h} diff --git a/semester3/spca/parts/00_c/01_basics/01_control-flow.tex b/semester3/spca/parts/00_c/01_basics/01_control-flow.tex index b95731a..01e277c 100644 --- a/semester3/spca/parts/00_c/01_basics/01_control-flow.tex +++ b/semester3/spca/parts/00_c/01_basics/01_control-flow.tex @@ -9,6 +9,6 @@ And because the labels are (as in Assembly) simply skipped over during execution 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} +\inputcodewithfilename{c}{code-examples/00_c/00_basics/}{01_func.c} diff --git a/semester3/spca/parts/00_c/01_basics/02_declarations.tex b/semester3/spca/parts/00_c/01_basics/02_declarations.tex index fe4c41e..b3c6b20 100644 --- a/semester3/spca/parts/00_c/01_basics/02_declarations.tex +++ b/semester3/spca/parts/00_c/01_basics/02_declarations.tex @@ -2,7 +2,7 @@ \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} +\inputcodewithfilename{c}{code-examples/00_c/00_basics/}{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} @@ -35,3 +35,5 @@ Some will force a change of bit representation, but most won't (notably, when ca 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 + +It is also possible to define a custom type using \texttt{typedef } diff --git a/semester3/spca/parts/00_c/01_basics/03_operators.tex b/semester3/spca/parts/00_c/01_basics/03_operators.tex index aae850e..752940c 100644 --- a/semester3/spca/parts/00_c/01_basics/03_operators.tex +++ b/semester3/spca/parts/00_c/01_basics/03_operators.tex @@ -41,3 +41,5 @@ As previously touched on, every statement is also an expression, i.e. the follow \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. + +\lC\ has an \texttt{assert} statement, but do not use it for error handling. The basic syntax is \texttt{assert( expr );} diff --git a/semester3/spca/parts/00_c/01_basics/04_arrays.tex b/semester3/spca/parts/00_c/01_basics/04_arrays.tex index d5e4ada..8f9ca15 100644 --- a/semester3/spca/parts/00_c/01_basics/04_arrays.tex +++ b/semester3/spca/parts/00_c/01_basics/04_arrays.tex @@ -4,4 +4,4 @@ Unlike some other programming languages, arrays are \bi{not} dynamic length. The below snippet includes already some pointer arithmetic tricks. The variable \texttt{data} is a pointer to the first element of the array. -\inputcodewithfilename{c}{code-examples/00_c/}{03_arrays.c} +\inputcodewithfilename{c}{code-examples/00_c/00_basics/}{03_arrays.c} diff --git a/semester3/spca/parts/00_c/01_basics/05_strings.tex b/semester3/spca/parts/00_c/01_basics/05_strings.tex index 16504e0..c2b884f 100644 --- a/semester3/spca/parts/00_c/01_basics/05_strings.tex +++ b/semester3/spca/parts/00_c/01_basics/05_strings.tex @@ -3,4 +3,4 @@ with length of the array $n + 1$ (where $n$ is the number of characters of the string). The extra element is the termination character, called the \texttt{null character}, denoted \verb|\0|. To determine the actual length of the string (as it may be padded), we can use \verb|strnlen(str, maxlen)| from \texttt{string.h} -\inputcodewithfilename{c}{code-examples/00_c/}{04_strings.c} +\inputcodewithfilename{c}{code-examples/00_c/00_basics/}{04_strings.c} diff --git a/semester3/spca/parts/00_c/01_basics/06_integers.tex b/semester3/spca/parts/00_c/01_basics/06_integers.tex index e69de29..be56d02 100644 --- a/semester3/spca/parts/00_c/01_basics/06_integers.tex +++ b/semester3/spca/parts/00_c/01_basics/06_integers.tex @@ -0,0 +1,9 @@ +\subsubsection{Integers in C} +As a reminder, integers are encoded as follows in big endian notation, with $x_i$ being the $i$-th bit and $w$ being the number of bits used to represent the number: +\begin{itemize}[noitemsep] + \item \bi{Unsigned}: $\displaystyle \sum_{i = 0}^{w - 1} x_i \cdot 2^i$ + \item \bi{Signed}: $\displaystyle -x_{w - 1} \cdot 2^{w - 1} + \sum_{i = 0}^{w - 1} x_i \cdot 2^i$ (two's complement notation, with $x_{w - 1}$ being the sign-bit) +\end{itemize} +The minimum number representable is $0$ and $-2^{w - 1}$, respectively, whereas the maximum number representable is $2^w - 1$ and $2^{w - 1} - 1$ + +We can use the shift operators to multiply and divide by two. Shift operations are usually \textit{much} cheaper than multiplication and division. diff --git a/semester3/spca/parts/00_c/02_preprocessor.tex b/semester3/spca/parts/00_c/02_preprocessor.tex new file mode 100644 index 0000000..cbe9bdc --- /dev/null +++ b/semester3/spca/parts/00_c/02_preprocessor.tex @@ -0,0 +1,28 @@ +\newpage +\subsection{The C preprocessor} +To have \texttt{gcc} stop compiliation after running through \texttt{cpp}, the \texttt{C preprocessor}, use \texttt{gcc -E }. + +Imports in \lC\ are handled by the preprocessor, that for each \verb|#include |, the preprocessor simply copies the contents of the file recursively into one file. + +Depending on if we use \verb|#include | or \verb|#include "file1.h"| the preprocessor will search for the file either in the system headers or in the project directory. +Be wary of including files twice, as the preprocessor will recursively include all files (i.e. it will include files from the files we included) + +The \lC\ preprocessor gives us what are called \texttt{preprocessor macros}, which have the format \verb|#define NAME SUBSTITUTION|. +\rmvspace + +\inputcodewithfilename{c}{code-examples/00_c/01_preprocessor/}{00_macros.c} + +To avoid issues with semicolons at the end of preprocessor macros that wrap statements that cannot end in semicolons, we can use a concept called semicolon swallowing. +For that, we wrap the statements in a \texttt{do \dots\ while(0)} loop, which is removed by the compiler on compile, also taking with it the semicolon. + +There are also a number of predefined macros: +\begin{itemize}[noitemsep] + \item \verb|__FILE__|: Filename of processed file + \item \verb|__LINE__|: Line number of this usage of macro + \item \verb|__DATE__|: Date of processing + \item \verb|__TIME__|: Time of processing + \item \verb|__STDC__|: Set if ANSI Standard \lC\ compiler is used + \item \verb|__STDC_VERSION__|: The version of Standard \lC\ being compiled + \item \dots many more +\end{itemize} +In headers, we typically use \verb|#ifndef __FILENAME_H_| followed by a \verb|#define __FILENAME_H_| or the like to check if the header was already included before diff --git a/semester3/spca/parts/00_c/02_preprocessor/00_intro.tex b/semester3/spca/parts/00_c/02_preprocessor/00_intro.tex deleted file mode 100644 index 9267262..0000000 --- a/semester3/spca/parts/00_c/02_preprocessor/00_intro.tex +++ /dev/null @@ -1 +0,0 @@ -\subsection{The C preprocessor} diff --git a/semester3/spca/spca-summary.pdf b/semester3/spca/spca-summary.pdf index d5d2b50..9777a2e 100644 Binary files a/semester3/spca/spca-summary.pdf and b/semester3/spca/spca-summary.pdf differ diff --git a/semester3/spca/spca-summary.tex b/semester3/spca/spca-summary.tex index 609cfd5..be693ad 100644 --- a/semester3/spca/spca-summary.tex +++ b/semester3/spca/spca-summary.tex @@ -66,8 +66,9 @@ \input{parts/00_c/01_basics/03_operators.tex} \input{parts/00_c/01_basics/04_arrays.tex} \input{parts/00_c/01_basics/05_strings.tex} -\input{parts/00_c/01_basics/06_pointers.tex} -\input{parts/00_c/02_preprocessor/00_intro.tex} +\input{parts/00_c/01_basics/06_integers.tex} +\input{parts/00_c/01_basics/07_pointers.tex} +\input{parts/00_c/02_preprocessor.tex} % ── Intro to x86 asm ────────────────────────────────────────────────