МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное бюджетное государственное образовательное учреждение высшего профессионального образования
«НАЦИОНАЛЬНЫЙ ИССЛЕДОВАТЕЛЬСКИЙ ТОМСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Учебно-методические указания к
лабораторной работе №5 по курсу «Информатика»
Язык Си. Задание значений переменным и массивам. Форматный ввод-вывод. Работа с файлом
Томск 2012 г.
СОДЕРЖАНИЕ
ВВЕДЕНИЕ 3
1Основные компоненты операторов языка Си 4
2Типы данных, описание переменных 4
2.1Основные типы данных языка Си 5
2.2Переменные 7
2.3Массивы, символьные строки 8
3Присваивание значений 10
4Вычисление выражений 11
5Функции ввода-вывода 12
5.1Особенности функции ввода scanf() 14
5.2Работа с файлами 14
5.3Массивы и операции ввода-вывода 16
ВВЕДЕНИЕ
Данные учебно-методические указания содержат теоретический материал необходимый для выполнения лабораторной работы №5 «Язык Си. Задание значений переменным и массивам. Форматный ввод-вывод. Работа с файлом»по курсу Информатика для бакалавров направления 140800 «Ядерные физика и технологии». В частности, рассматриваются основные компоненты операторов языка Си, основные типы данных, операторы описания переменных, присваивания и вычисления выражений, функции форматированного ввода/вывода языка Си.
Основные компоненты операторов языка Си
Операторы языка Си состоят из следующих основных компонент:
константа– фиксированное значение, такое как число или символ (символьная строка). Это значение не может быть изменено операторами программы;
переменная– символическое имя, которое представляет значение, размещенное в памяти ЭВМ. Это значение может быть изменены операторами программы в процессе счета и выполнения операций ввода;
вызов функции– имя функции со списком аргументов. Функция – программная единица, осуществляющая выполнение набора определенных действий с использованием аргументов, указанных в вызове функции. (например, для вычисления синуса угла 0,5 рад – функция sin(0.5). Значение вычисленного результата используется по месту вызова функции;
выражение – комбинация констант, переменных, вызовов функций и операций (“операция” – это уникальный символ для операции, такой как умножение, сложение и т.д.), получающая единственный результат. Иначе – это формула для вычисления значений.
Типы данных, описание переменных
Переменные, именованные константы, массивы и функции имеют имена. Символические имена идентифицируют объекты, которые появляются в программной единице.
Символическое имя– это строка символов (строчных и прописных букв, цифр и символа подчеркивания), которая идентифицирует объект в программе. Первым символом не может быть цифра.
Внимание! Если используется больше 8 символов, то во время трансляции от имени могут остаться первые 8 символов (в зависимости от используемого компилятора). Строчные и прописные буквы различаются. Так, per1 и Per1 – это два разных имени.
Данные (константы, переменные, массивы, выражения и результаты, возвращаемые функциями) по способу хранения в памяти ЭВМ делятся на целочисленные и вещественные. Аналог вещественных данных в математике – рациональные числа. Целочисленные данных хранятся в памяти ЭВМ точно, а вещественные – нет.
Каждая основная компонента оператора программы на Си (константа, переменная, массив, результат вызова функции, результат выражения) имеет один конкретный тип данных.
Информация по каждому типу однозначно определяет:
1) структуру хранения данных указанного типа, т.е. выделение памяти и представление данных в ней, с одной стороны, и интерпретирование двоичного представления, с другой;
2) множество допустимых значений, которые может иметь тот или иной объект описываемого типа;
3) множество допустимых операций, которые применимы к объекту описываемого типа.
Все типы в языке Си можно разделить на две группы: простые (базовые, основные)) и производные (сложные).
К простым относят:
Символьные значения или знаки (character);
Целые (integer);
Перечисляемые типы (enumeration);
Булевые, или логические значения (bool);
С плавающей точкой (floating point);
Пустой тип (void).
Типы знаковые, целые, перечисляемые и с плавающей точкой называют также арифметическими, так как их можно интерпретировать числом.
Производные типы конструируются из простых типов.
К производным типам относят:
Массивы (array);
Функции (function);
Указатели (pointer);
Структуры (structure);
Объединения (union).
Введем понятия:
Объект (object)– область памяти.
Описание (declaration) объекта – указание свойств объекта без выделения для него области памяти.
Определение (definition)– указание свойств объекта и выделение для него области памяти.
Рассмотрим некоторые простые типы данных языка Си.
Основные типы данных языка Си
i

long– целые числа двойной точности;
char– символы (буквы, цифры, и некоторые другие символы);
f

double– вещественные числа двойной точности.
int– целое число, во внутреннем представлении занимает 2 или 4 байта (в зависимости от разрядности используемого компилятора – так, например, компилятор bc версии 3.1 фирмы Borland International предоставляет под данные типа int 2 байта), причем старший бит отводится под знак (+ или -).
Таким образом, в данных этого типа будут храниться целые числа в диапазоне значений от (-215) до (+215-1) (от –32 768 до +32 767) для 2 байтов или от (-231) до (+231-1) (от –2 147 483 648 до +2 147 483 647) для 4 байтов соответственно. В памяти хранится ТОЧНО.
Пример размещения целого значения – числа 11 – в двухбайтовой переменной типа int:
|
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
Значение бита |
| |||||||||||||||||
|
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
№ бита |
| |||||||||||||||||
|
Бит знака |
214 |
213 |
212 |
211 |
210 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
Соответ-ствующее число |
| |||||||||||||||||
|
|
+ |
|
|
|
|
|
|
|
|
|
|
|
1.23 + |
0.22 + |
1.21 + |
1.20 = |
8+0+2+1=11 | |||||||||||||||||
long – целое число с в 2 раза большим числом значащих цифр, чем для int;во внутреннем представлении занимает 4или 8 байт (в зависимости от используемого компилятора), причем старший бит отводится под знак (+ или -), т.е. диапазон значений составляет от -231 до +231-1 или от -263 до +2+63-1 соответственно. В памяти хранится ТОЧНО.
float – “вещественные числа” (или в математике – "действительные" числа) – это десятичные дроби и, в частности, целые числа, записанные в виде десятичных дробей; вместо запятой, отделяющей целую часть от дробной, используется точка. Если целая часть константы равна нулю, то она может быть опущена, как и нулевая дробная часть (например, 0.18 == .18; 35.0 == 35.). Аналог “стандартной” записи числа – нормализованная запись константы с использованием буквы е (например, 2,5.109 == 2.5е9 == .25е10: здесь 0.25 – дробная часть, 10 – порядок). Размер –4 байта(1байт для представления порядка и 3 байта – для мантиссы, старший бит, как для мантиссы, так и для порядка, отводится под знак), значащих (верных) цифр в дробной части – 6-7; диапазон хранимых значений по модулю – от 3.4.10-39 до 3.4.10+38. Десятичная точка или буква е должны быть всегда.Данный тип соответствует типу real в Паскале или ФОРТРАНе. В памяти хранится НЕ ТОЧНО.
double – вещественное число с в 2 раза большим числом значащих цифр (~16), чемдляfloat; размер – 8 байт. Соответственно диапазон значений (по модулю) – от 1.7.10-308 до 1.7.10+308.
char - символ (размер в памяти – 1 байт). Этот тип определяет целые числа без знака в диапазоне от 0 до 255, что обычно соответствует кодам символов (буквы, цифры, псевдографика, неотображаемые символы, например, "звук", или "новая строка"). Символьные константы заключаются в апострофы: 'S', '1', 'a' –правильно записанные символьные константы. Значениями переменной или константы типа char могут быть только одиночные символы. Некоторые символы не являются отображаемыми (например, "новая строка", "табуляция" и т.д.). В этом случае используют либо код ASCII, либо специальную последовательность символов. Например, "табуляцию" можно обозначить как '\09' или '\t'. Например: nam = '\n'.Некоторые полезные управляющие последовательности:
-
\n
новая строка
\\
обратный слэш(обратная косая черта)
\t
Табуляция
\'
апостроф
\f
подача бланка
\"
кавычки
Переменные
Величина, значение которой может изменяться в процессе работы, называется переменной. Каждой переменной величине в памяти отводится ячейка ("домик"), размеры которой зависят от типа размещаемых данных. В этой ячейке и будет находиться текущее значение переменной. При вычислении нового значения переменной производится изменение содержимого ячейки памяти, в которой находилось прежнее значение этой переменной. Это новое значение переменной становится текущим до получения следующего её значения – в результате операции ввода или после вычисления выражения.
Для описания переменных используются операторы описания типа, приведенные выше, а затем перечисляются имена переменных:
тип_данных имя1, имя2, …;
Например:
int a, bc;
float g;
char nn, mm;
В программе на языке Си ВСЕ ПЕРЕМЕННЫЕ ДОЛЖНЫ БЫТЬ ОПИСАНЫ!!! Таким образом, во время разработки программы необходимо составить список всех требуемых переменных и указать при этом, какого они должны быть типа.
Для определения размера объекта в байтах в языке Си имеется встроенная функция sizeof():
int rr = sizeof(int);
printf("данные типа int занимают %d байта\n", rr);
В языке Си имеются и другие типы данных, как основные, так и производные – массивы, указатели, структуры, объединения – построенные с использованием основных типов.
Массивы, символьные строки
При необходимости связывания и использования ряда родственных величин (например, коэффициенты системы линейных уравнений) удобно использовать элементы массива, являющиеся переменными с индексами. Массивы являются важнейшим средством языка, применяемым во многих программах. Их использование позволяет удобным способом размещать в памяти большое количество необходимой информации.
Массив – это набор переменных, имеющих один тип и одно и то же базовое имя и отличающихся одна от другой числовым признаком (номером элемента). В памяти ЭВМ они располагаются последовательно. Другими словами, массив – это упорядоченный набор однородных переменных (одного типа, с одинаковой формой представления, основанием и точностью значений). Массив характеризуется своим именем, количеством измерений (индексов) и количеством переменных в каждом измерении (количеством значений, которые может принимать индекс).
Пример: улица с домами. Название улицы – это имя массива, номер дома – это номер элемента массива, количество жильцов в доме – значение элемента массива.
Для создания массива необходимо задать тип данных, имя и размер, т.е. количество элементов. Массив может быть как одномерным, так и многомерным, что указывается при его описании. Так, понятию "одномерный массив" в математике будет соответствовать понятие "вектор", а понятию "двумерный массив" – понятие "матрица", и т.д.
Описание массива:
тип имя[размер1][размер2]...
Пример:
int mas[10];
float aа[3][4];
В данном примере описан одномерный массив mas, содержащий 10 элементов,и двумерный массив aa, содержащий 3строких4столбца=12 элементов.
Каждый элемент определяется именем массива и списком индексов, заключенным в квадратные скобки. В качестве индекса элемента массива можно использовать не только целые константы, но и переменные целого типа, и результаты вычисления целочисленных выражений. Например:
aaa[5], bb[i], cc[k+5].
Под "размером" понимается количество элементов, а не номер последнего, т.к. ПЕРЕЧИСЛЕНИЕ НОМЕРОВ ЭЛЕМЕНТОВ МАССИВА НАЧИНАЕТСЯ С 0, А НЕ С 1 !!! Т.е. mas[0], mas[1], .. mas[9]; aa[0][0], aa[0][1], ... aa[2][3]. Таким образом, индексами должны быть целые числа (или переменные целого типа); индексирование начинается с 0.
Символьная строка – это последовательность, состоящая из одного или более символов. Например: "Привет участникам соревнований!". Кавычки вводятся для того, чтобы отметить начало и конец строки, т.е. играют ту же роль, что и апострофы в случае одиночного символа. Специального типа для описания строк НЕТ, поэтому строки представляются в виде массива элементов типа char,по одному элементу на символ, причем последним элементом массива является символ \0 – "нуль-символ", использующийся для пометки конца строки:
|
П |
р |
и |
в |
е |
т |
|
у |
ч |
а |
С |
т |
н |
и |
к |
а |
м |
|
с |
о |
р |
е |
в |
н |
о |
в |
а |
н |
и |
й |
\0 |
| |
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
– номер | |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
элемента массива | |
Таким образом, для размещения данной строки понадобится массив из 31 элементаи потребуется описать соответствующий массив:
char str[31] = "Привет участникам соревнований";
Присваивание значений
Присваивание значений переменным и массивам можно производить различными способами:
Инициализировать переменную при описании:
int s1 = 1, s2 = 0;
double x = 3.56;
char st = 'a';
2) Присвоить соответствующие значения можно с использованием оператора присваивания =.
3) Присвоить первоначальные значения можно с помощью функций ввода.
Оператор присваивания предназначен для вычисления выражения и присваивания его значения указанной переменной или элементу массива. Структура оператора:
имя_переменной = выражение;
Символ “=” – это не математическое “равно”! Это – “операция присваивания”!!!
Действие оператора присваивания можно описать предложением: "Вычислить значение выражения, расположенного СПРАВА от оператора “=”, и поместить результат в ячейку, имя которой указано СЛЕВА".
Примеры использования оператора =:
num = 2.4; ddd = 'e'; b[3] = 2*c;
В данном примере 4-му элементу массива b присвоено вычисленное значение 2.с и соответствующие значения присвоены переменным numи ddd.
i = i + 2;
Выполнение данного оператора можно пояснить следующей фразой: “Взять значение переменной с именем i, к нему прибавить 2, а затем присвоить новое значение переменной с именем i”. С математической же точки зрения данное выражение бессмысленно. Таким образом, операторы а=с; и с=а; выполнят совершенно разные действия.
Инициализировать символьный массив можно следующим образом:
char a0[] = "1234";
char a1[5] = "1234";
char *a2 = "1234";
printf("а0 = %s\n а1 =%s\n а2 =%s\n",a0,a1,a2);
Во всех случаях (а0, а1 и а2) в памяти будет выделено по 5 элементов, причем в последнем случае был использован "указатель" на тип char.
Для копирования одной строки в другую необходимо пользоваться функцией strcpy().
Пример:
#include <stdio.h>
#include <string.h> /*не забудьте!*/
void main(void)
{
char string[10];
char *str1 = "abcdefghi";
strcpy(string, str1);
printf("%s\n", string);
}
Вычисление выражений
Тип результата арифметической операции определяется типом данных, используемых в выражении. Например, при вычислении выражения 3/2 получим целый результат 1, т.к. и 3, и 2 – константы целого типа. Если операция выполняется над данными двух различных типов, то обе величины приводятся к "высшему" из двух типов (последовательность имен типов, упорядоченных от "высшего" к "низшему", выглядит так: double, float, long, int, char).Например, при вычислении выражения 3./2 получим вещественный результат 1.5, т.к. 3. – константа вещественного типа, а 2 – константа целого типа.
В операторе присваивания конечный результат вычисления выражения в правой части приводится к типу переменной, которой должно быть присвоено это значение. Например, при вычислении:
float a;
a= 3/2;
получим в качестве результата (значения переменной а) вещественное число 1.0, а не 1.5! Это объясняется тем, что сначала будет вычислено целочисленное выражение (3/2 = 1), а затем результат преобразуется к типу float.
Функции ввода-вывода
Функции ввода-вывода дают пользователю возможность взаимодействия с выполняющейся программой. Наиболее универсальными в Си являются функции printf() – для вывода информации и scanf() – для ввода информации, причем “ввод” и “вывод” рассматриваются с точки зрения ЭВМ, а не с вашей. “Ввести” – передать данные в память ЭВМ с внешнего устройства (с клавиатуры, из файла на диске, со сканера), “вывести” – передать данные из памяти ЭВМ на внешнее устройство (на экран монитора, в файл на диске, на печатающее устройство).
Обычно функции printf()иscanf()"работают" во многом одинаково – каждая использует "управляющую строку" и список "аргументов". При необходимости ввести (вывести) значение какой-либо переменной НЕОБХОДИМО ИСПОЛЬЗОВАТЬ ОПРЕДЕЛЕННЫЙ ФОРМАТ. Каждому формату соответствует тип выводимой (вводимой) информации. Список основных спецификаций преобразования приведен в таблице 1.
Таблица 1
|
Формат |
Тип выводимой информации |
Формат |
Тип выводимой информации |
|
%d |
Десятичное целое число |
%e |
Число с плавающей точкой, экспоненциальная запись |
|
%c |
Один символ |
%f |
Число с плавающей точкой, десятичная запись |
|
%s |
Строка символов |
%lf |
Число с плавающей точкой двойной точности (double), десятичная запись |
Пример:
float Pi = 3.14159;
printf("Значение числа pi равно %f\n",Pi);
Здесь "Значение числа pi равно \n" – текстовая строка, которая в том же самом виде и выведется, %f – "дырочка" в "трафарете" (спецификация преобразования), куда и выведется текущее значение переменной Pi.
Результат будет выглядеть так:
Значение числа pi равно 3.141590
Формат, указываемый при обращении к функции printf(), выглядит следующим образом:
