-
Notifications
You must be signed in to change notification settings - Fork 0
/
lecture3.tex
145 lines (122 loc) · 3.4 KB
/
lecture3.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
139
140
141
142
143
144
145
\chapter{Pointers}
\section{Pointers in C}
\begin{minted}{c}
int a;
a = -85;
printf("%d", a);
\end{minted}
\ldots yields the following (\emph{Type} and \emph{Name} are just for notation):
\noindent
\begin{tabular}{llrr}
Type & Name & Addr & Value\\ \hline
\vdots & \vdots & \vdots & \vdots \\
\texttt{int} & \texttt{a} & 100 & -85 \\
\vdots & \vdots & \vdots & \vdots \\
\end{tabular}
A pointer is a way of storing an memory address.
\begin{minted}[tabsize=4]{c}
int *x; // x is an address of a int
int y = 9; // y is an int
x = &y; // x points to address of y
// "reference" operator
int z = *x; // z gets the value of what x pointed to
// "dereference" operator
*x = -7; // assign -7 to x's target.
\end{minted}
\subsection{Generic pointer}
\begin{itemize}
\item Points to \emph{any object}.
\item \mint{c}{void *vp;}
\end{itemize}
\subsection{Pointer to struct}
\begin{minted}{c}
typedef struct { int x, y; } Point;
// initialize point object
Point pt = { 0, 5 };
// declare pointer
Point pt_ptr = &pt;
// access elements
(*pt_ptr).x = (*pt_ptr).y;
// but alternative syntax is cooler
pp->x = pp->y;
\end{minted}
\subsection{Pointers as function arguments}
\begin{minted}{c}
void f(int x, int *p) {
// does nothing outside
x = 5;
// changes outside!!
*p = -9;
}
// e.g.
int a = 1, b = -3;
f(a, &b);
// now a = 1 but b = -9.
\end{minted}
\section{Arrays}
\begin{itemize}
\item To allocate:
\begin{minted}[autogobble]{c}
// allocate space
// unknown content
int a[5];
// can also initialize at the same time
int b = { 3, 2, 1 };
\end{minted}
\item Array elements are matched sequentially in memory.
\item C doesn't check array bounds; if you read too far you'll get junk.
\item Define array size using a constant! (not a literal)
\begin{itemize}
\item Bad:
\begin{minted}[autogobble]{c}
int i, ar[10];
for(i = 0; i < 10; i++);
\end{minted}
\item Good:
\begin{minted}[autogobble]{c}
const int ARRAY_SIZE;
int i, ar[ARRAY_SIZE];
for(i = 0; i < ARRAY_SIZE; i++);
\end{minted}
\end{itemize}
\item \texttt{sizeof} works on bounds!
\begin{minted}[autogobble]{c}
int array[5];
// evaluates to 20:
sizeof(array);
\end{minted}
but can be awkward on a \texttt{struct} because of padding:
\begin{minted}[autogobble]{c}
// should take up 2 + 2 bytes right???
struct { short a; char c; } s;
// evaluates to 4!
sizeof(s);
\end{minted}
\end{itemize}
\section{Pointer arithmetic}
\subsection{\texttt{char} example}
\begin{minted}{c}
#include <stdio.h>
int main(void) {
char c[] = { 'a', 'b' };
// c[] already is a pointer! (char[] = char*)
char *pc = c;
// advance pc to the next location in the array
pc++;
/*
(pc - c) is 1.
*/
int i[] = { 10, 20 };
int *pi = i;
pi++;
/*
(pi - i) is 4.
*/
}
\end{minted}
Pointer value is in bytes, but pointer arithmetic is in units of \texttt{sizeof(pointed\_to\_type)}.
\subsection{Array name/pointer duality}
\texttt{char *pstr} and \texttt{char astr[]} are about the same, except \texttt{astr++} is illegal (as though it were constant).
The reason you can't mutate the array reference variable is that it's not a ``real'' variable but just a compiler name.
\subsection{Arrays as arguments}
\emph{An array is always passed as a pointer!} You need to pass in the size of the array, as \texttt{sizeof} will just evaluate to the size of the pointer representation (e.g.~32/64 bits).