- •И.А. Васюткина основы алгоритмизации и программирования.
- •Содержание
- •1.Обзор языКа программирования с
- •2.Этапы создания программы
- •3.Структура программы на языке си
- •3.1. Внутренняя структура программы
- •3.2. Пример программы на си
- •4.Базовые элементы языка си
- •5.Данные в программе на си
- •5.1. Константы
- •5.2. Базовые стандартные типы переменных
- •6.2. Операции отношения
- •6.3. Логические операции
- •6.4. Операции с разрядами
- •6.5. Операции сдвига
- •6.6. Операция условия ?:
- •6.7. Преобразование типов
- •6.8. Операции приведения
- •6.9. Дополнительные операции присваивания
- •7.Операторы языка си
- •Оператор может быть простым и составным. Позволяет пропустить оператор или блок операторов, если условие ложно.
- •1.Схема выполнения оператора
- •8. Оператор множественного выбора
- •9. Операторы цикла while
- •8. Операторы безусловных переходов
- •8.Стандартные функции ввода и вывода
- •8.1. Функция вывода данных на экран printf ()
- •8.2. Модификаторы спецификаций преобразования
- •8.3. Функция ввода данных с клавиатуры sсanf()
- •8.4. Функции ввода/вывода одного символа getchar(), putchar()
- •8.5. Функции небуфиризированного ввода с клавиатуры
- •8.7. Форматирование вывода
- •Заключительная программа
- •9. Массивы
- •9.1. Одномерные массивы
- •Стандартные алгоритмы работы с одномерными массивами
- •Инициализация одномерных массивов
- •9.2. Многомерные массивы
- •Инициализация многомерных массивов
- •9.2.2 Стандартные алгоритмы работы с двумерными массивами
- •10. Функции
- •10.1.Cоздание и использование пользовательских функций
- •10.2.Параметры функции
- •10.3.Возвращение значения функцией
- •10.4.Inline-функции
- •10.5.Значение формальных параметров функции по умолчанию
- •10.6.Перегрузка функций
- •11. Классы памяти и область действия
- •11.1.Глобальные переменные
- •Extern - внешние переменные
- •Статистические внешние переменные - static
- •11.2.Локальные переменные
- •Внутренняя статическая переменная
- •Регистровая переменная
- •Автоматические переменные
- •11.3.Доступ к функциям в многомодульной программе
- •12. Препроцессор языка си
- •12.1. Подстановка имен
- •12.2.Включение файлов
- •12.3.Условная компиляция
- •13. Указатели
- •13.1.Операция косвенной адресации *
- •13.2. Описание указателей
- •13.3.Использование указателей для связи функций
- •13.4.Указатели на одномерные массивы
- •13.5.Указатели на многомерные массивы
- •13.6.Операции над указателями
- •13.7.Передача массива в качестве параметра в функцию
- •13.8.Указатель на void *
- •14. Символьные строки и функции над строками
- •14.1.Массивы символьных строк
- •14.2.Массивы указателей
- •14.3.Указатель как возвращаемое значение функции Передача указателя как параметра функции
- •14.4.Функции, работающие со строками Функции, определеные в заголовочном файле stdio.H
- •14.5. Стандартные библиотечные функции Функции, определеные в заголовочном файле string.H
- •14.6. Преобразование символьных строк
- •Функции, определеные в заголовочном файле ctype.H.
- •15. Ссылки
- •16. Параметры командной строки
- •17. Производные типы данных
- •17.1.Структуры
- •Массивы структур
- •Вложенные структуры
- •17.1.3 Указатели на структуры
- •Операции над структурами
- •Передача структуры в функцию
- •17.2.Объединения
- •17.3. Синоним имени типа
- •17.4.Определение именнованных констант
- •17.5.Перечисления
- •17.6.Битовые поля
- •18. Динамическое выделение памяти
- •2. Функция void* calloc(n,size type);
- •18.2.Операция new с массивами
- •18.3.Инициализаторы с операцией new
- •18.4.Ошибки при использовании динамичской памяти
- •19. Файл
- •19.1.Открытие файла fopen()
- •19.2.Закрытие файла fclose()
- •19.3.Функции ввода/вывода одного символа fgetc(), fputc()
- •19.4.Функции форматированного ввода/вывода в файл
- •Int fprintf(file *stream,”управл.Cтрока”,arg1,…)
- •Int fscanf(file *stream,”управл.Cтрока”,&arg1,…)
- •19.5. Функции ввода/вывода строки символов в файл
- •19.6.Функции управления указателем в файле
- •Int fseek(file *stream, смещение, start)
- •19.7.Ввод/вывод записей фиксированной длины
- •20. Динамические структуры данных
- •20.1.Однонаправленные связные списки
- •Вставка узла
- •Удаление узла из списка
- •20.2.Бинарные деревья
- •21. Размещение данных в памяти
- •22.Модели памяти
- •Список литературы
18.3.Инициализаторы с операцией new
Другим преимуществом операции new по сравнению с malloc является возможность инициализации. При отсутствии явных инициализаторов объект, создаваемый new, содержит непредсказуемые данные ("мусор"). Объекты, распределяемые new, за исключением массивов, могут инициализироваться соответствующим выражением в скобках:
int_ptr = new int(3);
Для очистки выделенной памяти операцией new можно использовать функцию meset(), объявленную в <mem.h>. Ей передаются 3 параметра: адрес очищаемой памяти, символ для очистки, количество байт.
#include <string.h>
#include <stdio.h>
#include <mem.h>
int main(void) {
char buffer[] = "Hello world\n";
printf("Буфер до memset: %s\n", buffer);
memset(buffer, '*', strlen(buffer) - 1);
printf("Буфер после memset: %s\n", buffer);
return 0;
}
18.4.Ошибки при использовании динамичской памяти
1). Недоступные блоки - блоки памяти, указатели на которые потеряны.
2). Висящие ссылки - указатели на освобожденные блоки памяти.
3). Повторное освобождение динамической памяти. Недоступные блоки возникают после выделения памяти при присваивании указателю какого- либо другого значения или при уничтожении локального указателя после выхода из области видимости.
Пример 1:
int *a1, *a2;
a1 = new int[1000]; //выделили память
... //что-то делаем
a1 = a2; //ошибка - присвоение а1 другого
//значения - память недоступна
Пример 2:
void func(void)
{
int * a1;
a1 = new int[1000];
...
} //ошибка - при выходе из функции автоматически
//уничтожен a1,а память, тем не менее, осталась
//занята и недоступна.
Необходимо следить за указателями на выделенную память:
int * c;
void func1(void) {
int * a1;
a1 = new int[1000];
c = a1; //если данные по адресу a1 необходимы вне func1
... //иначе освободить перед выходом из функции
}
void func2(void)
{
...
delete []c;
}
Висящие ссылки возникают при освобождении памяти, на которую указывает более чем 1 указатель:
int *a = new int[1000];
int *a1 = a;
...
delete []a;
d = *(a1+50); //опасно - a1 уже нельзя использовать для обращения к
//массиву!
...
Если нет освобождения памяти, программист в зависимости от конкретной ситуации может посчитать это ошибкой, а может и нет (хотя это в любом случае уменьшает доступные ресурсы памяти), повторное освобождение безусловно ошибочно и скорее всего приведет к зависанию системы. Как правило, подобные ошибки не проявляются немедленно после появления, что затрудняет процесс отладки.
Написать программу учета успеваемости группы. Программа должна считать ср. бал группы и выводить на экран.
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
void main(void) {
int i,j,n;
float varsum=0;
struct stud { char fio[15]; char name[10];
struct exam { int val1; int val2;
int val3; int val4;}estimate;
float midle;
};
puts(«введите кол-во студентов”);
cin>>n;
struct stud *pgroup=new struct stud[n];
for(i=0; i<n; i++) {
printf(“Введите данные по %d студенту\n”,i+1);
cout<< “Фамилия:”;
gets(pgroup->fio);
cout<< “Имя:”;
gets(pgroup->name);
cout<< “Оценка за 1-й экзамен:”;
gets(pgroup->estimate.val1);
cout<< “Оценка за 2-й экзамен:”;
gets(pgroup->estimate.val2);
cout<< “Оценка за 3-й экзамен:”;
gets(pgroup->estimate.val3);
cout<< “Оценка за 4-й экзамен:”;
gets(pgroup->estimate.val4);
pgroup->middle = ( pgroup->estimate.val1+pgroup->estimate.val2+ pgroup->estimate.val3+ pgroup->estimate.val4)/4;
cout<<”Средний бал ”<< pgroup->fio<< pgroup->name<< pgroup->midle<<endl;
varsum+= pgroup->midle;
}
cout<<»Средний балл по группе”<<varsum/n<<endl;
delete[] pgroup;
}