forked from joelfenwick/ctute
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoperators.tex
138 lines (108 loc) · 6.94 KB
/
operators.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
\chapter{Operators and expressions}
%Until now, I've avoided putting (non-atom) expressions into calls.
In most cases in C, wherever you write literal values, you can write expressions\footnote{More information:
there are some things which need to be known at \emph{compile time} rather than \emph{run time}.
The most obvious cases of this are \emph{case labels} and array sizes in ANSI-C.}.
An expression is a fragment of code which can be ``evaluated'' --- that is, they can be processed to get a value.
For example:
\texttt{3+4} is an expression which gives the value \texttt{7} when evaluated.
In fact, literal values are also expressions (they evaluate to the value as written).
\section{Arithmetic operators}
The operators \texttt{+} and \texttt{-} work as you would expect.
Division is written with \texttt{/} and multiplication as \texttt{*}.
The \texttt{\%} operator (known as ``modulo'') returns the remainder of its arguments;
\texttt{a\%b} returns the remainder when \texttt{a} is divided by \texttt{b}.
For example: \lstinline!7%3! is \texttt{1} and \lstinline!23%5! is \texttt{3}.
\subsection{Precedence}
When an expression involves more than one type of operator, the issue of precedence comes up.
That is, some operators are evaluated before others --- this is independent of the order the operators are written in.
The rules for \texttt{+,-,*,/} are the same as for normal arithmetic.
You can look up the precedence for operators, but you can also test them.
For example, \texttt{+} and \texttt{*} could be compared like this:
(Enter and run the following)
\begin{codeblock}
#include <stdio.h>
int main(int argc, char** argv) {
printf("%d %d %d\n", (2 + 3 * 7), ((2 + 3) * 7),
(2 + (3 * 7))); // Continues from prev line.
if ((2 + 3 * 7) == ((2 + 3) * 7)) {
printf("+ is evaluated first\n");
} else if ((2 + 3 * 7)==(2 + (3 * 7))) {
printf("* is evaluated first\n");
} else {
printf("Something has gone horribly wrong\n");
}
return 0;
}
\end{codeblock}
\begin{exercise}
Modify the program above to test relative precedence of \texttt{+} and \texttt{\%}.
\end{exercise}
\subsection{Simple Types}\label{sec:types}
All of C's simple types are numeric in some way.
This includes types which have other purposes (\texttt{char} and \texttt{bool}).
Numeric types can be classified in a number of ways:
\begin{itemize}
\item Integer vs Floating point --- \texttt{bool\footnote{\texttt{stdbool.h} must be included to use \texttt{bool} (and \texttt{true} and \texttt{false}).}, char, int} are integer types while \texttt{float} and \texttt{double} are floating point types.
Arithmetic operators which act on integers \emph{will evaluate to an integer result} so for example, \texttt{5/2} is \texttt{2}, not \texttt{2.5}.
Do not make this mistake:
\texttt{float f=2/3;}
\texttt{f} will contain \texttt{0} not \texttt{0.66}.
This is because storing a value in a variable does not influence the way the expression is evaluated.
If an expression contains a mixture of types, its arguments will be converted to the most general type.
For example:
\texttt{2/3.0} will give a floating point result because one of its arguments is floating point\footnote{Somewhat confusingly, the default floating point type in C is \texttt{double} not \texttt{float}.}.
You could also achieve this with a \emph{cast}: \texttt{2/(float)3} or multiplication \texttt{(1.0*2)/3}.
\item Signed vs Unsigned --- integer types can be restricted to store only positive values\footnote{and therefore store higher maximum values using the same number of bits because the sign bit can be used for value storage.}.
For example: \texttt{unsigned int}, \texttt{unsigned char}\footnote{\texttt{int} defaults to \texttt{signed int} but if you care whether your \texttt{char}s are signed or unsigned, it is better to be explicit.}.
\item size --- types can be modified to indicate how much memory they take\footnote{In C, these modifications are not absolutely defined in the standard.}.
Types which take more memory can store a larger range of values.
For example: \texttt{short int} and \texttt{long int} are smaller and larger than normal \texttt{int}s respectively.
These can be combined with \texttt{signed} and \texttt{unsigned}.
\end{itemize}
There are other type modifiers but we'll keep this simple and standard\footnote{For example: \texttt{long long int} and \texttt{quad double} are non-standard types.}.
To output other types with \texttt{printf}, different placeholders are required:
\begin{itemize}
\item [\texttt{\%e \%f \%g}] --- all of these will output a \texttt{float} \emph{or} \texttt{double} but they format it in different ways.
\item [\texttt{\%c}] --- prints a char (as a character rather than as a number).
\item [\texttt{\%hd}] --- prints a \texttt{short int}.
\item [\texttt{\%ld}] --- prints a \texttt{long int}.
\item [\texttt{\%u}] --- prints an \texttt{unsigned int}.
\end{itemize}
Consult documentation for other combinations.
\section{Bit operators}
These operators act on the individual bits in the value.
\begin{itemize}
\item \lstinline|a&b| --- bitwise \emph{and} of the two values.
\item \lstinline:a|b: --- bitwise \emph{or} of the two values.
\item \lstinline|a^b| --- bitwise \emph{exclusive or} of the two values.
\item \lstinline|a<<b| --- left shift \texttt{a} by \texttt{b} bits.
\item \lstinline|a>>b| --- right shift \texttt{a} by \texttt{b} bits.
\item \lstinline|~a| --- one's complement of \texttt{a}.
\end{itemize}
\section{Relational operators}
These return a boolean value \texttt{true} or \texttt{false}.
Remember that in C, \texttt{bool}s are also integer values.
A 0 indicates false, and any non-zero value is interpreted as true.
\lstinline|a < b, a <= b, a > b, a >= b, a != b, a == b|.
Be careful comparing floating point values, since numerical errors can
creep in\footnote{A better option for \texttt{a==b} is to check if the difference is small
enough. $|a-b|<tolerance$ $\Rightarrow$ \lstinline!fabs(a-b)<0.0002!}.
\section{Logical operators}
These look like their bitwise counterparts so it is important not to mix them up.
\begin{itemize}
\item \lstinline!a && b! --- logical \emph{and}. eg: \lstinline!true && true == true!
\item \lstinline!a || b! --- logical \emph{or}. eg: \lstinline!false || true == true!
\item \lstinline|!a| --- logical \emph{not}. eg: \lstinline@!(a || b) == (!a && !b)@ (deMorgan's law)
\end{itemize}
\lstinline!&&! and \lstinline!||! are ``short-circuiting'' operators: the second argument will not be evaluated unless required (ie: in \lstinline!false && EXP! and \lstinline!true || EXP!, \texttt{EXP} will not be evaluated).
\section{Other operators}
The following are also operators in C but we won't talk about them here.
\begin{itemize}
\item unary \texttt{*} for pointers (as opposed to arithmetic)
\item \texttt{->} for pointers
\item \texttt{+ -} for pointers
\item \texttt{[ ]} for array subscripts
\item \texttt{ ? : } --- the ternary operator.
\item \texttt{,} --- the comma operator.
\end{itemize}