Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Описание различных типов, переменные и константы



 

Целые числа.

У целого числа никогда не бывает дробной части. Представив целое число в двоичном виде, его нетрудно разместить в машине. Например, число 3 в двоичном виде выглядит как 11. Если его поместить в слово 32-разрядной машины, необходимо первые 30 бит установить в 0, а последние 2 бита - в 1.

 

Числа с плавающей точкой.

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

Все данные типов int, short, long являются числами со знаками, т.е. значениями этих типов могут быть только целые числа - положительные, отрицательные и нуль. Один бит используется для указания знака числа, поэтому максимальное число со знаком, которое можно представить в слове, меньше, чем максимальное число без знака.

 

Описание данных целого типа.

При описании данных необходимо написать только тип, за которым должен следовать список имен переменных. Например, int dog, rad, nina. В качестве разделителя между именами переменных необходимо использовать запятую.

 

Целые константы.

Согласно правилам языка Си, число без десятичной точки и без показателя степени рассматривается как целое. Поэтому компилятор по записи константы определяет, целая она или вещественная. Если нужно ввести константу типа long, то нужно указать признак L или l в конце числа. Если при записи константы целое начинается с цифры 0, то эта константа интерпретируется как восьмеричное число, если же целое начинается с символа 0x или 0X - как шестнадцатеричное число.

 

Инициализация переменных целого типа.

Константы применяются при инициализации переменных. Это означает присваивание переменной некоторого значения перед началом обработки. Можно инициализировать переменную в операторе описания.

Например,

int dog=5;

int rad=077;

int nina=0X99;

! В языке Си введено три класса целых чисел, имеющих различные размеры. Тем самым пользователю языка Си предоставили возможность выбора типа переменной с требованием задачи. Например, если переменная типа int занимает одно слово, а переменная типа long занимает два слова, значит, тип long позволяет обрабатывать большие числа. Если в задаче не используются большие числа, то незачем вводить в программу переменные типа long, т.к. если вместо числа, занимающего одно слово в памяти, используется число, занимающее два слова, работа машины замедляется.

Описание данных типа unsigned .

Этот тип является модификатором типов: int, short, long. Мы можем использовать комбинацию ключевых слов unsigned int, unsigned short, unsigned long, т.е. переменная не может принимать отрицательного значения. Для указания типа unsigned int достаточно написать unsigned. Целые беззнаковые константы записываются так же, как и обычные константы, запрещено только использование знака минус.

Например, unsigned age;

 

Описание данных типа char .

Этот тип определяет целые числа без знака в диапазоне от 0 до 255. Такое целое обычно размещается в одном байте памяти. Для описания символьной переменной применяется ключевое слово char. Правила описания более чем одной переменной и инициализации переменных остаются теми же, что и для других основных типов.

Например, char dog, cat;

Символьные константы. Символы в языке Си заключаются в апострофы.

Например, char dog; dog='b';

Если апострофы опущены, то компилятор считает, что используется неописанная переменная b. В стандартном языке Си значением переменной или константы типа char могут быть только одиночные символы.

Примеры символьных констант: 'A', 'a', '7', '$'.

 

Специальные (управляющие) символьные константы.

Новая строка (перевод строки) '\n'
Горизонтальная табуляция '\t'
Вертикальная табуляция '\v'
Возврат на шаг '\b'
Возврат каретки '\r'
Перевод формата '\f'
Обратная косая '\\'
Апостроф '\''
Кавычки '\" '
Нулевой символ (пусто) '\0'

Кроме того, любой символ может быть представлен последовательностью трех восьмеричных цифр: '\ddd'. Символьные константы считаются данными типа int.

 

Строковые константы.

Строковая константа представляется последовательностью символов кода ASCII, заключенной в кавычки.

Например,

" Это строковая константа"

В конце каждой строки компилятор помещает нулевой символ '\0', отмечающий конец данной строки. Каждая строковая константа, даже если она идентична другой строковой константе, сохраняется в отдельном месте памяти. Если необходимо ввести в строку символ кавычек (" ), то перед ними надо поставить символ обратной косой (\). В строку могут быть введены любые специальные символьные константы, перед которыми стоит символ \. Символ \ и следующий за ним символ новой строки игнорируется.

 

Перечисляемые константы.

Имена, указанные в описании перечисляемых констант, трактуются как целые числа (см. описание перечисления).

 

Описание данных типа float и double .

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

Пример алгебраической записи чисел с плавающей точкой:

Число Алгебраическая запись Запись для ввода в машину
= 5.0 * 103 = 5.0e3
0.000077 = 7.7 * 10-5 = 7.7e-5

Обычно для размещения в памяти числа с плавающей точкой отводится 32 бита - 8 бит для представления порядка и знака и 24 бита - для мантиссы, т.е. коэффициента при степени десяти. Для представления данных типа double (вычисление с двойной точностью) для представления чисел используется удвоенное число битов. Другой способ определения данных типа double заключается в использовании ключевых слов long float.

Переменные с плавающей точкой описываются и инициализируются таким же образом, что и переменные целого типа.

Например,

float dog, cat, bigword=5.77e+34;

 

Константы с плавающей точкой.

В языке Си имеется несколько возможностей записи констант с плавающей точкой. Наиболее общая форма записи константы - это последовательность десятичных цифр со знаком, включающим в себя десятичную точку, затем символ e или Е и показатель степени по основанию 10 со знаком. Знак “+” можно не писать. Ниже приведено несколько правильно записанных констант с плавающей точкой:

1.1e+12

3.14159

 

! Во время разработки программы необходимо составить список требуемых переменных и указать при этом, какого они должны быть типа. Описывайте эти данные в самом начале тела функции, в которой они используются. Имена переменных выбирайте таким образом, чтобы они указывали на их смысл. При инициализации переменной следите за тем, чтобы тип константы соответствовал типу переменной, хотя язык Си рассматривает такие несоответствия менее жестко, чем Паскаль, но лучше учиться избегать дурного тона в программировании!

Символьные строки

 

Символьная строка - это последовательность символов, возможно пустая (" " ). Рассмотрим пример:

" Большой спрос на образование в области

информационных дисциплин объясняется не только

популярностью компьютеров в современном обществе,

но и реальной пользой от их применения."

Кавычки не являются частью строки. Они вводятся только для того, чтобы отметить ее начало и конец. В языке Си нет специального типа, который можно было бы использовать для описания строк. Вместо этого строки представляются в виде " набора" элементов типа char. Это означает, что символы в строке можно представить расположенными в соседних ячейках памяти - по одному символу в ячейке. Символ \0 в языке Си используется для того, чтобы отмечать конец строки. Нуль-символ не выводится на печать и в таблице кода ASCII (American Standard Code for Information Interchange) имеет номер 0. Наличие нуль-символа означает, что количество ячеек массива символов должно быть на одну больше, чем число символов строки. Массив можно представить как совокупность нескольких ячеек памяти, объединенных в одну строку. Массив - это упорядоченная последовательность элементов данных одного типа. В нашем примере мы создали массив из 177 ячеек памяти, в каждую из которых можно поместить один символ типа char. Это можно сделать с помощью оператора описания:

char String[177];

Квадратные скобки указывают, что переменная String - массив из 177 элементов, а char задает тип каждого элемента. Длину строки в символах (без завершающего символа) определяет функция strlen( ). Обращение к ней в нашем примере выглядит так:

strlen(String);

Результат - целое число.

 

Препроцессор языка Си

 

Вернемся к константам. Чтобы ввести ту или иную константу в программу, нужно указать ее фактическое значение, как было сказано выше. Можно использовать вместо этого " символические константы" и позволить компилятору заменить символические константы числами. Как можно создать такую константу? Можно это сделать так:

float cost = 0.0012;

Такой способ задания констант в больших программах неэкономичен. В Си имеется другой, лучший способ. Этот способ реализуется с помощью препроцессора языка Си. Препроцессор дает возможность задавать константы. Для этого в начало программы нужно добавить строку, аналогичную следующей:

#define COST 0.0012

При компиляции программы каждый раз, когда появится переменная COST, она будет заменяться величиной 0.0012. Такой процесс называется подстановкой во время компиляции. Замечание по поводу формата: сначала идет ключевое слово #define (оно должно начинаться с самой левой позиции), потом идет символическое имя константы, а затем ее величина. Символ " точка с запятой " не используется, потому что это не оператор языка Си.

Если в качестве первого символа в строке программы используется символ #, то эта строка является командной строкой препроцессора (макропроцессора). Командная строка препроцессора заканчивается символом перевода на новую строку. Если непосредственно перед концом строки поставить символ обратной косой (\), то командная строка будет продолжаться на следующей строке программы.

Препроцессор используется для обработки текста программы до этапа ее компиляции. Обычно препроцессоры служили средством расширения языков с целью обеспечения дополнительных возможностей. Несмотря на бесчисленное множество препроцессоров, созданных для расширения возможностей языков программирования, все они были нестандартными. Для некоторых языков, например для языков общего назначения ПЛ/1 и Си, препроцессоры поставлялись как часть их стандартной среды. Препроцессор для языка Си обеспечивает средства для определения макросов, определения констант, включения файлов и условную компиляцию. Препроцессор языка Си вызывается автоматически при обращении к компилятору. Программа может быть обработана только препроцессором без компиляции, если в команде сс указать ключ:

cc -E имя_файла

Результат работы препроцессора помещается в поток стандартного вывода stdout. Обработка программы препроцессором без компиляции позволяет программисту проанализировать действие определений препроцессора и макровызовов.

 

! Символическую константу после #define лучше писать прописными буквами. В процессе использования языка Си выработалась традиция писать константы большими буквами. Если при просмотре программы встречается имя, написанное прописными буквами, сразу становится ясно, что это константа, а не переменная. Давайте не нарушать традицию!

Директиву #define можно использовать для определения символьных и строковых констант. В первом случае необходимо использовать " апостроф", а во втором кавычки.

Например,

#define NULL '\0'

#define USA '$'

#define RUSSIA " Рубль"

#undef USA

Команда #undef USA отменяет предыдущее определение для идентификатора USA. Через команду #define можно задавать выражения - макросы, которые вычисляются и при компиляции подставляются в программу. Воизбежании ошибок при вычислении выражений макроопределения необходимо заключать в скобки:

#define идентификатор1 (идентификатор2, _) строка

Пример:

#define abs(A) (((A)> 0)? (A): - (A))

Каждое вхождение выражения abs(arg) в тексте программы заменяется на ((arg)> 0)? (arg): -(arg)), причем параметр макроопределения A заменяется на arg.

Пpимер:

#define nmem(P, N)\

(P)-> p_mem[N].u_long

Символ \ продолжает макроопределение на вторую строку. Это макроопределение уменьшает сложность выражения, описывающего массив объединений внутри структуры.

Макроопределения препроцессора языка Си имеют две формы - простую и параметризованную,

#define идентификатор строка_замены

#define идентификатор(x1, x2, _, xn) строка_замены

где строка_замены может содержать идентификаторы, ключевые слова, разделители, такие как круглая или прямоугольная скобка, или строки знаков, не содержащие каких-либо разделителей.

 

Замечание.

Командная строка #include может встречаться в любом месте программы, но обычно все включения размещаются в начале исходного текста:

#include < имя_файла>

Пример:

#include < math.h>

Препроцессор заменяет эту строку содержимым файла math.h. Угловые скобки обозначают, что файл math.h будет взят из некоторого стандартного каталога, обычно это /usr/include. Текущий каталог не просматривается:

#include " имя_файла"

Пример:

#include " ABC"

Препроцессор заменяет эту строку содержимым файла ABC. Так как имя файла заключено в кавычки, то поиск производится в текущем каталоге, в котором содержится основной файл исходного текста. Если в текущем каталоге данного файла нет, то поиск производится в каталогах, определенных именем пути в опции -i препроцессора. Если и там файла нет, то просматривается стандартный каталог.

Командные строки препроцессора используются для условной компиляции различных частей исходного текста в зависимости от внешних условий. Условной компиляцией называется выборочная компиляция только тех частей программы, которые удовлетворяют определенным условиям. Например, можно скомпилировать только те части программы, которые необходимы для конкретной версии системы.

Условная компиляция обладает следующими достоинствами:

Обеспечивается средство параметризации во время компиляции. Например, такая возможность может быть использована для генерации программ с различной структурой.

Обеспечивается эффективное использование оперативной памяти, поскольку во время выполнения нет необходимости держать в памяти неиспользуемые коды программы.

Обеспечивается возможность принятия решений во время компиляции, а не во время выполнения. Часто это оказывается более эффективным подходом.

Для условной компиляции используется инструкция препроцессора if. Она имеет две формы - с частью else и без нее:

#if - заголовок

текстовые строки для случая " истина"

#endif

и

#if - заголовок

текстовые строки для случая " истина"

#else

текстовые строки для случая " ложь"

#endif

где if - заголовок является управляющей строкой препроцессора, а текстовые строки могут содержать произвольный текст. Управляющая строка препроцессора if-заголовка содержит условие, на основе анализа которого производится выбор соответствующих текстовых строк:

#if константное_выражение

Пример:

#ifdef ABC

Истина, если идентификатор ABC определен ранее

командой #define.

#ifndef идентификатор

Пример:

#ifndef ABC

Истина, если идентификатор ABC не определен

в настоящий момент.

#else

...

#endif

Если предшествующие проверки #if, #ifdef или #ifndef дают значение Истина, то строки от #else до #endif игнорируются при компиляции. Если эти проверки дают значение Ложь, то строки от проверки до #else, а при отсутствии #else - до #endif, игнорируются. Команда #endif обозначает конец условной компиляции.

Пример:

#ifdef DEBUG

fprintf (stderr, " location. X=%d\n", x);

#endif

 

При помощи команд препроцессора можно изменить номер текущей строки или имя компилируемого файла:

#line целая_константа " имя_файла"

Пример:

#line 20 " ABC"

Препроцессор изменяет номер текущей строки и имя компилируемого файла. Имя файла может быть опущено.

 

Замечание.

Хотя препроцессоры и расширяют возможности языков программирования, их использование не лишено недостатков: использование препроцессоров требует дополнительного просмотра текста программы и, как следствие, добавочного времени.

 

 

Лекция: Операции.

 

-Основные операции.

-Дополнительные операции.

-Перечень операций языка Си.

 

Основные операции

Рассмотрим способы обработки данных - для этого язык Си имеет широкий набор возможностей. Основные арифметические операции: сложения, вычитания, умножения, деления. Операции в языке Си применяются для представления арифметических действий. Например, выполнение операции + приводит к сложению двух величин, стоящих слева и справа от этого знака. Рассмотрим операции =, +, -, *, /. В языке Си нет операции возведения в степень.

 

Операция присваивания: =

В языке Си знак равенства не означает " равно". Он означает операцию присваивания некоторого значения. С помощью оператора

yar=2004;

переменной c именем yar присваивается значение 2004, т.е. элемент слева от знака = - это имя переменной, а элемент справа - ее значение. Мы называем символ = операцией присваивания. В этой операции действие выполняется справа налево.

Возможно, различие между именем переменной и ее значением покажется незначительным? В таком случае давайте рассмотрим следующий оператор:

i=i+1;

C математической точки зрения это бессмыслица. Если вы прибавляете единицу к конечному числу, результат не может быть равен исходному числу. Но как оператор присваивания, данная строка имеет вполне определенный смысл, который можно выразить, например, такой фразой. Взять значение переменной с именем i, к нему прибавить 1, а затем присвоить новое значение переменной с именем i.

Оператор вида

2004=yar;

на языке Си не имеет смысла, поскольку 2004 - число. Мы не можем присвоить константе какое-то значение; ее значением является она сама. Поэтому, помните, что элемент, стоящий слева от знака =, всегда должен быть именем переменной. Операнд - это то, над чем выполняются операции. Например, можно описать процесс " поедания" картошки как применения операции " поедание" к операнду " картошка".

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

/* таблица результатов по шахматам */

main( )

{

int l, m, n;

n=m=l=165;

printf(" l m n\n" );

printf(" Счет первой партии %4d %8d %8d\n", l, m, n);

}

Присваивания выполняются справа налево: сначала переменная l получает значение 165, затем переменная m и наконец n. В языке Си имеется несколько других операций присваивания, которые отличаются от описанной операции. Их мы рассмотрим попозже.

Представим еще один пример простой программы:

/* использование операции присваивания */

main( )

{

/* переменные number, ouzo, cost инициализируются конкретными значениями*/

int number=5;

float ouzo=13.5;

int cost=31000;

printf(" number ouzo cost\n" );

printf(" number=%d ouzo=%f cost=%d\n",

number, ouzo, cost);

}

 

Операция сложения: +

Выполнение операции + приводит к сложению двух величин, стоящих слева и справа от этого знака. Например, в результате работы оператора

printf(" %d", 100 + 65);

на печать будет выведено число 165, а не выражение 100+65. Операнды могут быть как переменными, так и константами. Операция + называется " бинарной ", или " диадической ". Эти названия отражают тот факт, что она имеет дело с двумя операндами.

Пример:

i=j+2;

Переменной i присваивается значение переменной j плюс 2.

 

Операция вычитания: -

Выполнение операции вычитания приводит к вычитанию числа, расположенного справа от знака -, из числа, стоящего слева от этого знака. Оператор

n = 163.00 - 100.00;

присваивает переменной n значение 63.00.

 

Операция изменения знака: -

Знак минус используется для указания или изменения алгебраического знака некоторой величины. Например, в результате выполнения последовательности операторов

teg = -15;

get = -teg;

переменной get будет присвоено значение 15. Когда знак используется подобным образом, данная операция называется " унарной ". Такое название указывает на то, что она имеет дело только с одним операндом.

Пример:

x = -x;

Операция изменяет алгебраический знак x.

 

Операция умножения: *

Операция умножения обозначается знаком *. При выполнении оператора

z = 3 * x

значение переменной x умножается на 3, и результат присваивается переменной z.

 

Операция деления: /

В языке Си символ / указывает на операцию деления. Величина, стоящая слева от этого знака, делится на величину, расположенную справа от этого знака. Например, в результате выполнения оператора

l = 126.0 / 2.0;

переменной l будет присвоено значение 63.0. Над данными целого типа операция деления производится не так, как над данными с плавающей точкой: в первом случае результат будет целым числом, а во втором - числом с плавающей точкой. В языке Си принято правило, согласно которому дробная часть у результата деления целых чисел отбрасывается. Это действие называется " усечением".

Рассмотрим пример, как выполняется усечение и чем деление целых чисел отличается от деления чисел с плавающей точкой:

main( )

{

printf(" деление целых: 5/4 это %d \n", 5/4);

printf(" деление целых: 6/3 это %d \n", 6/3);

printf(" деление целых: 7/4 это %d \n", 7/4);

printf(" деление чисел с плавающей точкой: 7./4. это %2.2f \n", 7./4.);

printf(" смешанное деление: 7./4 это %2.2f \n", 7./4);

}

Последний пример на использование смешанных типов, т.е. деление вещественного числа на целое. Язык Си менее строго подходит к подобным вопросам, и позволяет выполнять такие операции.

! Смешения типов следует избегать!

Результат выполнения указанной программы:

деление целых: 5/4 это 1

деление целых: 6/3 это 2

деление целых: 7/4 это 1

деление чисел с плавающей точкой: 7./4. это 1.75

смешанное деление: 7./4 это 1.75

Результат деления целых чисел округляется не до ближайшего целого, а всегда до меньшего целого числа. Когда мы смешиваем целые числа и числа с плавающей точкой, результат будет таким же, как если бы оба операнда были числами с плавающей точкой. В этом случае перед делением целое преобразуется в число с плавающей точкой.

 

Для того чтобы понять, что происходит в тех случаях, когда в одном операторе используется несколько операций, рассмотрим порядок выполнения операций. Совершенно очевидно, что изменение порядка выполнения действий может приводить к различным результатам. В языке Си каждой операции назначается уровень старшинства. Умножение и деление имеют более высокий уровень, чем сложение и вычитание, поэтому они выполняются первыми. Если же две операции имеют один и тот же уровень старшинства, они выполняются в том порядке, в котором присутствуют в операторе. Для большинства операций обычный порядок - слева направо. Операция = является исключением из этого правила. Многие программисты предпочитают представлять порядок вычислений с помощью дерева выражений. Например, выражение

(a+b)*c

будет выглядеть так:

*

/ \

+ c

/ \

a b

Мы можем составить таблицу правил описанных нами операций. В дальнейшем мы приведем таблицу, где содержатся правила, относящиеся ко всем операциям языка Си.

Таблица 1.1. Операции в порядке уменьшения уровня старшинства
Операции Порядок вычисления
( ) слева направо
- (унарный) слева направо
* / слева направо
+ - (вычитание) слева направо
= справа налево

Дополнительные операции

 

В языке Си имеется около сорока операций. Те операции, которые мы рассмотрели, являются наиболее общеупотребительными. Рассмотрим еще три операции, наиболее используемые программистами.

 

Операция деления по модулю: %

Эта операция используется в целочисленной арифметике. Ее результатом является остаток от деления целого числа, стоящего слева от знака операции, на число, расположенное справа от нее. Например, 63%5, читается как 63 по модулю 5, имеет значение 3, т.к. 12*5+3.

В результате выполнения оператора

minutes=time%60;

переменной minutes будет присвоено значение остатка от деления time на 60.

 

Операция увеличения: ++

Операция увеличения осуществляет следующее простое действие: она увеличивает значение своего операнда на единицу. Существуют две возможности использования данной операции: первая, когда символы ++ находятся слева от переменной (операнда), - " префиксная" форма, и вторая, когда символы ++ стоят справа от переменной, - " постфиксная" форма. Эти две формы указанной операции различаются между собой только тем, в какой момент осуществляется увеличение операнда. Префиксная форма изменяет значение операнда перед тем, как операнд используется. Постфиксная форма изменяет значение после того как операнд использовался.

В примере,

j=i++;

переменной j сначала присваивается значение i, затем значение переменной i увеличивается на 1.

 

Операция уменьшения: --

Каждой операции увеличения соответствует некоторая операция уменьшения, при этом вместо символов ++ мы используем --. Когда символы -- находятся слева от операнда - " префиксная" форма операции уменьшения. Если символы -- стоят справа от операнда - это " постфиксная" форма операции уменьшения.

В соответствии с принятым в языке Си порядком вычислений операции увеличения и уменьшения имеют очень высокий уровень старшинства. Только круглые скобки обладают более высоким приоритетом. Поэтому выражение a/b++ означает (a)/(b++), а не (a/b)++.

! Не применяйте операции увеличения или уменьшения к переменной, присутствующей в более чем одном аргументе функции. Не применяйте операции увеличения или уменьшения к переменной, которая входит в выражение более одного раза.

 

Перечень операций языка Си

 

Рассмотрим множество операций языка Си. Описанные операции входят в это множество. Язык Си отличается их большим разнообразием. В этом разделе будет обсуждаться их семантика. Каждая операция характеризуется уровнем приоритета и порядком, в котором эти операции выполняются - слева направо или справа налево. Если все операции выражения имеют один и тот же уровень приоритета, то значение выражения вычисляется слева направо в соответствии с порядком выполнения операций. Все операции с одним и тем же уровнем приоритета имеют один и тот же порядок. Однако если в выражении имеются операции с различными уровнями приоритета, то сначала выполняются операции с наивысшим уровнем приоритета, затем - следующего за ним приоритета и так далее в порядке убывания приоритета. Операции одного уровня приоритета выполняются в последовательности, указанной их порядком.

 


Поделиться:



Последнее изменение этой страницы: 2017-04-13; Просмотров: 830; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.14 с.)
Главная | Случайная страница | Обратная связь