Понятие типа данных. Переменные и константы. Основные типы данных в языке Си: общая характеристика, машинное представление, описание данных в программе
Вид материала | Лекция |
СодержаниеВыраженияю условная операция. |
- Вопросы по дисциплине, 14.43kb.
- Структура программы. Часть Структуры данных. 24. Классификация структур данных. Операции, 41.26kb.
- Курс за второй семестр. Абстрактные типы данных, 687.76kb.
- Программа дисциплины программирование на языке С++ для направления 080700. 62 «Бизнес-информатика», 131.2kb.
- Лабораторная работа №4 Тема : Структурный тип данных в языке С++, 112.14kb.
- Borland Turbo Pascal, знать простые основные алгоритмы работы с простыми типами данных, 316.19kb.
- Реляционная модель данных в системах управления базами данных, 200.05kb.
- Анализировать и сравнивать, 157.08kb.
- Понятия о базах данных и системах управления ими. Классификация баз данных. Основные, 222.31kb.
- Задание на нахождение оптимального раскроя 25 4 База данных, 467.88kb.
ЛЕКЦИЯ 2
Понятие типа данных.Переменные и константы. Основные типы данных в языке Си: общая характеристика, машинное представление, описание данных в программе. Числовые, символьные и строковые константы. Арифметические операции и выражения. Операции отношения, логические операции и выражения. Условная операция. Автоматическое преобразование типов и операция приведения. Простейшие операторы языка Си. Составной оператор.
$ 1. ПОНЯТИЕ ТИПА ДАННЫХ. ПЕРЕМЕННЫЕ И КОНСТАНТЫ. ОПЕРАЦИЯ ПРИСВАИВАНИЯ.
Всякая программа, предназначенная для реализации на ЭВМ, представляет собой формальное описание алгоритма решения той или иной задачи. Действия, выполняемые программой в соответствии с этим алгоритмом, направлены на преобразование некоторых объектов, определяющих текущее состояние процесса решения задачи. Такие внутренние объекты программы принято называть данными. Для хранения всякого элемента данных выделяется необходимое пространство в оперативной памяти ЭВМ, размер которого мы будем называть длиной этого элемента.
Важнейшей характеристикой любого элемента данных является его тип. Понятие типа включает в себя следующую информацию об элементе данных:
- допустимый набор значений, которые объект этого типа может принимать в процессе работы программы (совокупность всех указанных значений будем называть областью определения типа);
- состав операций, которые разрешено выполнять над объектами данного типа;
- способ представления элемента данных рассматриваемого типа в памяти машины;
- правила выполнения всякой операции из допустимого для этого типа набора операций.
Язык Си обеспечивает возможность представления и обработки данных следующих основных типов:
- целые числа различной длины со знаком и без;
- вещественные числа различной длины;
- символы, представимые в формате стандарта ASCII.
Те элементы данных, которые сохраняют неизменные значения напротяжении всего времени работы программы, принято называть константами. Другие же объекты, являющиеся предметом изменения в ходе выполнения алгоритма, называются переменными. С точки зрения языка Си, всякая переменная величина отождествляется с ее именем или идентификатором. С позиции же ЭВМ она рассматривается как изменяющееся во времени содержимое некоторой области оперативной памяти.
Инструкция языка программирования, позволяющая назначать и изменять значения переменных, носит название операции присваивания. Для ее обозначения в Си используется символ " = ". Например:
а = 2; b = c = 3*(a + 4);
После выполнения указанных действий переменная а принимает значение, равное 2, а переменные с и b - значение 18.
$ 2. ТИПЫ ДАННЫХ В ЯЗЫКЕ СИ. ОПИСАНИЕ ДАННЫХ В ПРОГРАММЕ.
В простейшем случае инструкция описания данных в Си-программе имеет следующий формат:
[описатель класса памяти] описатель типа имя1 [ ,имя2 ...];
Для большинства компиляторов с языка Си допустимыми являются следующие описатели типа ( с указанием длины в байтах и области допустимых значений для компьютеров типа IBM PC.
Тип | Семантика и длина | Диапазон значений | ||
char | Символьная со знаком ( 1 ) | от | 128 до 127 | |
int | Целая ( 2 ) | от | 32768 до 32767 | |
short | Короткая целая ( 2 ) | от | 32768 до 32767 | |
long | Длинная целая ( 4 ) | от -2147483648 до 2147483647 | ||
unsigned char | Символьная без знака ( 1 ) | от 0 до 255 | ||
unsigned | Целая без знака ( 2 ) | от 0 до 65535 | ||
unsigned short | Короткая целая без знака ( 2 ) | от 0 до 65535 | ||
unsigned long | Длинная целая без знака ( 4 ) | от 0 до 4294967297 | ||
float | Вещественная ( 4 ) | 3.4е | 38 : 3.8е38 | |
double | Двойной точности вещ. ( 8 ) | 1.7е-308 : 1.7е308 |
Ключевые слова unsigned, signed, short и long могут быть использованы как модификаторы основных типов данных при построении производных. Например, следующие описания рассматриваются компилятором как эквивалентные:
short int...............short
long int ...............long
unsigned int ...........unsigned
unsigned short int .....unsigned short
unsigned long int ......unsigned long
signed int .............int
signed char ............char
Примеры описаний:
int a, b, c;
float alpha, beta;
Поскольку внутреннее машинное представление данных одих и тех же типов для различных ЭВМ могут быть различными, то возникают определенные трудности при необходимости обеспечить надлежащую мобильность программного обеспечения. Так, например, всякая переменная типа int на машинах типа IBM PC AT занимает два байта памяти, в то время как для ее представления на VAX-11 требуется четыре байта. Подобные различия могут привести к неправильной работе программ, манипулирующих, например с битовыми цепочками или требующих динамического выделения памяти для хранения переменных. Преодолеть возникающие при этом трудности можно, используя, где это необходимо, операцию определения количества памяти, требуемой для представления некоторой переменной или какого-либо типа. В общем случае эта операция выглядит следующим образом:
sizeof(name)
где name есть либо идентификатор переменной, либо имя типа данных.
Например:
a = sizeof(int);
Переменная а принимает значение, равное количеству байт памяти, требуемых для представления любой величины типа int, на конкретной ЭВМ.
$ 3. КОНСТАНТЫ В ЯЗЫКЕ СИ.
Константами в языке Си могут быть числа (целые и вещественные), символы и строки символов, которые разрешено использовать в программе в смысле их значения.
3.1. Целые константы.
Целые константы могут быть представлены в трех основных форматах: десятичном [-] десятичные цифры 0 - 9 [ L или l ]
восьмеричном 0цифры 0 - 7[ L или l]
шестнадцатеричном 0xцифры 0-F[L или l]
Компилятор IBM C/2 рассматривает десятичные константы как числа со знаком и присваивает им тип int. Если значение константы превышает наибольшее машинное целое со знаком, то она представляется как длинное целое (тип long). Знак минус в записи десятичной константы интерпретируется компилятором как арифметическая операция, а сама константа в этом случае является константным арифметическим выражением.
Восьмеричные и шестнадцатеричные константы могут иметь тип int, unsigned, long или unsigned long в зависимости от их абсолютной величины. Если константа допускает представление в виде целого числа стандартной длины, то компилятор присваивает ей тип int. Если же значение константы превышает максимальное положительное число со знаком, представимое как int, но меньше числа, которое без учета знака может быть представлено тем же числом разрядов, что и int, то ей назначается тип unsigned. Аналогично, если константа не может быть представлена как unsigned, она получает тип long или unsigned long.
Модификатор L или l, непосредственно следующий за записью константы, требует от компилятора ее представления как имеющей тип long или unsigned long независимо от абсолютной величины.
Примеры различных форм записи целых констант:
-
Десятичная
Восьмеричная
Шестнадцатеричная
10
012
0xa или 0XA
132
0204
0x84
32179
076663
0x7DB3
15L
017L
0xFL
3.2. Константы с плавающей точкой.
Константы с плавающей точкой являются вещественными десятичными числами со знаком. Их запись может включать в себя целую часть, десятичную точку, дробную часть, символ экспоненты е или Е и показатель экспоненты в виде целого числа со знаком:
[-]целая часть.[дробная] [E [+ | -]показатель] или
[-][целая часть].дробная [E [+ | -]показатель]
Знак минус перед константой рассматривается компилятором как арифметический оператор и поэтому вещественная отрицательная константа по существу является константным арифметическим выражением. В записи вещественной константы может отсутствовать либо целая, либо дробная часть (но не обе сразу). Отсутствие десятичной точки допустимо лишь при наличии экспоненты. Примеры возможных форм записи вещественных констант:
15.75 1.575E1 1575e-2 .1575E2 -.175e2 0.137 137. 137.0
Всякая константа с плавающей точкой рассматривается компилятором как имеющая тип double, т.е. представляется с двойной точностью.
3.3. Символьные константы.
Символьная константа представляет собой букву, цифру, знак пунктуации или Esc-последовательность, заключенные в одиночные кавычки:
'D' '7' ' ' '.'
Esc-последовательности состоят из обратной косой черты, за которой следует буква или комбинация цифр. Символы ' и \ также представляются в виде Esc-последовательностей. В языке Си допустимы следующие Esc-последовательности:
\n - новая строка \t - горизонтальная табуляция \v - вертикальная табуляция \b - шаг назад \r - возврат каретки \f - новая страница \a - звуковой сигнал \' - одиночная кавычка \" - двойная кавычка \\ - обратная косая черта \ddd - символ ASCII в восьмеричном представлении \xddd - символ ASCII в шестнадцатеричном представлении Во всех остальных случаях символ \ игнорируется компилятором. |
Последовательности вида \ddd и \xddd позволяют представить любой символ ASCII, включая и непечатные символы, в восьмеричном и шестнадцатеричном формате соответственно. Незначащие нули слева в обоих случаях могут быть опущены.
Значением символьной константы является целое число, отвечающее внутреннему машинному представлению соответствующего символа.
Примеры правильной записи символьных констант:
'A' 'c' '?' '1' '\'' '\\' '\n' '\033' '\10' '\x1F' 'r'
3.4. Строки символов.
Строками в языке Си являются последовательности символов ASCII, заключенные в двойные кавычки:
" [ один или более символов ASCII ] "
Непечатаемые символы ASCII, а также символы " и \ в составе строк должны представляться соответствующими Esc-последовательностями.
Компилятор IBM C/2 заносит символы строки в память ЭВМ в порядке их следования, автоматически добавляя нуль-символ (Esc-последовательность \0) в конец строки. Формально допустимой является также пустая строка (""), состоящая во внутреннем представлении из одного символа \0. Примеры записи символьных строк:
"Это строка символов"
"Enter a number between 1 and 100 \n Or press Enter"
"\"Yes, I do\", she said."
Для формирования длинной последовательности символов, занимающей более одной строки на экране терминала, необходимо набрать символ \, нажать клавишу Enter и продолжить ввод символов с новой строки:
" Длинная строка может быть продолжена\
на следующей строке."
Необходимо отметить, что символьная константа, например 'x', не идентична строке "х", содержащей один символ, так как символьная константа занимает в памяти один байт и равносильна своему числовому коду во внутреннем машинном представлении, строка же из одного символа занимает два байта памяти, первый из которых содержит код этого символа, а второй - символ \0.
$ 4. АРИФМЕТИЧЕСКИЕ ОПЕРАЦИИ И ВЫРАЖЕНИЯ
Примеры:
b = (c + d) % 4
e = ++b/(g + h)
В данном примере использована префиксная форма оператора ++ и поэтому операция деления будет выполнена после фактического увеличения значения переменной b на единицу.
Замечание. В языке Си операция присваивания является полноправной частью любого арифметического выражения и в общем случае имеет формат
выражение1 = выражение2
[ a+b=c*=d ]
Однако, не вдаваясь пока в семантические подробности такой записи, мы будем пользоваться ее упрощенной формой
идентификатор = выражение
Но даже в такую упрощенную схему укладываются достаточно сложные в семантическом отношении выражения вида
h = 28(q + s)/(t = u * v++)
$ 5. ОПЕРАЦИИ ОТНОШЕНИЯ. ЛОГИЧЕСКИЕ ОПЕРАЦИИ И ЛОГИЧЕСКИЕ
ВЫРАЖЕНИЯЮ УСЛОВНАЯ ОПЕРАЦИЯ.
Полный набор операций отношения следующий:
< > <= >= != ==
Результатом всякой операции отношения является числовое значение типа int, отличное от нуля, если сравнение истинно, и нулю в противном случае. Таким образом, операции отношения во внутреннем машинном представлении приводят к арифметическому результату. Это дает возможность объединить понятие арифметического, условного и логического выражения в едином понятии "выражение", что очень важно с точки зрения гибкости и "симметричности" языка.
В процессе вычисления значения всякого условного выражения, операции отношения обрабатываются слева направо. Установленный порядок может быть изменен путем использования круглых скобок. Например:
x < y == z эквивалентно (x < y) == z
в то время как выражение вида
x < (y == z)
отличается от предыдущего порядком выполнения операций < и =.
Для объединения нескольких операций отношения используется набор двуместных логических операций:
&& || !
Логические выражения являются прямым обобщением простых условных выражений. Стандартный порядок их обработки - слева направо. Приоритет логических опреаций && и || ниже приоритета любой операции отношения.
a <=b && b > c ЁЁЁ (a <= b) && ( b > c)
Операция логического отрицания имеет высокий приоритет, (такой же, как и приоритет одноместных арифметических операций) только круглые скобки имеют более высокий приоритет.
В общем случае операндами логических операций могут быть не только условные выражения, но и любые арифметические выражения.
Простейшей инструкцией языка Си, использующей логические выражения, является условный оператор:
выражение1 ? выражение2 : выражение3
Например, инструкция
abs_x = (x > 0) ? x : -x
присваивает переменной abs_x абсолютное значение переменной х.
$ 6. АВТОМАТИЧЕСКОЕ ПРЕОБРАЗОВАНИЕ ТИПОВ И ОПЕРАЦИЯ ПРИВЕДЕНИЯ.
Если в состав арифметического или условного выражения входят операнды различных типов, то компилятор автоматически выполняет приведение к общему типу. Несмотря на то, что в ряде случаев характер преобразования зависит от вида конкретной операции и типа операндов, существует общий набор стандартных правил преобразования:
1. если операция выполняется над данными двух различных типов, обе величины приводятся к "высшему" типу;
2. в операторе присваивания конечный результат вычисления выражения в правой части приводится к типу переменной , которой должно быть присвоено значение.
Последовательность имен типов, упорядоченных от "высшего" типа к "низшему", выглядит следующим образом: double, float, long, int, short и char. Применение ключевого слова unsigned повышает ранг соответствующего типа данных со знаком.
Кроме этого компилятор Си во всех случаях расширяет короткие операнды до операндов стандартной длины, принятой при выполнении машинных операций. Так операнды, имеющие тип float, преобразуются к типу double, операнды типа char и short к типу int, а операнды типа unsigned char и unsigned short - к unsigned.
Наряду с автоматическим преобразованием типов, в языке Си имеется возможность точно указать тип данных, к которому необходимо привести некоторую величину. Эта возможность реализуется в операции приведения типов следующим образом: перед данной величиной в круглых скобках записывается имя требуемого типа. Пусть, например, переменная rez имеет тип int. Тогда значение арифметического выражения
rez = 2.7 + 1.5
согласно общим правилам преобразования типов, равно 4. Однако применив явным образом операцию приведения типа к обоим операндам в правой части
rez = (int)2.7 + (int)1.5
получим результат, равный 3. зтот пример говорит о необходимости с особой осторожностью относиться ко всевозможным преобразованиям типов операндов.
$ 7. ПРОСТЕЙШИЕ ОПЕРАТОРЫ ЯЗЫКА СИ. СОСТАВНОЙ ОПЕРАТОР.
Арифметические, условные и логические выражения в совокупности образуют объекты программы, которые принято называть просто выражениями. Этой терминологией подчеркивается равноправие операций различных групп с точки зрения их роли в формировании выражений. Более того, всякому выражению в Си соответствует некоторое числовое значение (за исключением, конечно, тех случаев, когда результат операции считается неопределенным), которое может быть использовано в дальнейшем.
Однако сами по себе выражения любого вида еще не являются законченными инструкциями языка Си. Для обозначения завершенных действий используется понятие оператора. Простейшим оператором языка СИ является всякое выражение, заканчивающееся точкой с запятой (;). B частности, отдельно стоящая точка с запятой интерпретируется компилятором как нуль-оператор. Например, инструкции вида
a = c*(d + e)/4;
f = alfa++;
являющиеся операторами-выражениями, играют роль законченных предписаний для исполняющей системы.
Группа из одного или более операторов, заключенных в фигурные скобки, образуют составной оператор или блок. Например, группа из трех операторов
x = 7.5; y = x + 10;
z = (x + y)/7;
рассматривается компилятором как один составной оператор. В программе на языке Си составные операторы могут быть использованы всюду наравне с простыми операторами.
Пример 1.
#include
#include
/* Печать таблицы символов ASCII */
main()
{int c, symbol=0, lines=0;
char keycode;
for (c=32; c<=255; c++)
{
if (symbols > 3)
{ printf("\n");
symbols = 0;
lines += 1;
}
if (lines > 23)
{ printf (" Для продолжения нажмите любую клавишу\n");
keycode = getch();
lines = 0;
}
printf("%3d (hex %2x) - %c;",c,c,c);
symbols += 1;
}
printf( "\n"); }
Пример 2.
/* Правила выполнения операции деления */
#include
void main()
{float rez;
printf("\n Результат операции 7/3 равен :.3f", rez = 7/3);
printf("\n Результат операции 7.0/3 равен :.3f", rez = 7.0/3);
printf("\n Результат операции 7./3. равен :.3f", rez = 7./3.);
printf("\n Результат операции (float)7/3 равен :.3f",
rez=(float)7/3);
printf("\n Результат операции (float)(7/3) равен :.3f",
rez = (float)(7/3));
}
Пример 3.
/* Опрос клавиатуры и печать расширенных кодов клавишей */
#include
#include
main()
{ int key;
while (1)
{ printf("\t*** Нажмите любую комбинацию ключей ***\n");
key = getch();
if (key != 0)
printf("Код нажатой клавиши = %3d (hex %2)\n",key, key);
else
{ printf("Прочитанный код равен нулю. Выход\n");
break; }
}
printf("\n---------------------------\n");
}
Пример 4.
/* Подсчет количества слов в предложении */
#include
#define OFF 0
#define ON 1
void main()
{
char sym;
int nwords = ON, state = OFF;
printf('\n Введите предложение > \n");
while ((sym = getch()) != '\n')
if(sym == ' ' || sym == ',' || sym == ';' || sym == '.')
state = OFF;
else if(state == OFF)
state = ON; nwords ++
printf("\n\n Количество слов в предложении = %d",nwords);
}