диаграмма указателей

This commit is contained in:
Ivan I. Ovchinnikov 2021-09-06 15:49:23 +03:00
parent 9392a69490
commit 9f297d50bd
6 changed files with 39 additions and 41 deletions

Binary file not shown.

View File

@ -12,6 +12,7 @@
\usepackage{layout} \usepackage{layout}
\usepackage{titlesec} \usepackage{titlesec}
\usepackage{hyperref} \usepackage{hyperref}
\usepackage{tikz}
\usepackage[lmargin=1.5cm,rmargin=2.5cm,tmargin=2.5cm,bmargin=2.5cm,paperheight=240mm,paperwidth=170mm]{geometry} \usepackage[lmargin=1.5cm,rmargin=2.5cm,tmargin=2.5cm,bmargin=2.5cm,paperheight=240mm,paperwidth=170mm]{geometry}
\definecolor{codekeywords}{rgb}{0.1,0.3,0.3} \definecolor{codekeywords}{rgb}{0.1,0.3,0.3}

View File

@ -91,7 +91,7 @@
printf("lets see whats in 0-th element: %d", a) printf("lets see whats in 0-th element: %d", a)
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
% При помощи массивов решают множество задач, таких как поиск, сортировка, составление таблиц соответствия, создание частотных диаграмм. На основе массивов создают более сложные структуры данных. Для примера давайте напишем программу, которая будет печатать наш массив в консоль. При помощи массивов решают множество задач, таких как поиск, сортировка, составление таблиц соответствия, создание частотных диаграмм. На основе массивов создают более сложные структуры данных. Для короткого минимального примера, давайте напишем программу, которая будет печатать наш массив в консоль.
% #include <stdio.h> % #include <stdio.h>
% int main( int argc, char *argv[]) % int main( int argc, char *argv[])

View File

@ -1,44 +1,35 @@
\tikzset{every picture/.style={line width=0.75pt}} %set default line width to 0.75pt \tikzset{every picture/.style={line width=0.75pt}} %set default line width to 0.75pt
\usetikzlibrary{arrows.meta}
\begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1] \begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1]
%uncomment if require: \path (0,460); %set diagram left start at 0, and has height of 460 %uncomment if require: \path (0,460); %set diagram left start at 0, and has height of 460
%Shape: Rectangle [id:dp48909031690071814] % rect val
\draw (40,150) -- (199,150) -- (199,220.5) -- (40,220.5) -- cycle ; \draw (40, 150) -- (200, 150) -- (200, 220) -- (40, 220) -- cycle ;
%Shape: Rectangle [id:dp3254956575959984] % rect var
\draw (222,60) -- (381,60) -- (381,130.5) -- (222,130.5) -- cycle ; \draw (220, 60) -- (380, 60) -- (380, 130) -- (220, 130) -- cycle ;
%Shape: Rectangle [id:dp8271767901522998] % rect addr
\draw (401,151) -- (560,151) -- (560,221.5) -- (401,221.5) -- cycle ; \draw (400, 150) -- (560, 150) -- (560, 220) -- (400, 220) -- cycle ;
%Shape: Rectangle [id:dp7663103953587053] % rect ptr
\draw (220,240) -- (379,240) -- (379,310.5) -- (220,310.5) -- cycle ; \draw (220, 240) -- (380, 240) -- (380, 310) -- (220, 310) -- cycle ;
%Curve Lines [id:da5551761286150834]
\draw (383,91) .. controls (420.81,62.64) and (422.98,61.51) .. (490.97,150.16) ;
\draw [shift={(492,151.5)}, rotate = 232.52] [color={rgb, 255:red, 0; green, 0; blue, 0 } ][line width=0.75] (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29) ;
%Curve Lines [id:da7602593545992278]
\draw (490,223) .. controls (553.36,260.13) and (430.5,280.1) .. (382.43,290.2) ;
\draw [shift={(381,290.5)}, rotate = 347.99] [color={rgb, 255:red, 0; green, 0; blue, 0 } ][line width=0.75] (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29) ;
%Curve Lines [id:da0637330676841148]
\draw (221,279) .. controls (188.16,311.34) and (187.01,308.53) .. (113.12,223.78) ;
\draw [shift={(112,222.5)}, rotate = 408.90999999999997] [color={rgb, 255:red, 0; green, 0; blue, 0 } ][line width=0.75] (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29) ;
%Curve Lines [id:da9922300811837096]
\draw (121,152) .. controls (86,85.5) and (85,83.5) .. (223,90.5) ;
\draw [shift={(223,90.5)}, rotate = 182.9] [color={rgb, 255:red, 0; green, 0; blue, 0 } ][line width=0.75] (10.93,-3.29) .. controls (6.95,-1.4) and (3.31,-0.3) .. (0,0) .. controls (3.31,0.3) and (6.95,1.4) .. (10.93,3.29) ;
% Text Node % Arrow var-addr
\draw (49,155) node [anchor=north west][inner sep=0.75pt] [align=left] {Значение}; \draw [-{To[width=3mm, length=5mm]}] (380, 95) -- (480, 150) ;
% Text Node % Arrow addr-ptr
\draw (231,69) node [anchor=north west][inner sep=0.75pt] [align=left] {Переменная \\(идентификатор)}; \draw [-{To[width=3mm, length=5mm]}] (480, 220) -- (380, 275);
% Text Node % Arrow ptr-val
\draw (413,162) node [anchor=north west][inner sep=0.75pt] [align=left] {Адрес}; \draw [{To[width=3mm, length=5mm]}-{To[width=3mm, length=5mm]}] (220, 275) -- (120, 220);
% Text Node % Arrow val-var
\draw (236,251) node [anchor=north west][inner sep=0.75pt] [align=left] {Указатель}; \draw [{To[width=3mm, length=5mm]}-{To[width=3mm, length=5mm]}] (120, 150) -- (220, 95);
% Text Node % Arrow ptr-var
\draw (457,68) node [anchor=north west][inner sep=0.75pt] [align=left] {Хранится по}; \draw [dotted,-{To[width=3mm, length=5mm]}] (300, 240) -- (300, 130);
% Text Node
\draw (470,272) node [anchor=north west][inner sep=0.75pt] [align=left] {Сохраняется в};
% Text Node
\draw (88,66) node [anchor=north west][inner sep=0.75pt] [align=left] {Получается по};
% Text Node
\draw (65,299) node [anchor=north west][inner sep=0.75pt] [align=left] {Разыменовывается};
\draw (440,80) node [anchor=north west][inner sep=0.75pt] [align=left] {Хранит своё\\значение по};
\draw (55,160) node [anchor=north west][inner sep=0.75pt] [align=left] {Значение переменной};
\draw (250,75) node [anchor=north west][inner sep=0.75pt] [align=left] {Переменная \\(идентификатор)};
\draw (450,165) node [anchor=north west][inner sep=0.75pt] [align=left] {Адрес};
\draw (260,250) node [anchor=north west][inner sep=0.75pt] [align=left] {Указатель};
\draw (440,270) node [anchor=north west][inner sep=0.75pt] [align=left] {Сохраняется в};
\draw (100,70) node [anchor=north west][inner sep=0.75pt] [align=left] {Простое чтение\\и/или запись};
\draw (65,255) node [anchor=north west][inner sep=0.75pt] [align=left] {Разыменование\\(как для чтения, так\\и для записи)};
\draw (250,160) node [anchor=north west][inner sep=0.75pt] [align=left] {тоже переменная\\поэтому для него\\тоже создаётся\\идентификатор};
\end{tikzpicture} \end{tikzpicture}

View File

@ -73,7 +73,7 @@ $
\end{verbatim} \end{verbatim}
\end{figure} \end{figure}
\label{text:pointers} \label{text:pointers}
\paragraph{Тип данных - указатель.} Как было сказано - переменная это именованный контейнер. У каждого такого контейнера есть свой собственный адрес в оперативной памяти. Язык С позволяет узнать этот адрес и работать с ним. Оператор взятия адреса это знак амперсанд (\&), написанный перед именем переменной. То есть у любой переменной всегда есть значение и адрес где это значение хранится. Для вывода в консоль адреса используется специальный заполнитель - \code{\%p}. \paragraph{Тип данных - указатель.} Как было сказано - переменная это именованный контейнер. У каждого такого контейнера есть свой собственный адрес в оперативной памяти. Язык С позволяет узнать этот адрес и работать с ним. Оператор взятия адреса это знак амперсанд (\&), написанный перед именем переменной. То есть у любой переменной всегда есть значение и адрес где это значение хранится (немного подробнее на стр. \pageref{fig:dereference}). Для вывода в консоль адреса используется специальный заполнитель - \code{\%p}.
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[language=C,style=CCodeStyle] \begin{lstlisting}[language=C,style=CCodeStyle]

View File

@ -31,7 +31,13 @@ value of 'pointer' is 6422044
address of 'pointer' is 000000000061FE10 address of 'pointer' is 000000000061FE10
value of 'pointer' is 000000000061FE1C value of 'pointer' is 000000000061FE1C
\end{verbatim} \end{verbatim}
В общем-то, пока что ничего необычного, все эти операции мы выполняли на предыдущих уроках. Но поскольку \code{pointer} это немного необычная переменная, а указатель, то мы можем получить не только её значение, но и \textit{значение переменной, на которую она указывает}, именно этот процесс называется разыменованием указателя. Давайте запишем, вывести в консоль <<переменная pointer указывает на такое-то значение>> и разыменуем \code{pointer}. То есть получим доступ к значению переменной, на которую ссылается указатель \code{pointer}. В общем-то, пока что ничего необычного, все эти операции мы выполняли на предыдущих уроках. Но поскольку \code{pointer} это немного необычная переменная, а указатель, то мы можем получить не только её значение, но и \textit{значение переменной, на которую она указывает}, именно этот процесс называется разыменованием указателя.
\begin{figure}[h!]
\include{schemes/pointer.tex}
\caption{Отношения указателей, адресов, идентификаторов и значений}
\label{fig:dereference}
\end{figure}
Давайте запишем, вывести в консоль <<переменная pointer указывает на такое-то значение>> и разыменуем \code{pointer}. То есть получим доступ к значению переменной, на которую ссылается указатель \code{pointer}.
\begin{lstlisting}[language=C,style=CCodeStyle] \begin{lstlisting}[language=C,style=CCodeStyle]
printf("variable 'pointer' points at: %d", *pointer); printf("variable 'pointer' points at: %d", *pointer);
\end{lstlisting} \end{lstlisting}
@ -51,4 +57,4 @@ value of 'pointer' is 000000000061FE1C
\columnbreak \columnbreak
\lstinputlisting[language=C,style=CCodeStyle]{../sources/swapprog.c} \lstinputlisting[language=C,style=CCodeStyle]{../sources/swapprog.c}
\end{multicols} \end{multicols}
Применение такого подхода открывает перед нами широкие возможности, некоторые из них мы рассмотрим в следующих разделах. Применение такого подхода открывает перед нами широкие возможности. Ванжо, на схеме со стр. \pageref{fig:dereference}, что указатель - это тоже переменная, поэтому мы можем создавать указатели на указатели, и так далее любой сложности.