Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции (Ведищев) + шпоры к экзамену / лекции по программированию за 1 курс.doc
Скачиваний:
174
Добавлен:
20.06.2014
Размер:
805.38 Кб
Скачать

Язык программирования с.

Элементы языка.

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

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

  1. Алфавит.

Состоит из латинских букв строчных и прописных (от A до Z)и цифр (от 0 до 9). Строчные и прописные буквы – различные символы.

Комментарии:

/*…*/

//…

\t – табуляция

\l –возврат каретки

\v –вертикальная таблица

\n –новая строка

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

Разделители(:?)

Являются частью оператора. Результат 2-го или 3-го операнда, в зависимости от значения «истина» или «ложь» 1-го операнда.

‘ – ограничитель символьной константы

“ – ограничитель строковой константы

! – логическое отрицание

Для хранения значений логических выражений используются целые значения (0-ложь, все остальные - истина).

А

А

0

1

1

0

!5=0

!0=1

(!) – логическое или (логическое сложение, дизъюнкция)

A

B

A|B

0

0

1

1

0

1

0

1

0

1

1

1

| - побитовое «или»

|| - логическое «или»

5|7=12

101|111=1111

8|5=13

1000|0101=1101

/ - целочисленное деление через конструкции комментариев

5/3=1

\ - часть конструкции, задающая специальный символ

~ - побитная инверсия (тильда)

~5=.65630

Замечание: отрицательных целых констант нет. Используется выражение из унарного минуса и положительного целого.

- символ используется наравне с буквами

_ - смысловой разделитель

( ) – для изменения приоритета операции в выражении

А( ) – указывает, что идентификатор имя функции

{} – начало и конец группового оператора. Тело функции – групповой оператор.

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

[] – используется для доступа к элементам массива по их индексам, используется при описании массива для определения количества по данной размерности

int A[4][3] – матрица 4х3

# - начало директивы препроцессора

% - деление по модулю (определение остатка по целочисленному делению)

48%45=3

используется в стандартных функциях потока ввода, вывода (scanf, printf), для обозначения спецификатора ввода, вывода

& - логическое «и» (конъюнкция, логическое умножение)

А

В

А&B

0

0

1

1

0

1

0

1

0

0

0

1

&& -логическое «и»

& - побитовое «и»

5&7=5

Унарная операция взятия адреса

&x – значение адреса в формате текущей адресации

int X[4][3] – идентификатор массива

& X[0][0]=X - первый элемент массива

^ - исключающее «или»

A

B

A^B

0

0

1

1

0

1

0

1

0

1

1

0

- - бинарная операция вычитания (унарная операция смены знака), унарный минус

= - оператор присваивания (часть операции отношения)

+ - сложение

- бинарная операция умножения (операция определения значения по адресу)

int X[4][3]

X= X[0][0]

Замечание:

В соответствии с правилом образования идентификатора типа матрица 4х3 определяется как массив из 4 элементов, каждый из которых является массивом из 3-х элементов, каждый из которых предназначен для хранения целого значения. Запись *х означает значение адреса начала нулевой строки.

>> - операция побитового сдвига вправо

<< - операция побитового сдвига влево

1>>1=0

1<<1=2

\b – шаг назад

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

\r – возврат каретки (перевод на начало строки)

\f – новая страница

\a – звуковой сигнал

\’ – обозначение одиночной кавычки

\” – обозначение кавычек

\\ - обратный слеш

‘ - апостроф

“ – ограничение строки. Также в программе имеется возможность обозначать нетерминальные символы, для этого используется их код из таблицы кодирования ASCII, KOH-7, KOH-8.

Код символа –порядковый номер в таблице кодирования.

Операции.

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

10<<2=40

10>>2=2

Операции отношения.

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

Z – признак 0

N – признак отрицательного результата

a>b a-b>0 N= 0 Z=0

a<b a-b<0 N= 1 Z=0

a= =b a-b=0 N= 0 Z=1

a>=b a-b>=0 N= 0 Z= или N=0 Z=1

a<=b a-b<=0 N= 1 Z=0

a!=b a-b !=0 N= Z=0

, - операция последовательного выполнения

в языке С каждое значение имеет выражение равное результату вычисления выражения.

2+3 имеет значение 5

х=2 имеет значение 2

Вместо 1-го выражения можно использовать последовательность выпажений, разделенных запятыми. Результат – значение последнего выражения.

Х=2, н=3 будет иметь значение 3.

Отличие оператора присваивания С от Паскаля:

В Паскале эта операция чисто переноса значения, в С также сохраняется результат.

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

For (i=0,j=10…)

?: - условная тринарная операция.

<оператор 1>?< оператор 2>:< оператор 3>

Если в результате 1 – «истина», выполняется 2-ой операнд, «ложь» - 3-ий операнд

Результат – вычисленное значение 2-го или 3-го.

<x>0>?<|x|=x>:<|x|=-x>

если требуется заменить значение х , то третий операнд заменяем на х=-х

х=5&7=5

y=5&&7=1 (истина)

++ - инкремент – увеличение на 1

различают:

прединкремент (++ перед переменной) – результат изменяется на 1, переменная меняется на 1

постинкремент (после переменной ++) - результат значение переменной до увеличения, переменная меняется на 1

а=0

в=а++

с=++в

а=в=с=1

-- - декремент (--а – преддекремент; а-- - постдекремент)

к=10

l=--k—

n=--l—

k=8 l=7 n=8

x=15

y=-- --x++ ++

x=15 y=13

= - присваивание. Значение правого операнда присваивается левому операнду. Значение, хранящееся по адресу правого переносится в место хранения левого операнда. Машинный язык: команда переслать. Накладываются ограничения на вид операндов. Левый операнд должен являться 1-value выражением.

Значение может состоять в левой части оператора присваивания. L-value – выражение специфицирует место, в которое может быть записано выражение.

Например, вызов функции не является 1-value выражением. В правой части должны стоять r-value выражения, то есть выражение, имеющее конкретное значение, которое можно использовать.

Например, строка массива не является r-value выражением, поэтому значения массивов можно переносит только перед присваиванием значения каждого элемента массива.

В качестве левого операнда в С можно использовать адрес функции (вместо строки – адрес строки)

Char *s=”aбв” - хранит адрес строки из 4 символов abc\0.

В s хранится адрес строки (адрес буквы а).

Char с;

С=*s (в с запишем букву «а»)

C1=*(s+2) (в с1 запишем букву «в»)

*s=«х» (замена символа «а» на «х», строка «хбв»)

qsort – быстрая сортировка, в этой функции адрес сравнения 2-х элементов

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

+=

-=

*=

/=

%=

>>=

<<=

*- доступ к значению, хранящегося по адресу

& - определить значение, хранящееся по адресу

объявим р как указатель на целое, х как целое

int *p;

int x;

x=1;p=&x;

printf (“%d”,*p);

sizeof – определение размера памяти в байтах, занимаемой операндом. В качестве операнда имя типа, имя переменой. Sizeof(int) во всех случаях, когда требуется использовать константы равные объему памяти, рекомендуется использовать операцию sizeof.

Пример: требуется сохранить информацию об аттестации студенческой группы. Количество студентов от 8 до 9 человек, количество предметов от 9.

Применяют динамическое распределение памяти. Объявляют указатель на значение типа int. Пользователь вводит количество студентов и предметов.в программе вызывается функция выделения памяти, которой необходимо указать точное количество байт, требуемых для хранения информации. Количество байт=число строк* количество столбцов* sizeof(int)

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

Х= sizeof(int)=2 – 2 байта

Приоритет операций и порядок их выполнения.

Группирование операндов и последовательность их выполнения определяются приоритетом и ассоциативностью операций языка С. Ассоциативность влияет на выполнение операций одинакового приоритета.

A>B (А более первично, чем В)

C=D (D более первично, чем С)

Операции в порядке убывания приоритета:

Первичные:

  • Ассоциативность слева направо

  • Вызов функции f( )

  • Индексация элементов массива x[i]

  • Взятие элементов структуры

  • Взятие элемента структуры на ссылке (p→b(*p).b)\унарные^

Унарные:

  • Ассоциативность справа налево

  • УНАРНЫЙ МИНУС –

  • ИНВЕРСИЯ

  • ВЗЯТИЕ АДРЕСА &

  • Инкремент++

  • Декремент –

  • Ретипизация (приведение значения к определенному типу (type))

  • Sizeof

Мультипликативные:

  • Ассоциативность слева направо

  • *, /, %

Аддитивные:

  • Ассоциативность слева направо

  • Сложение, вычитание

Сдвига:

  • Ассоциативность слева направо

  • Сдвиг вправо, влево (>>,<<)

2 1 5 4 3 6

-_-x+-_-y+a

Отношения:

  • Ассоциативность слева направо

  • <,>,>=,<=,!=,=

единственные операции:

  1. поразрядное «и» &

  2. исключающее «или»^

  3. поразрядное «или» | 1-5 слева направо

  4. логическое «и» &&

  5. логическое «или» | |

  6. условная тринарная операция справа налево

  7. простое и составное присваивание справа налево

  8. последовательное вычисление слева направо

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

(а+в)+с=а+(в+с)

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

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

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

Пример, (а=3,а++,а=0), а=0.

Замечание.

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

F(i=1,i++,i++) любые значения из множества 1,2,3, при этом 2 и 3 могут быть заменены любым значением из оперативной памяти, такого рода вызовы использовать нельзя.

Логические операции обеспечивают порядок вычислений, но при этом могут вычисляться только операнды, влияющие на конечный результат.a||b||c. При а!=0 выражение b||c рассматриваться не будет. Данный подход к вычислению логических выражений позволяет повысить эффективность вычислений за сет смещения операндов с наиболее вероятным результатом в начало выражения. Это позволяет включать в выражение проверку, останавливающую дальнейшее вычисление.

F(x)&&G(y)

F(x)+G(y) будут вызваны обе функции.

Замечание.

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

Побочные эффекты.

Выражаются в неявном изменении значений переменной в ходе вычисления выражения.

Вызывать операциями присваивания.

Вызов функции, которая изменяет значение внешней переменной, через ссылку или присваивание.

Порядок вычисления выражения зависит от реализации компилятора и гарантируется только в вышеозначенных функциях. – примеры побочных эффектов.

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

Контрольные точки:

- операции последовательного вычисления;

- условные

- логическое «и»

- логическое «или»

- вызов функции

- конец полного выражения , то есть выражение, которое не является частью другого

также конец инициализированного выражения для переменной класса памяти «авто». И конец выражения управления операторов if, switch,while,do,for.

add(i+1;i=j+2) – использовать нельзя

единица может быт прибавлена к i до или после операции присваивания.

i-целая переменная, а – вектор из 10

i=0, a[i++]=I использовать нельзя либо 1, либо 0

Операции преобразования типов выполняются либо неявно (по умолчанию), либо явно с помощью операций преобразования типа явного.

(int )x (х привести к типу целого).

Всегда фактические параметры функции преобразуются к типу формальному, что требует от программиста контроля совпадения типов. В Pascal транслятор контролирует совпадения.

Тип float всегда преобразуется в double, подтип целого в int. Символы хранятся в 2 байтах.