В отличие от многих языков программирования высокого уровня, в языке С переменные могут объявляться в любом месте текста программы.
В языке С просто реализуются элементарные математические операции: сложения, вычитания, умножения и деления:
int a, b;
a=4;// с начальными значениями
b=8;
int c;
c= a+b; //сложение двух переменных
с=a-b; //вычитание
c=a*b; //умножение
c=a/b; //деление
Представленные операции можно выполнять не только с переменными, но и с конкретными числами, например
c = 10 + 5;
c = 8*4;
float d;
d = 7/2;
Результатом первых двух арифметических операций будут числа 15 и 32 соответственно, но при выполнении операции деления в переменную d будет записано число 3, а не 3,5. Это связано с тем, что число 7 в языке С будет интерпретироваться как целочисленная величина, которая не может содержать дробной части. Поэтому полученная дробная часть 0,5 будет отброшена. Для реализации корректного деления одного числа на другое следует использовать такую запись: d = 7.0/2;
или
d = (float )7/2;
В первом случае вещественное число делится на два и результат (вещественный) присваивается вещественной переменной d. Во втором варианте выполняется приведение типов: целое число 7 приводится к
вещественному типу float, а затем делится на 2.
Второй вариант удобен, когда выполняется деление одной целочисленной переменной на другую:
int a, b;
a = 7;
b = 2;
d = a/b;
В результате значение d будет равно 3, но если записать
d = (float )a/b;
то получим значение 3,5.
Если переменная d является целочисленной, то результат деления всегда будет записан с отброшенной дробной частью.
Приоритет операций умножения и деления выше приоритета операций сложения и вычитания.
Для того чтобы изменить порядок вычисления (поменять приоритеты), используются круглые скобки :
double arg = (25.0 + 60.0)*n/SCALE;
Здесь сначала выполняется операция сложения и только затем операции умножения и деления.
Для простоты программирования в языке С реализованы компактные операторы инкремента и декремента, т.е. увеличения и уменьшения значения переменной на 1 соответственно. Данные операторы могут быть записаны в виде
i++; // операция инкремента
++i; // операция инкремента
I-- ; // операция декремента
--i; // операция декремента
Разницу между первой и второй формами записи данных операторов можно продемонстрировать на следующем примере:
int i=10, j=10;
int a = i++; //значение a = 10; i = 11;
int b = ++j; //значение b = 11; j = 11;
Из полученных результатов видно, что если оператор инкремента стоит после имени переменной, то сначала выполняется операция присваивания и только затем операция инкремента. Во втором случае наоборот, операция инкремента реализуется до присвоения результата другой переменной. Поэтому значение a = 10, а значение b = 11.
Директивы препроцессора.
Почти все программы на языке С используют специальные команды для компилятора, которые называются директивами. В общем случае директива - это указание компилятору языка С выполнить то или иное действие в момент компиляции программы.
Существует строго определенный набор возможных директив, который включает в себя следующие определения:
#define, #elif, #else, #endif, #if, #ifdef, #ifndef, #include, #undef.
Директива #define используется для задания констант, ключевых слов, операторов и выражений, используемых в программе. Общий синтаксис данной директивы имеет следующий вид:
#define <идентификатор> <текст>
или
#define <идентификатор> (<список параметров>) <текст>
Пример использования директивы #define.
#include <stdio.h>
#define TWO 2
#define FOUR TWO*TWO
#define PX printf("X равно %d.\n", x)
#define FMT «X равно %d.\n»
#define SQUARE(X) X*X
Int main()
{ int x = TWO;
PX;
x = FOUR;
printf(FMT, x);
x = SQUARE(3);
PX;
return 0; }
После выполнения этой программы на экране монитора появится три строки:
X равно 2.
X равно 4.
X равно 9.
Директива #undef отменяет определение, введенное ранее директивой #define. Предположим, что на каком-либо участке программы нужно отменить определение константы FOUR. Это достигается следующей командой:
#undef FOUR
Интересной особенностью данной директивы является возможность переопределения значения ранее введенной константы.
Действительно, повторное использование директивы #define для ранее введенной константы FOUR невозможно, т.к. это приведет к сообщению об ошибке в момент компиляции программы. Но если отменить определение константы FOUR с помощью директивы #undef, то появляется возможность повторного использования директивы #define для константы FOUR.
Для того чтобы иметь возможность выполнять условную компиляцию, используется группа директив #if, #ifdef, #ifndef, #elif, #else и #endif.
Пример:программа выполняет подключение библиотек в зависимости от установленных констант.
#if defined(GRAPH)
#include <graphics.h> //подключение графической библиотеки
#elif defined(TEXT)
#include <conio.h> //подключение текстовой библиотеки
#else
#include <io.h> //подключение библиотеки ввода-вывода
#endif
Программа работает следующим образом: если ранее была задана константа с именем GRAPH через директиву #define, то будет подключена графическая библиотека с помощью директивы #include. Если идентификатор GRAPH не определен, но имеется определение TEXT, то будет использоваться библиотека текстового ввода/вывода. Иначе, при отсутствии каких-либо определений, подключается библиотека ввода/вывода. Вместо словосочетания #if defined часто используют сокращенные обозначения #ifdef и #ifndef и выше приведенную программу можно переписать в виде:
#ifdef GRAPH
#include <graphics.h> //подключение графической библиотеки
#ifdef TEXT
#include <conio.h> //подключение текстовой библиотеки
#else
#include <io.h> //подключение библиотеки ввода-вывода
#endif
Отличие директивы #if от директив #ifdef и #ifndef заключается в возможности проверки более разнообразных условий, а не только существует или нет какие-либо константы.
Например, с помощью директивы #if можно проводить такую проверку:
#if SIZE == 1
#include <math.h> // подключение математической библиотеки
#elif SIZE > 1
#include <array.h> // подключение библиотеки обработки
// массивов
#endif
В приведенном примере подключается либо математическая библиотека, либо библиотека обработки массивов, в зависимости от значения константы SIZE.
Используемая в приведенных примерах директива #include позволяет добавлять в программу ранее написанные программы и сохраненные в виде файлов. Например, строка
#include <stdio.h>
указывает препроцессору добавить содержимое файла stdio.h вместо приведенной строки. Это дает большую гибкость, легкость программирования и наглядность создаваемого текста программы.