- •Экзаменационные вопросы по дисциплине
- •«Программирование на языках высокого уровня»
- •Среда программирования языка Си.
- •Алфавит языка.
- •Данные и типы данных в Си.
- •Int (целый);
- •Константы и переменные.
- •Перечень операций в Си. Приоритет операций.
- •Структура программы.
- •Int scanf(char *управляющая строка);
- •Массивы в Си.
- •Массивы указателей. Массивы динамической памяти.
- •Представление символа и строки в памяти эвм. Ввод-вывод символов и строк.
- •Понятие функции в Си. Определение и описание. Вызов функции.
- •Передача параметров функции по значению.
- •Передача параметров функции по ссылке.
- •Рекурсивные функции.
- •Определение структур. Инициализация и присваивание структур.
- •Доступ к элементам структур
- •Двоичный режим обмена с файлами. Строковый обмен с файлами.
- •Использование макросов в Си.
Определение структур. Инициализация и присваивание структур.
Структуры в си ( c ) - это объединенные данные, у которых есть некоторая логическая взаимосвязь. В отличие от массивов, структуры могут содержать данные разных типов. Вот пару примеров структур в си ( c ): структура класс (имя учащегося, буква класса, средний балл); структура футбольная команда (тренер, название команды, место в турнирной таблице). Т.е. структуру вы будете использовать довольно часто. Теперь давайте рассмотрим, как описываются структуры в си:
struct klass {
char name[20];
char klass_name;
float bal;
};
struct
Любая структура в языке си ( c ) должна начинаться с ключевого слова - struct, которое сообщает компилятору, что тут у нас будет структура. Все данные в структуре (struct) пишутся в фигурных скобках, и в конце ставится запятая с точкой (;). Советую сразу ставить запятую с точкой, что бы не было ошибок.
Как вы видите, в структуре (struct) у нас находятся данные различных типов, но они объединены в логическую связь, так как в моем примере они являются определенным школьным классом. Данные в структуре должны иметь уникальные имена, но в различных структурах можно использовать одинаковые названия.
Структура, которая создана выше не занимает в памяти компьютера места, так как мы, на самом деле, просто создали свой тип данных. Объявление структуры ни чем не отличается от объявления любого типа данных в языке си ( c ). Вот пример:
struct klass a, b[5], *c;
Мы объявили переменную а типа struct klass, массив b, состоящий из 5 элементов типа struct klass и указатель на переменную struct klass.
Так же можно объявлять переменные сразу после объявления структуры:
struct klass {
char name[20];
char klass_name;
float bal;
} a, b[5], *c;
А какие же операции можно проделывать со структурами? Ответ на этот вопрос лучше перечислить по пунктам:
присваивание полю структуры значение того же типа
можно получить адрес структуры. Не забываем операцию взятия адреса (&)
можно обращаться к любому полю структуры
для того, что бы определить размер структуры можно использовать операцию sizeof()
Инициализация структуры
Инициализация структуры в языке си ( c ) происходит так же, как и при инициализации массива. Вот пример инициализации структуры:
struct klass a = {"Sergey", 'B', 4.5 };
Т.е. мы создаем переменную типа struct klass и присваиваем всем трем полям, которые у нас определенны в структуре, значения. Порядок очень важен при инициализации структуры, так как компьютер сам не может отсортировывать данные. Если какое-либо поле у вас будет не заполненным, то оно автоматом заполнится 0 - для целочисленных типов; NULL - для указателей; \0 (ноль-терминатор) - для строковых типов.
Доступ к элементам структур
Доступ к отдельным членам структуры осуществляется с помощью оператора точка (.). Его еще называют оператором доступа к членам структуры. Например, можно присвоить в уже объявленной ранее на уроке 84 структуре addr_info значение zip-кода, равное 12345:
addr_info.zip=12345;
Этот отдельный член определяется именем объекта addr_info, за которым обязательно следует точка, а затем имя самого этого члена zip. В общем виде использование оператора точка для доступа к члену структуры выглядит таким образом:
имя-объекта.имя-члена
Поэтому, чтобы вывести на экран zip-код, необходимо записать следующую команду:
printf("%lu", addr_info.zip);
Аналогично, при вызове с помощью gets() члена addr_info.name, являющегося массивом символов, нужно использовать gets(addr_info.name); Таким образом, в начало name передается указатель на символьную строку. Учитывая, что name является массивом символов, доступ к отдельным элементам массива name можно получить, если использовать индексы массива. Например, с помощью следующего кода можно вывести на экран содержимое члена addr_info.name:
for(t=0;addr_info.name(t);++t) putchar(addr_info.name[t]);
Обратите внимание, что индексируется именно name, а не addr_info. Нужно хорошо помнить, что addr_info - это имя всего объекта, а name - это имя элемента этой структуры. Таким образом, если требуется индексировать элемент структуры, то индекс необходимо указывать после имени этого элемента.
Массивы структур.
1). Самый привычный способ
struct my_struct m[8];
Если вам надо задать статический массив (любой "мерности" - хоть линейный, хоть прямоугольный, хоть 296-мерный).
По сути, это:
тип имя_массива [размер_1][размер_2]...;
где тип - это "struct my_struct", всё остальное - элементарно.
2). Динамический массив. Всё так же, как и, например, с массивами целых чисел, т.е. если вы знаете, что значит
int * m;
m=new int [20][36];
то просто вместо "int" пишете "struct my_struct".
P.S.: Предполагается, что "struct my_struct" - это некоторая уже описанная структура
Понятие потокового ввода-вывода.
Под вводом-выводом в программировании понимается процесс обмена информацией между оперативной памятью и внешними устройствами: клавиатурой, дисплеем, магнитными накопителями и т. п. Ввод — это занесение информации с внешних устройств в оперативную память, а вывод — вынос информации из оперативной памяти на внешние устройства. Такие устройства, как дисплей и принтер, предназначены только для вывода; клавиатура — устройство ввода. Магнитные накопители (диски, ленты) используются как для ввода, так и для вывода.
Основным понятием, связанным с информацией на внешних устройствах ЭВМ, является понятие файла. Всякая операция ввода-вывода трактуется как операция обмена с файлами: ввод — это чтение из файла в оперативную память; вывод — запись информации из оперативной памяти в файл. Поэтому вопрос об организации в языке программирования ввода-вывода сводится к вопросу об организации работы с файлами.
Вспомним, что в Паскале мы использовали представления о внутреннем и внешнем файле. Внутренний файл — это переменная файлового типа, являющаяся структурированной величиной. Элементы файловой переменной могут иметь разный тип и, соответственно, разную длину и форму внутреннего представления. Внутренний файл связывается с внешним (физическим) файлом с помощью стандартной процедуры Assign. Один элемент файловой переменной становится отдельной записью во внешнем файле и может быть прочитан или записан с помощью одной команды. Попытка записать в файл или прочитать из него величину, не совпадающую по типу с типом элементов файла, приводит к ошибке.
Аналогом понятия внутреннего файла в языках Си/Си++ является понятие потока. Отличие от файловой переменной Паскаля состоит в том, что потоку в Си не ставится в соответствие тип. Поток — это байтовая последовательность, передаваемая в процессе ввода-вывода.
Поток должен быть связан с каким-либо внешним устройством или файлом на диске. В терминологии Си это звучит так: поток должен быть направлен на какое-то устройство или файл.
Основные отличия файлов в Си состоят в следующем: здесь отсутствует понятие типа файла и, следовательно, фиксированной структуры записи файла. Любой файл рассматривается как байтовая последовательность
Открытие и закрытие потока.
Fopen(f);
Fclose(f);
