- •1 Понятие алгоритма формы представления алгоритмов
- •2 Линейные и разветвляющиеся алгоритмы.
- •3 Циклические алгоритмы
- •4 Понятие прикладного и системного программирования
- •5 Структура программ на языке си
- •6 Арифметико-логические операции над переменными
- •Арифметические операции
- •Операции увеличения и уменьшения
- •Операции "увеличить на", "домножить на" и т.П.
- •Логические операции
- •Операции сравнения
- •Побитовые логические операции
- •7 Два вида оператора выбора Оператор if
- •8 Понятие цикла
- •1.4.6. Оператор break
- •1.4.7. Оператор for
- •1.4.8. Оператор while
- •1.4.9. Оператор do while
- •1.4.10. Оператор continue
- •1.4.11. Оператор return
- •9 Массив
- •12 Указатели
- •13 Адресная арифметика
- •14 Операции над указателями
- •15 Массивы указателей
- •16 Указатели на функции Указатели на функции
- •17 Структуры
- •18 Доступ к элементам структуры
- •19 Структуры как аргументы
- •6.2. Структуры и функции
- •20 Динамические структуры на массиве
- •21 Динамическое распределение памяти Функции динамического распределения
- •Динамическое выделение памяти для массивов
- •23 Организация доступа к файлам
- •Закрытие потока при помощи fclose
- •Чтение из потока при помощи fgetc
- •«Ловушка» eof
- •При помощи fgets
- •24 Форматированный ввод –вывод Функции форматированного ввода и вывода в си
- •Спецификатор типа
- •Спецификатор типа
- •25 Верификация тестирование отладка программ
- •Введение
- •26 Причины и последствия появления ошибок
- •27 Идея модульного программирования
- •28 Технология проектирования сверху-вниз
- •29 Итерация рекурсия
- •30 Методы сортировки
- •34 Способы защиты информации
Динамическое выделение памяти для массивов
Довольно часто возникает необходимость выделить память динамически, используя malloc(), но работать с этой памятью удобнее так, будто это массив, который можно индексировать. В этом случае нужно создать динамический массив. Сделать это несложно, потому что каждый указатель можно индексировать как массив. В следующем примере одномерный динамический массив содержит строку:
/* Динамическое распределение строки, строка вводится
пользователем, а затем распечатывается справа налево. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char *s;
register int t;
s = malloc(80);
if(!s) {
printf("Требуемая память не выделена.\n");
exit(1);
}
gets(s);
for(t=strlen(s)-1; t>=0; t--) putchar(s[t]);
free(s);
return 0;
}
Перед первым использованием s программа проверяет, успешно ли прошло выделение памяти. Эта проверка необходима для предотвращения случайного использования нулевого указателя. Обратите внимание на то, что указатель s используется в функции gets(), а также при выводе на экран (но на этот раз уже как обыкновенный массив).
Можно также динамически выделить память для многомерного массива. Для этого нужно объявить указатель, определяющий все, кроме самого левого измерения массива. В следующем примере[2] двухмерный динамический массив содержит таблицу чисел от 1 до 10 в степенях 1, 2, 3 и 4.
#include <stdio.h>
#include <stdlib.h>
int pwr(int a, int b);
int main(void)
{
/* Объявление указателя на массив из 10 строк
в которых хранятсяцелые числа (int). */
int (*p)[10];
register int i, j;
/* выделение памяти для массива 4 x 10 */
p = malloc(40*sizeof(int));
if(!p) {
printf("Требуемая память не выделена.\n");
exit(1);
}
for(j=1; j<11; j++)
for(i=1; i<5; i++) p[i-1][j-1] = pwr(j, i);
for(j=1; j<11; j++) {
for(i=1; i<5; i++) printf("%10d ", p[i-1][j-1]);
printf("\n");
}
return 0;
}
/* Возведение чисел в степень. */
pwr(int a, int b)
{
register int t=1;
for(; b; b--) t = t*a;
return t;
}
Программа выводит на экран следующее:
1 1 1 1
2 4 8 16
3 9 27 81
4 16 64 256
5 25 125 625
6 36 216 1296
7 49 343 2401
8 64 512 4096
9 81 729 6561
10 100 1000 10000
Указатель р в главной программе (main()) объявлен как
int (*p)[10]
Следует отметить, что скобки вокруг *р обязательны. Такое объявление означает, что р указывает на массив из 10 целых. Если увеличить указатель р на 1, то он будет указывать на следующие 10 целых чисел. Таким образом, р — это указатель на двухмерный массив с 10 числами в каждой строке. Поэтому р можно индексировать как обычный двухмерный массив. Разница только в том, что здесь память выделена с помощью malloc(), а для обыкновенного массива память выделяет компилятор.
Как упоминалось ранее, в C++ нужно преобразовывать типы указателей явно. Поэтому чтобы данная программа была правильной и в С, и в C++, необходимо выполнить явное приведение типа значения, возвращаемого функцией malloc(). Для этого строчку, в которой указателю р присваивается это значение, нужно переписать следующим образом: