Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Электронный конспект по программированию часть 1.doc
Скачиваний:
131
Добавлен:
13.02.2016
Размер:
33.92 Mб
Скачать

Void SortStrings ( char *s[], int n ) // *s[] – массивуказателей

{ // n – число строк

char *p;

int i, j;

for ( i = 0; i < n-1; i ++ )

for ( j = n-1; j > i; j -- )

if ( strcmp(s[j-1],s[j]) > 0 ) {

p = s[j]; s[j] = s[j-1]; // перестановка УКАЗАТЕЛЕЙ

s[j-1] = p;

}

}

Эту функцию использует приведенная ниже программа, которая сортирует строки и выводит их на экран уже в алфавитном порядке.

main()

{

char s[20][80]; // массив из 20 строк

char *ps[20]; // массив из 20 указателей на строки

Int I, count;

// здесь нужно ввести строки и записать

// в переменную count их количество

for ( i = 0; i < count; i ++ ) // расставитьуказатели

ps[i] = s[i];

SortStrings ( ps, count ); // сортировкауказателей

for ( i = 0; i < count; i ++ )

puts ( ps[i] ); // вывод через указатели

}

5. Управление памятью

Указатели

Рассмотрим такую задачу: в файле записаны целые числа. Надо отсортировать их и записать в другой файл. Проблема заключается в том, что заранее неизвестно, сколько в файле таких чисел. В такой ситуации есть два варианта:

1. Выделить память с запасом, если известно, например, что этих чисел гарантированно не

более 1000.

2. Использовать динамическое выделение памяти – сначала определить, сколько чисел в

массиве, а потом выделить ровно столько памяти, сколько нужно.

Наиболее грамотным решением является второй вариант (использование динамических массивов). Для этого надо сначала поближе познакомиться с указателями.

Указатель – это переменная, в которой хранится адрес другой переменной или участка памяти.Указатели являются одним из основных понятий языка Си. В такие переменные можно записывать адреса любых участков памяти, на чаще всего – адрес начального элемента динамического массива. Что же можно делать с указателями?

Итак, что надо знать про указатели:

• указатель – это переменная, в которой записан адрес другой переменной;

• при объявлении указателя надо указать тип переменных, на которых он будет указывать, а

перед именем поставить знак *;

• знак &перед именем переменной обозначает ее адрес;

• знак * перед указателем в рабочей части программы (не в объявлении) обозначает значение ячейки, на которую указывает указатель;

• нельзя записывать по указателю, который указывает непонятно куда – это вызывает сбой

программы, поскольку что-то стирается в памяти;

• для обозначения недействительного указателя используется константа NULL;

• при изменении значения указателя на n он в самом деле сдвигается к n-ому следующему числу данного типа, то есть для указателей на целые числа на n*sizeof(int) байт;

• указатель печатаются по формату %p.

Теперь вам должно быть понятно, что многие функции ввода типа scanf и fscanf в самом

деле принимают в параметрах адреса переменных, например

scanf ( "%d", &i);

Динамическое выделение памяти

Динамическими называются массивы, размер которых неизвестен на этапе написания

программы. Прием, о котором мы будем говорить, относится уже не к стандартному языку Си, а к его расширению Си ++. Существуют и стандартные способы выделения памяти в языке Си(с помощью функций malloc и calloc), но они не очень удобны.

Следующая простейшая программа, которая использует динамический массив, вводит с

клавиатуры размер массива, все его элементы, а затем сортирует их и выводит на экран.

#include <stdio.h>

main()

{