mirror of
https://github.com/janishutz/eth-summaries.git
synced 2026-01-11 19:48:27 +00:00
[SPCA] Continue summary
This commit is contained in:
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
|
||||
@@ -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 <type it represents> <name of the new type>}
|
||||
|
||||
@@ -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 );}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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.
|
||||
|
||||
28
semester3/spca/parts/00_c/02_preprocessor.tex
Normal file
28
semester3/spca/parts/00_c/02_preprocessor.tex
Normal 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
|
||||
@@ -1 +0,0 @@
|
||||
\subsection{The C preprocessor}
|
||||
Binary file not shown.
@@ -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 ────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user