книги / Язык Си
..pdfПреимущества языка Си:
-переносимость программ на компьютеры различной архи тектуры и из одной операционной системы в другую;
-лаконичность записи алгоритмов;
-логическая стройность и удобочитаемость программ;
-возможность получить код, сравнимый по скорости выпол нения с Ассемблером;
-возможность добраться до каждого бита памяти.
1.2. Структура программы
Любая программа на языке Си представляет собой совокуп ность функций. Выполнение любой программы ВСЕГДА начина ется с функции с именем main, поэтому минимальное число функ ций - одна (это main). Больше функций с таким именем быть не должно. Максимальное число функций неограничено.
Для выполнения определенных действий функция main обыч но обращается к другим функциям, часть из которых находится в той же самой программе, а часть - в библиотеках, содержащих ра нее написанные функции. Для описания тела функции (это про граммный код внутри функции) используется составной оператор {}. Фигурные скобки ВСЕГДА используются парами - открываю щая и закрывающая. После имени функции обязательно наличие круглых скобок ().
Теперь вы можете написать свою первую программу на Си.
Пример. Пустая функция main.
main()
}
Переменные и константы - основные объекты, с которыми работает программа, вводятся для описания различных характери стик в решаемой задаче.
Операции определяют, что делать с переменными и констан тами (складывать, умножать, сравнивать и т.д.).
Выражения объединяют переменные и константы для полу чения новых значений.
Рассмотрим все вышеперечисленное на следующем примере.
Пример. Вычисление площади треугольника по формуле Герона.
#include<math.h> |
|
|
|
#include<stdio.h> |
|
|
|
#include<conio.h> |
|
|
|
main() |
|
|
|
{int a=3, b=4, c=5; |
//ст ороны |
т реугольника |
|
float S, p; |
//п ло щ а д ь |
и |
полупериметр |
p = (a+b+c)/2.0; |
//в ы ч и с л е н и е |
полупериметра |
|
//в ы ч и с л е н и е площади |
|
|
|
S=sqrt(р*(р-а)*(р-b)* (р-с)); |
|
|
|
printf("%f",S); |
//в ы в о д на |
экран |
|
//задерж ка ко н со ли |
до нажатия клавиш и |
||
getch() ; |
|
|
|
return 0; |
|
|
|
}
Поясним некоторые моменты.
В языке Си одна лексема отделяется от другой точкой с запя той (;).
а, Ьу с - переменные целого типа int (от англ, integer - целый), так как мы не задаем дробную часть.
Syр - переменные с плавающей точкой (от англ, float - пла вающий), так как будут иметь дробную часть.
sqrt —функция стандартной библиотеки, вычисляющая квад ратный корень из указанного в скобках выражения. Объявлена в файле mathhy который мы подключаем к программе директивой
^include.
printf - функция стандартной библиотеки для форматирован ного вывода на консоль (экран). В кавычках мы указываем, что выводимое значение - это число типа float (%f). После кавычек
указываем имя переменной, значение которой мы печатаем на эк ран. Сама функция prinrfобъявлена в файле stdio.h.
Перед именем каждой функции следует помешать тип воз вращаемого значения. Если функция ничего не возвращает, то ука зывается тип void. Если сведения о типе результата отсутствуют, то считается, что функция main возвращает целочисленное значе ние, которое будет анализироваться операционной системой. Это осуществляется оператором возврата return. Ноль указывает опе рационной системе, что программа успешно закончила свою работу.
Таким образом, в простом случае (когда программа состоит только из одной функции) программа на Си имеет вид
директивы препроцессора main()
{объявление объектов;
использование объектов;
return 0;
}
1.3.Этапы создания программы
1.Набор кода. Исходная программа на языке Си создается в текстовом файле, имеющем расширение *.с (также можно исполь зовать расширение *.срр - программа на Си++). Набирать ее мож но в любом текстовом редакторе, но лучше в специальных про граммных продуктах (например, Microsoft Visual Studio, С++ Builder и т.п.), которые объединяют в себе текстовый редактор (обычно такие редакторы выделяют разным цветом лексемы языка программирования, что делает набор текста удобным), компиля тор, отладчик и другие средства создания программы.
2.Обработка кода. После того, как программа написана, на
ееоснове должен быть создан выполняемый файл (*.ехе). Для это го любая программа должна пройти три обязательных этапа обра ботки:
1. Препроцессорное преобразование - на этом этапе осущест вляется поиск в тексте программы строк, начинающихся с символа #. Такие строки воспринимаются препроцессором как команды (<директивы), которые определяют действия по преобразованию текста или развертыванию макросов - сокращенных обозначений различных выражений.
2.Компиляция - перевод текста программы в машинный (объ ектный) код. В результате для каждого исходного файла (*.с) соз дается объектный файл (*.obj).
3.Компоновка (редактирование связей или сборка) - объеди
нение объектных файлов в единый загрузочный выполняемый мо дуль (*.ехе). Этот модуль можно запускать на выполнение.
■ Только после успешного завершения всех перечисленных этапов создается ехе-файл.
1.4. Стандартные заголовочные файлы
Заголовочный фаш - это файл с расширением *.Л (от англ. header - головной, заголовочный), в котором находятся определе ния типов данных, структуры, прототипы функций, перечисления, макросы препроцессора (табл. 1.1).
|
|
Т а б л и ц а 1.1 |
|
|
Наиболее часто используемые заголовочные файлы |
||
№ |
Файл |
Назначение |
|
п/п |
|||
|
|
||
1 |
conio.h |
Консольный ввод-вывод (функции getch, getche,putch) |
|
2 |
stdio.h |
Стандартный ввод-вывод (функции printf, scanf gets, |
|
puts, putc,fclose,fopen и т.д; константы NULL и EOF) |
|||
3 |
math.h |
Математическая библиотека (функцииpow, sqrt, hypot, |
|
|
|
sin, cos, tan и т.д.) |
№
Файл
п/п
4stdlib.h
5string.И
6time.И
7signalh
О к о н ч а н и е т а б л . 1.1
Назначение
Преобразование типов, генерация случайных чисел, вы деление и освобождение памяти, контроль процесса вы полнения программы {atoi, atof, rand, srand, malloc, calioc, realloc, abort, exit и т.д.)
Работа со строками (функции strlen, strcmp, strcat, strcpv
и т.д.)
Работа с датами и временем (функции clock, time, diffiime и т.д.)
Обработка сигналов (функции raise, signal и т.д.)
Заголовочным он называется потому, что подключается к файлу реализации (*.с) с помощью директивы #include в начале (заголовке) программы.
1.5.Алфавит, идентификаторы, служебные слова
Валфавит языка Си входят:
-прописные и строчные буквы латинского алфавита: A, B...Z,
а, Ъ,...
-цифры: 0,1, ..., 9;
-специальные знаки: «<>=+-/%,.:\_!&*#-Л()[] и т.п.;
-неизображаемые символы, используемые для отделения лексем друг от друга: пробел, табуляция, переход на новую строку;
-комментарии: многострочный /* */ и однострочный //. Комментарий не считается программным кодом, поэтому
компилятор его пропускает.
Пример. Использование комментариев в программе.
main()
{float г=5; //Радиус окружности
float S; |
//Площадь окружности |
/*
S = M_PI*r*r; printf("%f",S); */
getch(); return 0;
}
Идентификатор - последовательность букв, цифр и симво лов подчеркивания, начинающаяся с буквы или символа подчер кивания. Идентификаторы используются для обозначения имен переменных, констант, функций и новых типов данных, объявляе мых пользователем.
Пример. Идентификаторы.
radius_l, _MIN, ABS, abs.
Правила использования идентификаторов
1.Идентификатор может содержать строчные и прописные буквы латинского алфавита, цифры и символ подчеркивания.
2.Прописные и строчные буквы различаются: int А, а, АВС,
аЪс.
3.Идентификатор может иметь длину не более 31-го символа.
4.Идентификатор не может начинаться с цифры.
5.Идентификатор не должен совпадать со служебными сло вами языка Си.
Пример. Некоторые служебные слова.
auto, break, case, char, continue, |
const, |
do, |
double, else, extern, float, for, if, int, |
long, |
re |
turn, short, signed, sizeof, static, struct, switch, union, unsigned, void, while и т.д.
PNRPU |
1.6. Базовые типы данных |
Тип данных нужен для указания компилятору, сколько байт в оперативной памяти необходимо выделить под заданные перемен ные.
В языке Си определены следующие стандартные (базовые) типы данных (табл. 1.2):
char —символьный; int - целый;
float - с плавающей точкой, т.е. вещественный; double - с плавающей точкой двойной точности;
void - пустой, не имеющий значения (нельзя создать пере менную типа void).
|
|
Т а б л и ц а 1.2 |
|
Все возможные базовые типы данных |
|
||
|
(в 32-разрядных системах) |
|
|
Тип |
Размер в байтах |
Диапазон значений |
|
char |
i |
-128.... 127 |
|
unsigned char |
i |
0 ... 255 |
|
signed char |
i |
-128.... |
127 |
int |
4 |
-2 147 483 648 .... 2 147 483 647 |
|
unsigned int |
4 |
0... 4 294 967 295 |
|
signed int |
4 |
-2 147 483 648 ....2 147 483 647 |
|
short int |
4 |
-2 147 483 648 ...2 147 483 647 |
|
unsignedshort int |
4 |
0 ... 4 294 967 295 |
|
signed short int |
4 |
-2 147 483 648 ... 2 147 483 647 |
|
long int |
4 |
-2 147 483 648 ... 2 147 483 647 |
|
signed long int |
4 |
-2 147 483 648 ...2 147 483 647 |
|
unsigned long int |
4 |
0 ... 4294967295 |
|
float |
4 |
-3.4-1038 ... 3.41038 |
|
double |
8 |
-K7 1030S |
1.7Ю30* |
long double |
10 |
-3.4-104933 ... 3.4 104932 |
Существует четыре модификатора, уточняющих внутреннее представление и диапазон значений стандартных типов:
signed - знаковый; unsigned- беззнаковый; long - длинный;
short - короткий.
Модификаторы signed и unsigned могут применяться к типам char и int. Модификаторы short и long могут применяться к типу int. Модификаторы signed и unsigned могут комбинироваться с мо дификаторами short и long в применении к типу int. Если после модификатора long базовый тип не указан, то компилятор предпо лагает, что это int. Модификатор long также может применяться к типу double.
1.7. Переменные: объявление, инициализация
Переменная - это величина, к которой обращаются с помо щью символического имени (идентификатора) и которая может принимать различные значения.
■ Все переменные должны быть объявлены до их первого использования в программе.
Объявление переменной приводит к выделению компилято ром памяти в размере, необходимом для размещения переменной данного типа (см. табл. 1.2). Присваивание переменной какоголибо значения приводит к тому, что это значение заносится в вы деленную память.
Основная форма объявления переменных имеет вид
тип данных список переменных;
Список переменных может состоять из одной или нескольких переменных, разделенных запятыми:
int а,с; char s,b
float z;
В данном примере под переменные д, с выделено по 4 байта, под s, b - по 1 байту и под z также выделено 4 байта.
Переменную можно объявить:
-вне какой-либо функции, в том числе и mainQ. Такая пере менная называется глобальной, она может использоваться в любом месте программы и существует в течение всего времени выполне ния программы;
-внутри блока, в том числе и внутри тела функции. Такая пе ременная называется локальной, доступна только в том блоке, в котором объявлена и существует в памяти только во время выпол нения этого блока (функции);
-как формальный параметр функции.
Пример. Глобальные и локальные переменные.
#include<stdio.h>
int п=5,а=2; //глобальные переменные main()
{int a=3; //a - локальная переменная, //доступна только в функции main
printf("%d\n",а); //будет напечатано 3 printf("%d\n",n); //будет напечатано 5 printf (" ^ f c d W а) ; //будет напечатано 2
getch(); return 0;
}
Если имена локальной и глобальной переменных совпадают (как переменная а в примере выше), то локальная переменная пе рекрывает глобальную и printf(“%d\n”,a); печатает 3, а не 2. Для доступа к глобальной переменной в этом случае необходимо ис пользовать операцию ::, т.е.printf(“%>d\n”, ::а);
■ В одном блоке видимости нельзя создать две перемен ных с одинаковым именем.
main()
{int A=3,B,c=3;
float X=3,A,x,y; //ОШИБКА! Переменная A
//уже объявлена
/ /
getch();
return 0;
}
Рекомендуется давать переменным осмысленные имена (на пример, площадь фигуры лучше обозначить S, а не X).
После того как переменная объявлена, ей рано или поздно на до будет присвоить значение. По умолчанию локальная переменная имеет неопределенное значение. Надеяться на то, что она равна, например, нулю, нельзя. В языке Си переменной можно присвоить значение одновременно с объявлением.
Пример. Объявление и инициализация переменных.
int с, п=5;
float а=п+1;
float b=c; |
//Ь = ??? |
т.к. с имеет |
//неизвестное значение
Вданном примере под переменные с, п выделено по 4 байта и
в4 байта переменной п помещено значение 5 в двоичном пред ставлении. Переменная с не инициализирована, поэтому в ней на ходится какое-то случайное число (как правило, очень большое).
Переменная может быть инициализирована не только кон стантой (п = 5), но и выражением с использованием ранее опреде ленных переменных (а = п + 1).
■ Все переменные должны быть инициализированы до их
первого использования в правой части оператора присваивания