[SPCA] Continue summary

This commit is contained in:
2026-01-06 10:52:34 +01:00
parent 74205e8cf0
commit 13e3210298
20 changed files with 79 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
int my_int; // Allocates memory on the stack. int my_int; // Allocates memory on the stack.
// Variable is global (read / writable by entire program) // Variable is global (read / writable by entire program)
static int my_local_int; // only available locally (in this file) 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 const int MY_CONST = 10; // constant (immutable), convention: SCREAM_CASE
enum { ONE, TWO } num; // Enum. ONE will get value 0, TWO has value 1 enum { ONE, TWO } num; // Enum. ONE will get value 0, TWO has value 1

View File

@@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#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 { "<val(c)>", "<val(c)>_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;
}

View File

@@ -1,7 +1,7 @@
\subsection{Basics} \subsection{Basics}
\texttt{C} uses a very similar syntax as many other programming languages, like \texttt{Java}, \texttt{JavaScript} and many more\dots \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: 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) 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}). 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) \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. 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. 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}

View File

@@ -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. 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) (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}

View File

@@ -2,7 +2,7 @@
\subsubsection{Declarations} \subsubsection{Declarations}
We have already seen a few examples for how \texttt{C} handles 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}. 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. 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} \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. 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 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 <type it represents> <name of the new type>}

View File

@@ -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| \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. 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 );}

View File

@@ -4,4 +4,4 @@
Unlike some other programming languages, arrays are \bi{not} dynamic length. 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. 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}

View File

@@ -3,4 +3,4 @@
with length of the array $n + 1$ (where $n$ is the number of characters of the string). 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|. 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} 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}

View File

@@ -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.

View File

@@ -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 <file name>}.
Imports in \lC\ are handled by the preprocessor, that for each \verb|#include <file1.h>|, the preprocessor simply copies the contents of the file recursively into one file.
Depending on if we use \verb|#include <file1.h>| 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

View File

@@ -1 +0,0 @@
\subsection{The C preprocessor}

Binary file not shown.

View File

@@ -66,8 +66,9 @@
\input{parts/00_c/01_basics/03_operators.tex} \input{parts/00_c/01_basics/03_operators.tex}
\input{parts/00_c/01_basics/04_arrays.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/05_strings.tex}
\input{parts/00_c/01_basics/06_pointers.tex} \input{parts/00_c/01_basics/06_integers.tex}
\input{parts/00_c/02_preprocessor/00_intro.tex} \input{parts/00_c/01_basics/07_pointers.tex}
\input{parts/00_c/02_preprocessor.tex}
% ── Intro to x86 asm ──────────────────────────────────────────────── % ── Intro to x86 asm ────────────────────────────────────────────────