Вы находитесь на странице: 1из 53

ПЯВУ. Лекция 1.

Основы С
А.М. Задорожный
Содержание
1. Введение. Почему C.
2. Анализ программы “Hello, World!” на C
3. Процесс построения программы на C
4. Понятие переменной
5. Типы данных. Числовые типы
6. Консольный ввод
7. Оператор if и булевские величины
Структура семестра
Изучим 2 языка:
- С
- С++
Именно в такой последовательности…
‘Изучим’ – слишком сильно.
Но будем понимать настолько, чтобы
создавать простые программы и осваивать
программирование в дальнейшем
самостоятельно.
Когда и как возник
Разработан ~1970 г Д. Ритчи для написания ОС Unix
(прототип всех linux).

В это время уже был Pascal, разработанный Н.Виртом,


одна из целей
– обучение программированию.

C – разработан
программистами для программистов!

Чтобы легко освоить, лучше перенять их образ мыслей!


Почему C
Существует много языков программирования.

Распространены:
C#, Python – изучим во втором семестре,
Java, JavaScript, Kotlin, Go … Появляются новые!

Предполагают наличие развитой операционной


системы: файлы, одновременно несколько
задач, часто среду исполнения программы, …
Почему C
Как быть с микро-программированием?
В устройстве нет ОС, нет встроенного
интерпретатора JavaScript или Python?

Ни один из упомянутых языков неприменим в:


- графических видеокартах PC;
- блоках управления зажиганием и стабилизацией
автомобиля;
- медицинских датчиках;
- научной электронике;
- …
Почему C
Язык должен быть:
- Простым, что бы легко разработать
компиляторы для разных платформ;

- Получаемый код максимально


эффективным;

- Переносимым, платформонезависимым;
Почему C
Таким и оказался C.
• Простым: самый короткий синтаксис (3
базовых типа, минимальное число
зарезервированных слов) ;
• Эффективным: практически, близок к
ассемблеру;
• Имеет встроенные средства достижения
платформенной независимости.
Как будем изучать?
Удачный синтаксис стал основой многих
языков, в частности С++, C#, с которыми вы
познакомитесь во втором семестре!

Наиболее эффективный способ -


анализировать простые программы и
разбираться как они работают!
Простейшая программа
Содержание файла main.c

#include <stdio.h>

int main(int argc, char** argv)


{
printf("Hello, World!\n");
return 0;
}
Это блок {}

При выполнении этой программы на консоли появится текст “Hello,


World!”
Простейшая программа
Содержание файла main.c
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello, World!\n");
return 0;
}
• Количество пробелов, пустые строки не играют роли!
• Языке чувствителен к регистру. printf и Printf – разные
имена!
• Команды завершаются точкой с запятой – ‘;’.
Простейшая программа
Построчный анализ
#include <stdio.h>
// # - инструкция препроцессора
// Включить заголовочный файл “stdio.h”
// stdio – стандартный ввод/вывод
int main(int argc, char** argv)
{
printf("Hello, World!\n");
return 0;
}
Простейшая программа
Построчный анализ
#include <stdio.h> // включить файл
// main - главная функция
// с нее начинается выполнение программы.
int main(int argc, char** argv)
{
printf("Hello, World!\n");
return 0;
}
Простейшая программа
Построчный анализ
#include <stdio.h> // включить файл
int main(int argc, char** argv) // main
{
// функция вывода на консоль
// printf – функция печати. Описана в stdio.h
printf("Hello, World!\n");
return 0;
}
Простейшая программа
Построчный анализ
#include <stdio.h> // включить файл
int main(int argc, char** argv) // main
{ // вывод на консоль
printf("Hello, World!\n");

// выйти их функции и вернуть 0


return 0;
}

В ОС можно проверить возвращенный программой код. 0 – по


соглашению “Все ОК”.
Простейшая программа
Синтаксические ошибки
1. int Main(int argc, char** argv) // main

2. printf("Hello, World!\n") // ;

3. int main(int argc, char** argv){


printf("Hello, World!\n");
}
return 0; // вне блока

4. int main(int argc, char** argv){


printf("Hello, World!\n")
return 0;
}} // лишняя }
Процесс построения
программы на С
Процесс построения программы на C
стандартизован и включает 3 шага:

1. Предварительная обработка
(препроцессирование)
2. Компиляция
3. Сборка
Процесс построения
программы на С
Препроцессирование

На этом шаге обрабатываются текстовые *.c и *.h файлы


И выполняются все инструкции препроцессора – они
начинаются с первой позиции со значка #.

include – включить файл в текст программы.

Результат предварительной обработки – текстовый файл на


языке C (но уже без инструкций препроцессора).

Результат препроцессирования передается компилятору.


Процесс построения
программы на С
Компиляция
Компилятор обрабатывает каждый c-файл отдельно и
независимо друг от друга.

В результате компиляции каждого файла возникает


т.н. объектный файл - *.obj. В нашем случае “main.obj”.

В нем уже содержатся команды для компьютера,


ссылки на внешние переменные и функции и пр.

На этом шаге и выявляются синтаксические ошибки.


Процесс построения
программы на С
Сборка

На шаге сборки из объектных файлов программы и


стандартных библиотек собирается выполняемая
программа.

Точкой входа (точкой начала исполнения) назначается


функция main.

На этом шаге в основном и выявляются ошибки сборки:


отсутствует main или имеется 2 main, не найдены некоторые
функции (printf) или глобальные величины.
Процесс построения
программы на С
Сборка
HelloWorld.exe
До сборки
main.obj main

printf
printf.obj

1. Объединили модули
2. Подставили адрес вызова (стрелка) printf
3. Назначили точкой входа (звездочка) main
Процесс построения
программы на С
Рассмотренные шаги необходимо иметь ввиду
при разработке программы.

По сообщениям об ошибках построения можно


понять на каком этапе возникла проблема!
Это определяет и путь исправления.

Например, в VS ошибки сборки отмечены – L…,


а ошибки компиляции – C….
Контрольные вопросы
1. Какого типа инструкции входят в c-файл?
2. Из каких шагов состоит процесс
построения программы на C?
3. Опишите содержание (выполняемые
действия) и результат каждого шага
сборки программы.
4. Назовите основные синтаксические
правила ‘C’.
Объявление переменных
Переменная – место для хранения данных в
программе.
Переменная сначала должно быть объявлена, а
потом может использоваться.
Примеры:
int x; // int – тип данных. Числа целого типа х
// Теперь можно x = 2 + 3…
3
int x = 3; // Выделить место и поместить туда 3 х
int x = 3, y = 5; // 2 переменных
5 целого типа
3
х y
Объявление переменных
Объявление переменной – команда компьютеру во время
исполнения программы:
“Выдели место в памяти”.
В тексте программы мы обращаемся к этому месту по имени
переменной.

Общее правило объявления переменных


<тип данных> <имя_переменной>[=<начальное значение>] [, …];
Язык описания синтаксических конструкций.
То, что указано в угловых скобках <> – означает подстановку
фактического значения.
То, что в квадратных [] – может быть, а может не быть!
Остальное как есть.
Переменные и операция присваивания

Значение переменной при выполнении


программы может быть изменено!
Операция присваивания:
<имя_переменной> = <выражение>;
Например,
int x = 3, y = 5;
x = 2*x + y;
В память переменной x будет помещено значение
выражения 2*x + y, т.е. 11.
Переменные и операция присваивания
Присваивание - не то же самое, что равенство в алгебре.
x = y; - не то же самое, что y = x.
В первом случае значение y будет помещено в память x, а во
втором, значение x в память y.

Более наглядно было бы изобразить присваивание как


x <= y или x <- y,
но практичнее оставить как есть.

Слева от знака операции = всегда стоит имя переменной, в


которую будет помещено новое значение!
Вывод на консоль
printf - довольно сложна для новичков функция.
Обязательный первый параметр – строка. Она управляет
выводом остальных параметров.
Правила, по которым интерпретируется строка
форматирования в printf:
• Обычный текст выводится ‘как есть’. - printf("Hello,
World!\n"); выведет Hello, World!
• В те места, где стоит комбинация %<код>, будут
подставляться последующие параметры в порядке
появления (см. примеры ниже).
• Количество позиций подстановки должно совпадать с
количеством параметров.
Вывод на консоль
примеры
Пока научимся выводить целые числа.
int x = 13;
printf(“%d”, x);
Выведет на консоль 13.
%d – код для вывода целых в десятеричном представлении (от decimal).
printf(“%d, %o, %x\n”, x, x, x);
Здесь 3 позиции для подстановки и 3 параметра (все одинаковые - x).
Каждый параметр будет выведен в соответствии с кодом: d –
десятеричный, o – восьмеричный (от octal) и x – шестнадцатеричный
(от heXadecimal) вид/представление целого.
‘\n’ - код перевода на новую строку.
Итого увидим:
13, 15, d
Контрольные вопросы
1. Что такое переменная?
2. Опишите правила объявления переменных в C.
3. Является ли объявление переменной командой для
компьютера?
4. Как выглядит на C операция присваивания?
5. Является ли присваивание командой для компьютера?
6. Какая функция в C используется для вывода на консоль?
7. Опишите строку форматирования вывода.
8. Какие коды вывода рассмотрены в лекции?
Упражнение
Разработайте программу, реализующую алгоритм
обмена значениями двух переменных целого типа.

Значения переменных задавайте прямо в тексте


программы.

Для проверки и вывода на консоль используйте


команды
printf(“%d %d”, x, y);
Внимание к данным
В программировании организация данных играет
ключевую роль.

Остановимся на понятии Тип данных.


Тип данных определяет:
- какие значения могут принимать величины этого типа
- и какие операции над ним можно выполнять.

C – типизированный язык. Это означает, что каждая


переменная должна иметь определенный тип.
Тип данных
В C имеется минимальное количество встроенных типов данных.

Мы уже сталкивались с типом int (от англ. ineger - целое)


Какие значения…
Величины этого типа принимают целочисленные значения от
примерно -2*109 до +2*109.
В памяти занимают 4 байта.
Операции…
• Как и к большинству типов к целым можно применять операцию
присваивания! ( = )
• К ним можно применять арифметические операции: +, -, *, /.
(См. продолжение)
Тип данных
целые
Деление целых имеет в C некоторую особенность – в результате
деления целых чисел получается целое, дробная часть
отбрасывается!
Т.е. результатом 5/3 будет 1!
Остаток от целочисленного деления можно получить операцией %.
Результатом 5%3 будет 2.
Унарные операции (операции к одной переменной). К
целочисленной переменной применяются операции ++ и --.
++ - увеличивает значение переменной на 1, -- - уменьшает на 1.
Так, если x равно 3, то после
x++;
x станет равным 4, а после x--; - снова 3.
Тип данных
целые
В программах часто встречаются команды вида
x = x + <целое>;
Выполняется эта команда так: сначала вычисляется правая часть
операции присваивания и полученное значение помещается в
переменную, указанную в левой части, т.е. опять в x.
В C существует сокращенная версия такой команды (+=):
x += <целое>;

Имеются и сокращенные версии с другими операциями:


x -= <целое>;
x *= <целое>;
x /= <целое>;
x %= <целое>;
Тип данных
целые
Вполне аналогично типу int ведут себя и другие
целочисленные типы: short, long, char.
Их различие в объеме памяти, которая отводится под
переменную.
Самый маленький тип char – 1 байт, short – 2 байта и long – 8.
Соответственно объему памяти меняется и диапазон
возможных значений каждого типа – удвоение памяти
соответствует возведению в квадрат максимального значения
в диапазоне.
char – 255, short – 65535, int – 2-х миллиардов, …
Точные значения помнить не нужно (кроме байта) – их всегда
можно вычислить, но порядок величин знать полезно.
Тип данных
числа с плавающей точкой
Кроме целых чисел в C имеются и числа ‘с плавающей точкой’.
Смысл названия поймем позже, а по существу, такие
переменные предназначены для хранения дробных чисел.
В C таких типов 2: float и double. Float занимает 4 байта, а
double – 8.
Пример объявления и инициализации чисел double.
double x = 3.14;
С ними можно выполнять: присваивание =, +, -, *, /, а также
унарные операции +=, -=, *=, /=. Операции ++, -- и % к числам с
плавающей точкой не применимы.
Диапазон этих чисел огромен. Double по модулю могут быть от
10-200 до 10200.
Тип данных
числа с плавающей точкой
Для вывода числе с плавающей точкой применяется формат %f или более
точный %g.
Например:
double x = 3.14;
printf(“%f, %g”, x, x);
Если операции с целыми всегда точны, то операции с числами типа double
и float, хотя и имеют высокую точность, но имеют погрешность.
В этом можно убедиться, изучая пример:
double x = 1, y = 0.3;
printf("%f - 3*%f - 0.1 = %g", x, y, x - 3 * y - 0.1);
В результате мы увидим
1.000000 - 3*0.300000 - 0.1 = 8.32667e-17
Т.е., математически должны получить 0, но получили число 8.2*10 -17 –
маленькое, но отличное от 0.
Консольный ввод
Для ввода данных с консоли в C имеется функция scanf.

Определена scanf в том же заголовочном файле – “stdio.h”


Пример чтения с консоли значения в целочисленную пеоеиенную
при помощи scanf.
int x;
scanf("%d", &x);
printf("x = %d", x);
Коды для чтения целых аналогичны кодам для вывода.
Обратите внимание на знак & перед именем переменной в scanf.
Ставить его обязательно! Но смысл мы поймем позже.
Консольный ввод
При чтении чисел с плавающей точкой имеется еще одна особенность.
Пример для чтения числа с плавающей запятой.
float y;
scanf("%f", &y);
printf("y = %f", y);
Здесь коды чтения аналогичны кодам printf.

Но для double перед кодом нужно ставить латинскую l (от анг. long):
doublle y;
scanf("%lf", &y);
printf("y = %f", y);
Тип данных
числовые типы, итог
И так, в C имеется 3 группы числовых типов данных –
целочисленные и с плавающей точкой.

Целочисленные имеют небольшой диапазон, но все


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

Числа с плавающей точкой имеют огромный диапазон, но


операции выполняются приближенно (точность double
примерно 17 знаков).
Такие числа вполне годятся для расчетов.
Контрольные вопросы
1. Какие характеристики данных определяет Тип данных?
2. Что значит утверждение “C – типизированный язык”?
3. Какие 2 группы числовых типов рассмотрены в лекции?
Приведите примеры каждой группы.
4. Охарактеризуйте целочисленные типы? (множество
значений, операции, особенности)
5. Охарактеризуйте типы с плавающей точкой? (множество
значений, операции, особенности)
6. Какие коды для вывода на консоль целых и с плавающей
точкой упоминались в лекции?
7. Какая функция в C используется для ввода данных с
консоли?
Программы могут принимать решения
До сих пор наши программы выполнялись последовательно, т.е. каждая
команда выполнялась и выполнялась только 1 раз. Возможны и другие
варианты вычислений.
Пусть необходимо вычислить модуль числа x.
Тогда, если x >= 0, то его значение и есть модуль x, но если x < 0, модуль равен –
x.
Для подобных ситуаций в C имеется оператор if. Вот как он сработает в данном
случае:
int x, mod;
scanf(“%d”, &x);// прочли x
if (x >=0) // вычислили mod
mod = x;
else
mod = -x;
printf(“mod(%d) = %d ”, x, mod); // вывели результат
Оператор if
if (x >=0)
mod = x;
else
mod = -x;
Опишем синтаксис оператора if и порядок его исполнения.
Начинается с ключевого слова if. Затем круглые скобки, в которых стоит
условное выражение.
Далее идет первый блок операторов.
Затем ключевое слово else (англ. иначе).
За else следует второй блок операторов.
При исполнении, компьютер вычислит выражение в скобках. Если оно истинно,
то будет выполнен первый блок операторов, и на этом весь оператор if будет
закончен.
Если же выражение в скобках окажется ложным, то будет выполнен второй блок
операторов, и на этом оператор if будет закончен.
Оператор if
продолжение
if (x >=0)
mod = x;
else
mod = -x;
Таким образом, на основании данных (значения x), компьютер примет
решение, какие из команд выполнять, а какие нет.
Условное выражение – выражение, которое может принимать только 2
значения – истина и ложь. Как правило, возникают в результате
операций сравнения и вычисления булевских выражений (см. дальше).
“Далее идет первый блок операторов.”
В нашем случае, этот ‘блок’ состоит из одного оператора (mod = x;). Но в
тех случаях, когда нужно выполнить несколько команд, их помещают в
фигурные скобки {…} – блок.
Блок всегда законченный оператор и знак ‘;’ за ним не ставится!
Оператор if
еще пример
Еще пример.
Имеется 2 числа x и y. Нужно поместить их в переменные max и min, так,
чтобы в max оказалось более из них, а в min меньшее.
int max, min;
if (x > y)
{
max = x;
min = y;
}
else
{
max = y;
min = x;
}
Теперь уже нужны и фигурные скобки* - в каждой части более одного
оператора.
Оператор if
вариант решения
Имеется 2 числа x и y. Нужно поместить их в переменные max и
min, так, чтобы в max оказалось более из них, а в min меньшее.
int max = y, min = x;
if (x > y)
{
max = x;
min = y;
}
Здесь часть else не понадобилась. Мы сначала ‘сделали
предположение’ – поместили x в min, а y в max.
А затем проверили, нужно ли изменение.
Если часть else не нужна, то она может быть опущена!
Оператор if
итог
Опишем синтаксис и исполнение if более формально.
if (<условное выражение>)
<блок 1>
[
else
<блок 2>
]
, где <блок> - один оператор или несколько операторов, заключенных в
фигурные скобки.
Квадратные скобки [] говорят, что часть else может отсутствовать.
Исполнение. Вычисляется условное выражение. Если оно истинно, то
выполняется <блок 1> и на этом весь оператор завершен. Если условное
выражение ложно, и имеется часть else, то выполняется <блок 2>. Если
условное выражение ложно, а часть else отсутствует, то оператор
завершается без дополнительных действий.
Булевские величины
сравнения и булевские операции
Условное выражение – выражение, которое может принимать только 2
значения – истина и ложь. Как правило, возникают в результате
операций сравнения и вычисления булевских выражений.
В C определены следующие операции сравнения: >, >=, ==, <=, <, !=.
Остановимся только на 2-х:
• == - ‘равно’. x == y истинно, только если значения x и y совпадают.
• != - ‘не равно’. x != y истинно, только если значения x и y различны.
В результате операций сравнения возникают логические (булевские)
значения: истина и ложь.
В C отдельного типа булевских величин нет - это тоже числа! Их значение
роли не играет и принимается следующее правило:
0 соответствует булевскому ложь,
а любое число отличное от 0 – булевскому истина.
Булевские величины
сравнения и булевские операции
Любое число отличное от 0 соответствует булевскому ложь, а любое отличное от 0 – булевскому истина.

Будем для единообразия обозначать истинно как 1, а ложно, как 0.


В C определены булевские операции над булевскими величинами:
• && - ‘логическое И’
• || - ‘логическое ИЛИ’
• ! - ‘логическое отрицание’
! – унарная операция, т.е. она применяется к одному аргументу.
Действует она так:
!0 равно 1, а !1 равно 0.
Две другие операции бинарные, т.е. применяются к 2 аргументам.
Таблица && &&
Таблица
0 ||1 || 0 1

0 0 0 0 0 1
1 0 1 1 1 1
Булевские величины
сравнения и булевские операции
Применим операции к булевским величинам.
Пример.
Задача. Определить, является ли год Y високосным.
Високосным считается год, который делится на 4, но не делится на
100 или делится на 400.
Будем двигаться постепенно*.
if(Y % 4 == 0)
printf(“%d is a leap year\n”, Y);
else
printf(“%d is not a leap year\n”, Y);
Учтем, что Y не должно делиться на 100:
if(Y % 4 == 0 && Y % 100 != 0) …
Окончательно
if((Y % 4 == 0 && Y % 100 != 0 )|| Y % 400 == 0 ) …
Контрольные вопросы
1. На основании чего происходит ‘управление потоком
вычисления’ в программе? (компьютер ‘принимает решение’)
2. Опишите синтаксис оператора if.
3. Опишите исполнение оператора if.
4. Как в одной из ветвей if выполнить несколько операторов?
5. Что такое булевское выражение?
6. Какое соответствие принято в C между числовыми и
логическими значениями?
7. В результате каких операций возникают булевские значения?
8. Какие булевские операции определены в C?
Упражнение

Имеются ли среди выражений, приведенных ниже,


тождественные друг-другу?
a) ((Y % 4 == 0 && Y % 100 != 0 )|| Y % 400 == 0 )
b) ((Y % 100 != 0 && Y % 4 == 0)|| Y % 400 == 0 )
c) (Y % 4 == 0 && (Y % 100 != 0 || Y % 400 == 0) )
d) (Y % 100 != 0 && (Y % 4 == 0|| Y % 400 == 0) )
Если да, то какие?

Вам также может понравиться