Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Конспект_лекций_Ч_2.doc
Скачиваний:
26
Добавлен:
26.05.2015
Размер:
156.16 Кб
Скачать

Конспект лекций. 2 часть.

Тема 3.Язык программирования c. Реализация линейных алгоритмов.

Множество символов используемых в языке С можно разделить на пять групп:

  1. Прописные и строчные буквы латинского алфавита и символ подчеркивания;

  2. Группа прописных и строчных букв русского алфавита и арабские цифры;

  3. Знаки нумерации и специальные символы;

  4. Управляющие и разделительные символы. (пробел, символы табуляции, перевода строки, возврата каретки, новая страница и новая строка);

  5. Управляющие последовательности(начинается с обратной дробной черты (\) и комбинация латинских букв и цифр).

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

Компилятор допускает любое количество символов в идентификаторе, хотя значимыми являются первые 31 символ. Идентификатор создается на этапе объявления переменной, функции, структуры. Идентификатор не должен совпадать с ключевыми словами, с зарезервированными словами и именами функций библиотеки компилятора языка СИ.

Ключевые слова - это зарезервированные идентификаторы, которые наделены определенным смыслом. Их можно использовать только в соответствии со значением известным компилятору языка СИ.(например: char, extern, return, void, case, default, for и т.д.)

Константами называются перечисление величин в программе. В языке СИ разделяют четыре типа констант: целые константы, константы с плавающей запятой, символьные константы и строковыми литералы.

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

тип имя переменной [= значение];

Рассмотри подробнее каждый элемент синтаксиса переменной:

  • тип: размер выделяемой памяти;

  • имя переменной: любое английское название;

  • значение: (необязательный параметр) можно сразу присвоить определенное значение для нашей переменной;

Например:

int a,b,c; /* Объявляем три переменные типа int без указания имени */

float d = 2.01, f; /* Одну переменную просто объявляем, а вторую инициализируем значением */

В языке си ( с ) выделяют следующие типы переменных:

целочисленные: Тип

Диапазон значений

int

-128 по 127

char

32768 по 32767

long

-2 147 483 648 по 2 147 483 647

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

По диапазону значений можно узнать, сколько байт памяти занимает тот или иной тип:

printf ("%d",sizeof(char)); /* Выводим на экран размер выделяемый памятью под тип char. Он будет = 1*/

Вещественные: Тип

Диапазон значений

float

3.4*10-38- 3.4*10+38

double

1.7*10-308- 1.7*10+308

long double

очень много

А как сопоставляется выделяемая память и диапазон значений?

На пример, тип данных char, под который компьютер выделяет 1 байт. А 1 байт = 8 бит; получаем 28 = 256. Отсюда диапазон переменой от -128 до +127.

Имена переменных должны начинаться обязательно с буквы или символа подчеркивания "_". При чем в языке С/С++ имеется разница обычная или прописная буква.

Примеры идентификаторов:

_dlina, _DLINA; //два абсолютно разных имени.

fko14_w, len, aw_rw, SetLen;

Длина, которая отводится на имя переменной, зависит от вашего компилятора (все современные компиляторы поддерживают очень длинные названия).

Арифметические операции.

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

Бинарные операции

Операции

Запись

Сложение

a + b

Вычитание

a - b

Деление

a / b

Умножение

a * b

Нахождение остатка

a % b

Операции называются бинарными, если в них участвует два оператора.

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

int a = 4, b = 8;

printf ("%d",a+b); /* В результате получим значение 12 int -ового типа */

Унарные операции

Их всего две:

  • инкрементация:

  • yвеличение числа на единицу.

Например:

int i = 6;

i++; // инкрементация

i = i + 1; // эквивалентна инкрементации

Обратные унарные операции:

  • декриментация:

  • уменьшение числа на единицу.

Например:

int i = 6;

i--; // декрементация

i = i - 1; // эквивалентна декрементации

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

Но есть еще очень важный момент. Инкрементация и декрементация бывает префиксной и постфиксной:

int a = 5;

printf ("%d", ++a); // Выведет 6

printf ("%d", a++); // Выведет 5

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

Арифметические выражения

Арифметические выражения, стоящие в правой части оператора присваивания, могут содержать:

  • целые и вещественные числа (в вещественных числах целая и дробная часть разделяются точкой, а не запятой, как это принято в математике)

  • знаки арифметических действий:

+ — сложение, вычитание

/ умножение, деление

% остаток от деления

  • вызовы стандартных функций

abs(i) модуль целого числа i

fabs(x) модель вещественного числа x

sqrt(x) квадратный корень из вещественного числа x

pow(x,y) вычисляет x в степени y

  • круглые скобки для изменения порядка действий

Особенности арифметических операций.

При использовании деления надо помнить, что при делении целого числа на целое остаток от деления отбрасывается, таким образом, 7/4 будет равно 1. Если же надо получить вещественное число и не отбрасывать остаток, делимое или делитель надо преобразовать к вещественной форме.

Например:

int i, n;

float x;

i = 7;

x = i / 4; // x=1, делится целое на целое

x = i / 4.; // x=1.75, делится целое на дробное

x =(float) i / 4; // x=1.75, делится дробное на целое

n = 7. / 4.; // n=1, результат записывается в целую переменную

Наибольшие сложности из всех действий вызывает взятие остатка. Если надо вычислить остаток от деления переменной a на переменную b и результат записать в переменную ostatok, то оператор присваивания выглядит так:

ostatok = a % b;

Приоритет арифметических операций

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

  • операции в скобках, затем…

  • вызовы функций, затем…

  • умножение, деление и остаток от деления, слева направо, затем…

  • сложение и вычитание, слева направо.

Например:

2 1 5 4 3 8 6 7

x = ( a + 5 * b ) * fabs ( c + d ) — ( 3 * b — c );

Сокращенная запись арифметических выражений

Если мы хотим изменить значение какой-то переменной (взять ее старое значение, что-то с ним сделать и записать результат в эту же переменную), то удобно использовать сокращенную запись арифметических выражений:

Сокращенная запись

Полная запись

x += a;

x = x + a;

x -= a;

x = x - a;

x *= a;

x = x * a;

x /= a;

x = x / a;

x %= a;

x = x % a;

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

В компьютер изначально заложена булева логика, т.е. все числа преобразуются к 0 и 1.

В логических операциях 0 - это FALSE, а 1 - это TRUE. Эти понятия TRUE и FALSE тесно связанны с операциями сравнения:

Операция

значение

пример

==

равенство

a == b

!=

не равно

a != b

>

больше

a > b

<

меньше

a < b

<=

меньше или равно

a <= b

>=

больше или равно

a >= b

В принципе, самая распространенная ошибка, которую делают новички - это путают операцию присваивания (=) с операцией сравнения (==). Это абсолютно разные вещи.

Операции сдвига.

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

Сдвиг влево соответствует умножению первого операнда на степень числа 2, равную второму операнду, а сдвиг вправо соответствует делению первого операнда на 2 в степени, равной второму операнду.

Например:

int i=0x1234, j, k ;

k = i<<4; /* k = 0x0234 */

j = i<<8; /* j = 0x3400 */

i = j>>8; /* i = 0x0034 */

Преобразование типов

При выполнении операций происходят неявные преобразования типов в следующих случаях:

- при выполнении операций осуществляются обычные арифметические преобразования;

- при выполнении операций присваивания, если значение одного типа присваивается переменной другого типа;

- при передаче аргументов функции.

Преобразования при приведении типов. Явное преобразование типов может быть осуществлено посредством операции приведения типов, которая имеет формат:

( имя-типа ) операнд .

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

Подробнее рассмотрите материал в электронном учебнике:

http://citforum.ru/programming/c/dir.shtml

Функция printf().

Практически во всех примерах на си встречается функция printf. Функция printf() требует указания типа данных нужно выводить.

Например:

int i = 10;

float b = 12.5;

printf ("%d\n", i);

printf ("%f\n", b);

Спецификаторы формата

Вывод целых чисел:

спецификатор

для чего

%d

для вывода целых чисел в десятичной форме

%u

для вывода целых чисел в десятичной форме без знака

для вывода целых чисел без знака в восьмеричной форме

для вывода целых чисел без знака в шестнадцатеричном формате

Например:

int a = 16;

printf ("%d %o %x",a,a,a); // Вывод на экран: 16 10 20

Т.е. принцип этой функции заключается в следующем: в кавычках пишите нужные спецификаторы формата (ровно столько, сколько нужно вывести переменных); далее после кавычек ставите запятую и перечисляете, так же через запятую, все переменные для вывода в том порядке, в каком вы выставили спецификаторы формата.

Вывод вещественных чисел:

спецификатор

для чего

%f

для вывода вещественных чисел в обычной форме

%e

для вывода вещественных чисел в экспоненциальной форме

Например:

double a = 16;

printf ("%f %e",a,a); // Вывод на экран: 16.000000 1.600000е+01

Число (в экспоненциальной форме): 1.600000е+01 означает всего лишь 1.6 * 10 1

После написания знака (%) можно сразу же указать количество выводимых знаков вещественной составляющей числа.

double a = 16;

printf ("%.3f %.1e",a,a); // Вывод на экран: 16.000 1.6е+01

Управляющие последовательности выводом:

'\n' перевод на новую строку

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

'\a' сигнал

'\r' курсор в начало строки возвращается

'\'' вывод одиночной кавычки

'\"' вывод двойной кавычки

'\\' вывод косой черты

Примеры с бинарными арифметическими операциями переменных с разным типом данных.

#include <conio.h>

#include <stdio.h>

int main(int argc, char* argv[])

{ int a = 5; // 2 байта

float b = 3; // 4 байта

double c = 2; // 8 байт

char d = 'a'; // 1 байт

printf ("%d\n",sizeof(a+b)); /* 4 байта, следовательно тип float */

printf ("%d\n",sizeof(b+c)); /* 8 байт, следовательно тип double */

printf ("%d\n",sizeof(a+d)); /* 2 байта, следовательно тип int */

getch();

return 0;

}

Функция sizeof()

Функция sizeof() возвращает количество байт, которые память выделяет под переменную. При сложении переменных разных типов, при выходе получается переменная большего из типов. Для переменных типа char: символы, которые она хранит, имеют целочисленный код, поэтому при сложении ни каких проблем не возникает.

Операция - нахождение остатка:

int a = 5, b = 2;

a = a % b; // Значение а будет равно 1

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

Функция scanf().

В языке Си кроме функции вывода printf(), существует так же функция scanf() для ввода данных.

Например:

int i;

scanf("%d", &i);

В двойных кавычках записывается спецификатор формата во второй части функции записываем знак (&)-этот знак означает взятие адреса.

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

Спецификаторы формата

%d - прочитать целое число,

Пример:

int i;

scanf ("%d", &i);

%o - прочитать восьмеричное число

Пример:

int i;

scanf ("%o", &i);

%x - прочитать шестнадцатеричное число

Пример:

int i;

scanf ("%x", &i);

%e(%f) - прочитать вещественное число

Пример:

float t;

scanf ("%f", &t);

%с - прочитать символ

Пример:

char ch;

scanf ("%c", &ch);

%s - прочитать строку

Пример:

char *str;;

scanf ("%s", str);

Пример первой программы.

#include <conio.h> /* содержит функции для работы с экраном */

#include <stdio.h> /* файл содержит функции ввода/вывода */

int main() /* Функция, с которой начинается выполнение программы */

{ char s;

scanf ("%c", &s); // функция ввода

printf (" Символ: %c\tСтрока: %d\n",s,s); // функция вывода

getch(); /* функция ввода символа с клавиатуры. Используется для задержки выполнения программы */

return 0; /* Функция main() имеет возвращаемое значение типа int. Вот функцией return и возвращаем нужное значение /*

}

Все надписи, которые заключены в '/* */' или '//' знаки являются комментариями. Подробнее о комментариях вы можете узнать из этой статьи: Комментарии.

/* #include означает 'включение' файла в наш файл */

Функции.

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

Функция - это совокупность объявлений и операторов, обычно предназначенная для решения определенной задачи.При вызове функции ей при помощи аргументов (формальных параметров) могут быть переданы некоторые значения (фактические параметры), используемые во время выполнения функции.Функция может возвращать некоторое (одно !) значение(результатДопускается также использовать функции не имеющие аргументов и функции не возвращающие никаких значений.).

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

Все, что входит в функцию main должно быть заключено в фигурные скобки.

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

Файл stdio.h в примере программы подключается для реализации функций ввода и вывода. А файл conio.h необходим для реализации функции getch(). Она как раз просит ввести пользователя любой символ, который нам абсолютно не нужен, но зато мы получаем задержку на ожидание ввода и можем увидеть на экране результат предыдущих функций.

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

#include <conio.h>

#include <stdio.h>

int main()

{

/* вставлять код сюда */

getch();

return 0;

}

Операторы языка С.

Все операторы языка СИ могут быть условно разделены на следующие категории:

- условные операторы, к которым относятся оператор условия if и оператор выбора switch;

- операторы цикла (for,while,do while);

- операторы перехода (break, continue, return, goto);

- другие операторы (оператор "выражение", пустой оператор).

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

Все операторы языка СИ, кроме составных операторов, заканчиваются точкой с запятой ";".