Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
1. История развития средств вычислительной техники.
1642 Блез Паскаль изобрёл первое механическое устройство для счёта (36*13*8 см).
1672 Готтвит Вильгельм-Лейбниц вычислил идею механического умножения без последовательного действия. Через год создал машину, которая выполняла 4 арифметические операции.
1818 Карл Томас создал арифмометр.
1822 Чарльз Бэббидж создал первую разностную машину.
1883 Томас Эдисон изобрёл электрическую лампу.
1904 создание первого диода.
1941 изобретение электромагнитного реле. На этой основе Конрад Цудзе построил вычислительную машину.
1943 фирма IBM создала вычислительные машины MARK1 и MARK2.
2. Структурная схема вычислительных устройств по архитектуре фон Неймана.
передача данных, передача адресов
Требования в структуре компьютеров по схеме фон Неймана:
Принцип работы:
3. Этапы развития ЭВМ.
4. Теория алгоритмов. Понятие алгоритма и его свойства.
Программы, написанные на любом языке программирования, предназначены для решения определённых задач с помощью компьютера, а решение задач основывается на алгоритме.
Начальным этапом разработки любой программы является составление схемы решения поставленной задачи. После этого составляется алгоритм - дополнение на выбранном языке программирования, т. е. создаётся программная реализация данного алгоритма.
Алгоритм точное предписание, определяющее последовательность действий, обеспечивающее получение требуемого результата из исходных данных за конечное время.
Алгоритм должен обладать следующими свойствами:
5. Теория алгоритмов. Основные этапы алгоритмизации (здесь же, в 3-м этапе алгоритмизации, «6. Теория алгоритмов. Способы представления алгоритмов»).
Алгоритмизация процесс создания алгоритма решения задач. Состоит из следующих этапов:
7. Теория алгоритмов. Схема алгоритма.
Правильное оформление схем алгоритма:
ГОСТ 10.701-90 «Схема алгоритмов программ, данных и систем, условные обозначения и правила выполнения». Согласно ему все схемы алгоритмов состоят из:
Предопределённые символы:
Схема графическое представление метода решения задачи, в котором используются графические фигуры для отображения операций, данных, каких-либо действий.
Описание символов схем алгоритма
a = 10, 15, 20, 25, …
b = 1,5 а
Основные символы данных:
Специальные символы:
8. Алгоритмический язык Си и его особенности.
Достоинства и особенности языка Си:
9. Алфавит и зарезервированные слова языка Си.
Алфавит языка Си.
Множество символов языка Си можно разделить на 4 группы:
Зарезервированные слова имена директив, функций, типов данных, операторов, констант.
10. Идентификаторы и правила их написания на языке Си.
Идентификаторы:
Идентификатор имя, которым обозначается некоторый объект в программе.
Для записи идентификатора используются буквы латинского алфавита, цифры и знак подчёркивания (!но начинаться могут только с букв или знак подчёркивания). Идентификатор может состоять из неограниченного кол-ва символов из которых воспринимаются и используются только первые 32 символа.
11. Константы и переменные в языке Си.
Переменные элементы данных, значение которых могут изменяться в программе. Неизменяемые данные константы. В программе все данные должны быть объявлены или определены.
Отличие объявления от определения заключается в том, что при объявлении переменной место её в памяти соответствующей функцией не выделяется, объявление лишь сообщает калькулятору тип переменных; чтобы определить переменную, необходимо
[спецификатор_класса_памяти] спецификатор_типа идентификатор
[ = начальное значение] [идентификатор [ = начальное значение] ]
int a, b, c
int a = 2, b = 3
int a = b = 4
Спецификатор типа определяет тип переменной. Спецификаторы класса памяти:
auto, register, extern, static
12. Типы данных языка Си. Целочисленный, вещественный и символьный типы данных языка Си.
Типы данных
Следует различать тип данных и модификатор типа.
Базовые типы данных:
К модификаторам относятся:
Они определяют формат хранения данных в ОЗУ; диапазон значений, в пределах которого может изменяться переменная; операции, которые могут выполняться над данными соответствующего типа.
Типы данных:
Тип |
Синоним |
Размер в байтах |
Диапазон значений |
signed char |
char |
1 |
-128 … 127 |
unsigned char |
char |
1 |
0 … 255 |
signed int |
signed, int |
2* |
-32 768 … 32 767 |
unsigned int |
unsigned |
2* |
0 … 65 535 |
signed short int |
short, signed short |
2 |
-32 768 … 32 767 |
unsigned short int |
unsigned short |
2 |
0 … 65 535 |
signed long int |
long, signed long |
4 |
-2 147 483 648 … 2 147 483 647 |
unsigned long int |
unsigned long |
4 |
0 … 4 294 967 295 |
float |
7 знаков |
4 |
1,17 Е-38 … 3,37 Е+38 |
double |
15 знаков |
8 |
2,23 Е-308 … 1,67 Е+308 |
long double |
19 знаков |
10 |
3,37 Е-4932 … 1,2 Е+4932 |
* - В ОС Windows Vista эти типы данных имеют размер 4 байта.
Символьный тип данных
Данные типа char занимают в памяти 1 байт. Код от 0 до 255 в этом байте задает один из 256 возможных символов. Закрепление конкретных символов за кодами задается кодовыми таблицами. В операционной системе DOS используется кодовая таблица ASCII.
char s = a
0 < 1 < 2 < … < 9
A < B < … < Z
a < b < … < z
\n переход на новую строку
\t горизонтальная табуляция
\v вертикальная табуляция
\b перевод курсора влево на одну позицию
\r возврат каретки (возврат курсора в начало строки)
\f новая страница
\a кратковременная подача звукового сигнала
\ вывод на экран кавычек
\” вывод на экран кавычек
\\ вывод на экран bslash
/*Совместимость типов
Если в выражениях встречаются операнды различных типов, то они преобразуются к общему типу в соответствии со следующим набором правил.
(имя типа) выражение */
/*Стандартная математическая библиотека функций
Стандартная математическая библиотека Си включает набор функций, выполняющих элементарные математические операции. Библиотека подключается в самом начале текста программы с помощью заголовочного файла math.h:
#include <math.h>
Большая часть функций работает с типом double. Это значит, что они корректно работают и с типом float. Однако использование данных типа long double совместно с функциями математической библиотеки не допускается, так как в большинстве случаев приводит к ошибкам.
Наиболее часто употребляемые функции перечислены ниже.
Кроме перечисленных функций в Си доступны обычные арифметические операторы: сложения «+», вычитания «-», умножения «*», деления «/», получение остатка от деления нацело «%». */
13. Структура программы на языке Си.
# include <stdio.h> /* подключение библиотеки стандартного ввода-вывода */
# include <math.h> /* подключение библиотеки стандартных математических функций */
# define N 9 /* определение констант */
int Sq (int a) /* прототип функции */
main () /* главная функция */
{ int b; /* объявление переменных */
b = Sq (N); /* операции */
printf (“b = %d”, b);
}
int Sq (int a)
{ /* тело функции Sq */
return a * a
}
14. Понятие операции. Арифметические и поразрядные операции.
Все операции в Си делятся на:
Арифметические:
Поразрядные:
15. Понятие операции. Логические операции и операции отношения.
>, <, >=, <=, = =, !=; <<, >>.
16. Понятие операции. Тернарная операция и операция приведения типов.
Тернарная операция
(Выражение_1) ? (Выражение_2) : (Выражение_3)
Если «Выражение_1» истинно, то выполняется «Выражение_2», иначе выполняется «Выражение_3».
Пример
m = 2 n = 3 int a
a = (m = = n) ? (m + n) : (m - n) // -1
(m > n) ? (a = m) : (a = n)
a = (m > n) ? m : n
&& логическое и; || логическое или
a = (m > n) ? (n && (b = m)) : m
Операции преобразования типа
a = 1,6
b = 1,7
int m
m = a + b, // 3 m = 1,6 + 1,7 = 3,3
m = (int) a + (int) b, // 2 m = 1,6 + 1,7 = 2
17. Понятие операции. Операции “&” и “*” и их использование.
y = &x переменной y присваивается адрес переменной x (можно применять только к переменным и к элементам массивов).
* воспринимает операнд как адрес некоторого объекта и использует этот адрес для выборки содержимого по этому адресу.
z = *y переменной z присваивается значение, расположенное по адресу y.
Так как все переменные перед их использованием должны быть описаны, то и переменные, содержащие какой-либо адрес, должны быть описаны (эти переменные называются указателями и описываются следующим образом: int *L, float *p, char *ch, где L, p и ch указатели).
Идентификатор типа задаёт тип переменных, на которые ссылается указатель. Это необходимо, так как переменные разных типов занимают разное число ячеек в памяти, а для некоторых операций, связанных с указателями, требуется знать объём памяти, отведённый под переменную.
i указатель, *i значение, записанное по адресу i.
*i = 7 записать знак 7 по адресу i.
Указатели и целые числа можно суммировать, при этом транслятор будет масштабировать приращение адреса в соответствии с типом, определённом при описании указателя. Это позволяет задавать адрес n-ого объекта, на который указывает указатель.
int * i, n
i + = n
18. Понятие операции. Приоритетность операций в языке Си.
Операция |
Вид операции |
Порядок выполнения |
() [] . |
операции выражения |
|
- ~ ! * & ++ -- sizeof (тип) |
унарные |
|
* / % |
мультипликативные |
|
+ - |
аддитивные |
|
<< >> |
сдвиг |
|
< > <= >= |
операции отношения |
|
= = != |
то же, но с меньшим приоритетом |
|
& |
побитовое “И” |
|
^ |
побитовое исключающее “ИЛИ” |
|
| |
побитовое включающее “ИЛИ” |
|
&& |
логическое “И” |
|
|| |
логическое “ИЛИ” |
|
? : |
условные |
|
= *= /= %= += -= <<= >>= &= != ^= |
простое и составное присваивание |
|
, |
последовательное преобразование |
|
19. Организация ввода/вывода в языке Си. Функция scanf(). Спецификации и символьные константы.
Функции ввода-вывода. Формат преобразования данных.
Библиотека <stdio.h>
char *gets (char*buffer) считывает символьную строку стандартного входного потока и помещает её по адресу, заданному указателем buffer; приём строки заканчивается, если функция обнаруживает символ конца строки \n, данный символ удаляется и заменяется нуль-терминатором \0, функция возвращается на считанную строку.
int getchar (void)
int puts (const char + string)
int putchar (int char or other)
scanf ("управляющая строка", &аргумент1, &аргумент2, ...)
% [ширина] [точность] формат
Аргументы scanf должны быть указателями на соответствующие значения (перед именем переменной записывается символ &). Символ & перед именем переменной воспринимается как адрес ячейки, где содержится значение этой переменной.
"Управляющая строка" содержит спецификации преобразования и используется для установления количества и типа аргументов. В нее могут включаться: пробелы, символы табуляции и перехода на новую строку (все они игнорируются); спецификации преобразования, состоящие из знака %, возможно символа * (запрещение присваивания), возможно числа, задающего максимальный размер поля, и самого преобразования; обычные символы, кроме %.
Каждая спецификация преобразования начинается со знака % и заканчивается некоторым символом, задающим преобразования. Между знаком % и символом преобразования могут встречаться знаки: ЗНАК МИНУС, указывающий, что преобразованный параметр должен быть выровнен влево в своем поле; СТРОКА ЦИФР, задающая максимальный размер поля; ТОЧКА, отделяющая размер поля от последующей строки цифр; СТРОКА ЦИФР, задающая максимальное число символов, которые нужно вывести, или же количество цифр, которые нужно вывести справа от десятичной точки в значениях типов float или double; СИМВОЛ ДИЛИНЫ l, указывающий, что соответствующий аргумент имеет тип long.
Если после знака % записан не символ преобразования, то он выводится на экран.
В функции scanf допустимы многие из символов преобразования функции printf. Например:
Перед символами d,o,x,f может стоять буква l. В первых трех случаях соответствующие переменные должны иметь тип long, а в последнем - double.
После выполнения функции scanf осуществляется автоматический перевод курсора на следующую строку.
20. Организация ввода/вывода в языке Си. Функция printf(). Спецификации и символьные константы.
printf ("управляющая строка", аргумент1, аргумент2, ...)
"Управляющая строка" содержит объекты трех типов: обычные символы, которые просто выводятся на экран дисплея; спецификации преобразования, каждая из которых вызывает вывод на экран значения очередного аргумента из последующего списка, и управляющие символьные константы. Функция printf использует управляющую строку, чтобы определить, сколько всего аргументов и каковы их типы (аргументами могут быть переменные, константы, выражения, вызовы функции; главное, чтобы их значения соответствовали заданной спецификации).
(кол-во аргументов равно кол-ву знаков % в управляющей строке)
% [флаг] [ширина] [точность] [модификатор типа] формат
Символы преобразования:
Среди управляющих символьных констант наиболее часто используют следующие: \a, \b, \n, \r, \t, \v.
21. Операторы языка Си. Условный оператор if…else.
Операторы в Си делятся на 4 группы:
Условный оператор if предназначен для организации выполнения какого-либо действия в зависимости от выполнения поставленного условия.
if (условие)
{действие 1; …};
else {действие 2; …};
Пример:
if (d = = 1)
{ if (r = = 5) b = 2;};
else b = 3;
if (d = = 1 && r = = 5) b = 2
22. Операторы языка Си. Оператор выбора switch.
switch (выражение)
{
case const 1: оператор 1; break;
case const 2: оператор 2; break;
.......................................................
case const n: оператор n; break;
default: оператор n+1; break;
}
int n
scanf (“%d”,&n);
switch (n)
{ case 1: printf ("Первый"); break;
case 2: printf ("Второй"); break;
default: printf ("Нет"); break; }
char znak
znak='*';
switch (znak)
{ case '+': y=a+b; break;
case '-': y=a-b; break;
case '*': y=a*b; break;
case '/': y=a/b; break;
case '%': y=a%b; break;
default: printf ("Не верно"); break; }
23. Операторы языка Си. Оператор организации циклов for.
for (инициализация; условие; изменение параметров) {тело цикла;}
Очерёдность выполнения этого оператора:
!Оператор for является циклом с предусловием (решение, выполнить в очередной раз тело цикла или нет, принимается до начала его прохождения).
int i, n, fact
scanf (“%d”,&n);
for (i = 1; i <= n; i ++)
fact *= i;
printf ("%d", fact);
i = 1;
while (i <= n)
{ fact *= i;
i ++; }
24. Операторы языка Си. Операторы организации циклов while, do…while.
while (условие) {тело цикла;}
! Цикл с предусловием
do {тело цикла;} while (условие)
do { fact *= i;
i ++; }
while (i <= n)
25. Операторы языка Си. Операторы переходов break, continue, return, goto.
int surn = 0;
int i;
for (i = 1; i <= 10; i ++)
{ surn + = i;
if (i = = 5) goto metka;
}
printf ("Вывод");
metka;
printf ("%d", surn);
26. Понятие массива данных. Объявление и инициализация массивов. Одномерные массивы.
Массив группа элементов одного типа, расположенных друг за другом в памяти и имеющих одно общее имя.
Индекс порядковый номер элемента в массиве (индекс первого элемента всегда равен нулю).
int mas [n]
(если [], то массив будет работать)
size = sizeof (array)
for (i = 0; i < 4; i ++)
scanf (“%d”, & array [i])
Пример: дан массив из 4-х элементов. Если элемент массива является чётным, поменять его знак.
int array [4] = {3, 6, 7, 12};
for (i = 0; i < 4; i ++)
if (array [i]%2 = 0)
array [i] *= (-1)
27. Понятие массива данных. Многомерные массивы.
0 1 2 int m [] [3] = {{0}, {10, 11}, {20, 21, 22}}
10 11 12
20 21 22
for (i = 0, i < 3, i ++)
for (j = 0, j < 3, j ++)
scanf (“%d”, &m [i] [j]);
28. Понятие указателя в языке Си. Операции над указателями.
Указатель особый вид переменной, которая хранит адрес элемента в памяти, где может быть записано значение другой переменной.
тип *имя_указателя
int variable, *point
Операции с указателями:
int *p, a;
a = 18
p = &a
*p += 8 // 26
int i, *p;
p + i // указатель на адрес i-того элемента после данного
p - i // указатель на адрес i-того элемента перед данным
29. Строковые литералы и организация строк в Си.
Строковый литерал последовательность любых символов, заключенных в парные двойные кавычки. В Си отсутствует специальный строковый тип. Вместо этого строковый литерал представляется как массив элементов типа char, в конце которого помещен символ '\0' (нуль-терминатор). Такой массив называют строкой в формате ASCIIZ или просто ASCIIZ-строкой. Как и с любым массивом символов, со строковым литералом связан указатель-константа на первый элемент массива.
str = "строка"
scanf(“%s”, &str);
gets (str);
30. Стандартная библиотека работы со строками в Си (не менее 5 функций).
Библиотека <string.h>
Пример: ввести символьную строку и удалить все буквы, входящие в первое слово. «Пока падает снег».
# include <stdio.h>
# include <string.h>
main()
{
char *str, *ch, p
int i, j, dl
printf (“Введите строку”);
gets (str);
p = str [0];
dl = strlen (str);
for (i = 0; i <= dl; i ++)
{
if (p != )
{
while (ch = strchr (str, p) != NULL)
for (j = 0; j <= strlen (ch); j ++)
ch [j] = ch [j + 1];
p = str [0];
}
}
printf (“строка: %s”, str);
}
31. Директивы препроцессора Си.
1) # include включает в текст программы, содержимое указанного файла. Если имя файла задано в <>, то поиск файла производится в стандартных директориях операционной системы. Директива include может быть вложенной, т. е. во включаемом файле тоже может содержаться include.
2) # define идентификатор текст
# define идентификатор(список параметров) текст
# define WIDTH &0
# define LENGTH (WIDTH + 10)
t = LENGTH * 7
t = (WIDTH + 10) * 7
# define MAX(x, y) ((x)>(y))?(x):(y)
t = MAX(i, s[i]) // t = ((i) > (s[i]))?(i) :(s[i])
t = MAX(i & j, s[i] || j) // t = ((i&j) > (s[i] || j))?(i & j):(s[i] || j)
3) # undef
Служит для отмены действия директивы # define. Использование # undef для идентификатора, который не был определён директивой # define, не является ошибкой.
32. Командная строка. Параметры функции main().
Аргументы командной строки текст, записанный после имени запускаемого на выполнение com или exe файла, либо передаваемый программе с помощью опций интегрированный среды Си аргумент.
В качестве аргументов могут выступать имена файлов, функций; текст, задающий режим работы программы; а также сами данные.
int main (int argc, char *argv[], char *envp[])
{
}
int main (int argc, char *argv, char *envp)
{
}
Параметр argc сообщает функции кол-во передаваемых командной строке аргументов, учитывая в качестве первого аргумента имя самой выполняемой программы (кол-во параметров >= 1).
argv является указателем на массив из указателей на слова из командной строки (каждый параметр хранится в виде ASCIIZ-строки, под словом понимается любой текст, не содержащий символов “пробел” или “табуляция”; последним элементом массива указателя является нулевой NULL)
cm exe aaa ddd eee 32
cm exe \0
aaa \0
ddd \0
eee \0
32 \0
NULL
Параметр envp служит для передачи в программу информацию о системном окружении операционной системы (информация о среде, в которой выполняется программа); является указателем на массив указателей, каждый из которых определяет адрес, в котором хранится строка информации о среде, определяемой операционной системой. Также признаком конца массива является NULL-указатель.
33. Организация последовательного и бинарного поиска.
Последовательный поиск
int SeqSearch (int list[], int n, int key)
{
int i;
for (i = 0; i < n; i ++)
if (list [i] == key)
return i;
return -1;
}
main ()
{
int B [5];
a = SeqSearch (B [5], 5, 4);
}
Бинарный поиск
Применим только, если массив упорядочен по возрастанию/убыванию
if (A [mid] < key) low = mid + 1
34. Основные алгоритмы сортировки массивов. Сортировка методом пузырька.
Для сортировки массива A из n элементов требуется до n-1 проходов (прохождение всего массива один раз от первого до последнего элемента массива). В каждом проходе сравниваются соседние элементы и если первый из них больше второго, они меняются местами. К моменту окончания каждого прохода наименьший элемент поднимается к вершине текущего подсписка.
const int n = 5
int A [n], i, j, aux;
for (i = 0; i < (n-1); i ++)
for (j = 0; j < (n-1); j ++)
{
if (A [j] > A [j + 1])
{ aux = A [j];
A [j] = A [j + 1];
A [j + 1] = aux;
}
}
50 20 40 75 35
20 50 40 75 35
20 40 50 75 35
20 40 50 75 35
20 40 50 35 75
35. Основные алгоритмы сортировки массивов. Сортировка посредством выбора.
Для сортировки массива A из n элементов также требуется до n-1 проходов.
const int n = 5
int A [n], i, j, k, min;
for (i = 0; i < (n-1); i ++)
{ min = A [i];
for (j = i + 1; j < n; j ++)
{
if (A [j] < min)
{
k = j;
min = A [j];
}
}
A [k] = A [i];
A [i] = min;
}
50 20 40 75 35
20 50 40 75 35
20 35 40 75 50
20 35 40 75 50
20 35 40 50 75
36. Основные алгоритмы сортировки массивов. Сортировка методом вставки.
Для сортировки массива A из n элементов также требуется до n -1 проходов.
50 20 40 75 35
20 50 40 75 35
20 40 50 75 35
20 40 50 75 35
20 35 40 50 75
const int n = 5
int A [n], i, j, k, Aj, m;
for (i = 0; i < (n-1); i ++)
{
for (j = i +1; j < n; j ++)
{
for (k = 0; k < (i +1); k ++)
{
if (A [j] < A [k]) { Aj = A[j]
for (m = j; m > k; m--)
A [m] = A [m - 1];
A [k] = Aj; }
}
}
}
37. Основные алгоритмы сортировки массивов. Быстрая сортировка.
Функция qsort в библиотеке <stdlib.h>
Общая схема быстрой сортировки:
Достоинства этого метода:
Два недостатка:
Сортировка целочисленного массива
# include <stdio.h>
# include <stdlib.h>
# define N 1000
int cmp (const void *a, const void *b)
{
return (*(int*)a *(int*)b);
}
main ()
{
int n, i, a [N];
scanf(“%d”, &n);
for (i = 0; i < n; i ++) scanf(“%d”, &a[i]);
qsort (a, n, sizeof (int), cmp);
for (i = 0; i < n; i ++) printf(“%d”, a[i]);
}
Функция strcmp уже определена в библиотеке <string.h>
Программа упорядочивания строк в алфавитном порядке
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define N 100
# define M 30
main ()
{
int n, i;
char a [N][M];
scanf(“%d”, &n);
for (i = 0; i < n; i ++) scanf(“%s”, &a[i]);
qsort (a, n, sizeof (char [M]), (int (*)(const void*, const void*)) strcmp);
for (i = 0; i < n; i ++) printf(“%s\n”, a[i]);
}
38. Функции пользователя в Си. Функции с переменным числом аргументов.
Программы на Си обычно состоят из множества подпрограмм, называемых функциями. Функции имеют небольшой размер и могут располагаться в разных файлах. Независимо от расположения, все функции являются глобальными.
Причины использования функций:
Чтобы написать свою функцию на Си необходимо её определить или записать прототип в виде:
тип_возвращаемого_значения имя_функции (тип_входного_параметра1, тип_входного_параметра2, …);
main()
{ }
int function (int, int); // прототип int function (int a, int b); int function (int a, b, c, …);
main()
{ int a1, a2, c;
c = function (a1, a2); }
int function (int a, int b); // int function (int *a, int *b);
{ if a < b
return a;
else
return b;}
Каждая функция имеет входные параметры, которые записываются в круглых скобках после имени, и один определённый выходной параметр.
Если у функции нет выходных параметров, необходимо писать ключевое слово void.
39. Структуры в Си (здесь же «40. Структуры и указатели»).
Отличия от массива:
struct имя {тип_элемента1 имя1 ;
тип_элемента2 имя2 ;
…………………………
тип_элементаN имяN ; } ;
Примеры:
struct date {char month, day; int year ; } a, b ;
main ()
{ struct date c, d;
a. day = 5;
b. year = 1900; }
struct man { char name [20], fam [20];
struct date db;
int age; } ;
main ()
{ struct man M [100];
M [5]. name [5] = “a”;
M [10]. db. year = 2000; }
Каждая переменная нового для определённого типа struct будет занимать в памяти место, равное сумме, определённых в этой структуре переменных.
Указатели на struct:
struct date {char month, day; int year ; } *a, b ;
(*a). year = 5; ~ a year = 5;
41. Анонимное определение структуры и оператор определения типа (здесь же «40. Структуры и указатели»).
Возможно анонимное определение структуры, когда имя структуры после ключевого слова struct опускается. В этом случае список описываемых переменных должен быть непустым.
struct {
double x;
double y;} ;
typedef struct { double x; double y;} R2_point, *R2_p
R2_point t, *p;
*R2_p p;
42. Работа с памятью. Статическая память.
Выделяется до начала работы программы на стадии компиляции и сборки.
Статические переменные имеют фиксированный адрес, известный до запуска программы и не изменяющийся в процессе её работы. Статические переменные создаются и инициализируются до входа в функцию main.
Существует два типа статических переменных:
1) глобальные определены вне функций, обычно в их описании присутствует слово extern перед типом данных.
*.h
extern int N
*.c
int N
Таким образом, они доступны в любой точке программы во всех её файлах (желательно им придавать достаточно длинные имена).
2) статические также описываются перед функцией, но перед именем присутствует слово static. Присутствуют только в одном файле, в котором они определены, использовать можно только после их описания; никогда не описываются в *.h файлах.
43. Работа с памятью. Стековая или локальная память.
Локальные и стековые переменные это переменные, описанные внутри функции.
Память для таких переменных выделяется в аппаратном стеке. Память выделяется в момент входа в функцию или блок и освобождается в момент выхода из функции или блока. При этом захват и освобождение памяти происходит практически мгновенно, т. к. компьютер только изменяет регистр, содержащий адрес вершины стека.
Локальные переменные можно использовать при рекурсии, т. к. при повторном входе в функцию в стеке создаётся новый набор локальных переменных, а предыдущий набор не разрушается.
! Замечание: Всегда следует избегать использования глобальных и статических переменных, если можно обойтись локальными.
Размер аппаратного стека не бесконечен, стек может переполниться, например, при глубокой рекурсии, что приведёт к аварийному завершению программы, поэтому локальные переменные не должны быть большого размера, в том числе нельзя использовать большие массивы в качестве локальных переменных.
44. Работа с памятью. Динамическая память или «куча».
Помимо статической и стековой памяти, существует практически неограниченная память (динамическая). Программа может захватывать участки динамической памяти и использовать их. После использования, ранее захваченного участка, его следует освободить.
Динамическая память состоит из захваченных и свободных сегментов, каждому из которых предшествует описание сегмента. При выполнении запроса на захват памяти исполняющая система производит поиск свободного сегмента достаточного размера и захватывает в нём отрезок требуемой длины. При освобождении сегмента памяти он помечается как свободный. При необходимости, несколько подряд идущих свободных сегментов объединяются.
<stdlib.h> библиотека для работы с динамической памятью
Функция malloc возвращает адрес захваченного участка памяти или 0 в случае неудачи (когда памяти нет).
Для задания адреса используется указатель общего типа void *, поэтому после вызова функции malloc, его необходимо привести на определённый тип, используя операцию приведения типа.
Пример: необходимо захватить участок динамической памяти размером в 4000, его адрес присваивается указателю на 10001 целочисленных элементов.
int *a;
…
a = (int*) malloc (sizeof (int) * 1000);
…
free (a);
1 характерно для Windows XP, т. к. в этой ОС целочисленные данные занимают в памяти 4 байта.
АЛУ
УУ
ОЗУ
УВВ
0,25a
стековая max
динамическая
a
bb
a
a
R
R
bb
a
a
0,15a
0,15a
R
0,5a
a
статическая
R
bb
bb
0,75a
a
R = a
R
0,15a
R
bb
R = a
bb
a
a
bb
a
a
a
a
b
R = 0,5 a
R
R
b
R2.point
необязательно
t, *p
обязательно
low
указатели на struct
mid
high
0
n-1
i+1
0
j
i
k
n-1
bb