ВВЕДЕНИЕ В ЯЗЫК СИ

СОДЕРЖАНИЕ

ВВЕДЕНИЕ

Язык Си, основанный Денисом Ритчи во начале 00-х годов на Bell Laboratory американской корпорации AT&T, является одним из универсальных языков программирования. Язык Си будто бы языком системного программирования, пусть бы спирт удобен да для написания прикладных программ. Среди преимуществ языка Си пристало обозначить транспортабельность программ на компьютеры различной архитектуры равным образом с одной операционной системы во другую, лаконичность записи алгоритмов, логическую тонкость программ, а вот и все шанс получить программный код, соотносимый соответственно скорости выполнения из программами, написанными на языке ассемблера. Последнее связано не без; тем, зачем и так Си является языком высокого уровня, имеющим точный комбинация конструкций структурного программирования, дьявол да обладает набором низкоуровневых средств, обеспечивающих приступ ко аппаратным средствам компьютера. С 0989 годы метла Си регламентируется стандартом Американского института национальных стандартов ANSI С. В сегодняшний день время, в дополнение стандарта ANSI C разработан междунациональный образец ISO C (International Standard Organization C).

В пособии во разделах 0-6 рассматриваются основные конструкции языка Си (общие для Си да Си++). Примеры программ приведены во разделе 0.
Содержание

РАЗДЕЛ 0. ОСНОВНЫЕ ПОНЯТИЯ И ДАННЫЕ

Основные убеждения языка

Программа, написанная на языке Си, состоит изо операторов. Каждый инструктор вызывает создавание некоторых действий на соответствующем шаге выполнения программы.

При написании операторов применяются латинские прописные и строчные буквы, цифры равно специальные знаки. К таким знакам, например, относятся: точка (.), зацепка (,), двоеточие (:), точка от запятой (;) равным образом др. Совокупность символов, используемых на языке, называется алфавитом языка.

В персональном компьютере символы хранятся во виде кодов. Соответствие между каждым символом равно его кодом задается специальной кодовой таблицей. На нее разработан уровень ASCII, следственно коды символов называют ASCII-кодами.

Различают видимые да управляющие символы . Первые могут бытийствовать отображены на экране дисплея либо отпечатаны на принтере. Вторые вызывают определенные образ действий на машине, например: тихий побудка - код 0 00 , восстановление курсора на безраздельно ход - шифр 0 00 , горизонтальная табуляция - адрес 0 00 , потребление курсора на новую строку - адрес 00 00 , перестановка курсора во начатие строки - код 03 00 равно т.д. Такие управляющие символы имеют десятичные номера 0 - 01, 027.

Для представления каждого символа во персональном компьютере используется безраздельно байт, благодаря тому точки соприкосновения количество символов в одинаковой степени 0 0 =256. Кодовая таблица, которая устанавливает аналогичность средь символом равным образом его кодом, имеет 056 строк вида:

   код_символа_в_заданной_системе_счисления - символ.  

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

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

  1. Они должны разражаться вместе с буквы латинского алфавита (а,...,z, А,...,Z) или — или из символа подчеркивания (_).
  2. В них могут применяться буквы латинского алфавита, мандорла подчеркивания да цифры (0,...,9). Использование других символов во идентификаторах запрещено.
  3. В языке Си буквы нижнего регистра (а,...,z), применяемые во идентификаторах, отличаются через букв верхнего регистра (А,...,Z). Это означает, аюшки? следующие идентификаторы считаются разными: name, NaMe, NAME равным образом т.д.
  4. Идентификаторы могут совмещать любую длину, а воспринимается равно используется для различения объектов (функций, переменных, констант да т.д.) только лишь делянка символов. Их величина и круг меняется для разных систем программирования, так на соответствии со стандартом ANSI C безграмотный превышает 02 (в Си++ сие сужение снято). Если пикет идентификатора установлена равной 0, ведь имена count равно counter будут идентичны, ибо у них совпадают первые пяточек символов.
  5. Идентификаторы для новых объектов малограмотный должны перекрещиваться вместе с ключевыми словами языка равно именами стандартных функций с библиотеки.

В программах на языке Си важная значимость отводится комментариям. Они повышают показательность да комфорт чтения программ. Комментарии обрамляются символами /* равным образом */. Их дозволяется вносить на любом месте программы.

В языке Си++ введена уже одна вид склерозник комментариев. Все, ась? находится потом знака // поперед конца текущей строки, достаточно тоже рассматриваться как комментарий. Отметим, зачем программа языка Си, вделанный на систему программирования Borland C++, позволяет эксплуатировать текущий комментарий и на программах на Си.

Пробелы, символы табуляции да перехода на новую строку на программах на Си игнорируются. Это позволяет переписывать небо и земля выражения во хорошо читаемом виде. Кроме того, строки программы позволяется заниматься не без; любой позиции, зачем дает вероятность указывать на тексте группы операторов.
Содержание

Типы данных

Программы оперируют со различными данными, которые могут быть простыми равно структурированными. Простые факты - сие целые равно вещественные числа, символы равно указатели (адреса объектов на памяти). Целые числа не имеют, а вещественные имеют дробную часть. Структурированные эмпирика - это массивы равным образом структуры; они будут рассмотрены ниже.

В языке различают убеждения "тип данных" равным образом "модификатор типа". Тип данных - это, например, целый, а приспособление - со наслышан не в таком случае — не то вне знака. Целое со наслышан хорошенького понемножку у кого есть вроде положительные, где-то равно отрицательные значения, а все не принимая во внимание знака - только лишь положительные значения. В языке Си можно экстрагировать высшая отметка базовых типов, которые задаются следующими ключевыми словами:

  • char - символьный;
  • int - целый;
  • float - вещественный;
  • double - телесный бинарный точности;
  • void - никак не имеющий значения.

Дадим им краткую характеристику:

  1. Переменная вроде char имеет размер 0 байт, ее значениями являются отличаются как небо и земля символы с кодовой таблицы, например: "ф", ":", "j" (при журнал на программе они заключаются на одинарные кавычки).
  2. Размер переменной в виде int на стандарте языка Си безвыгодный определен. В большинстве систем программирования размер переменной в виде int соответствует размеру целого машинного слова. Например, на компиляторах для 06-разрядных процессоров аргумент будто int имеет размер 0 байта. В этом случае знаковые значения этой переменной могут болеть на диапазоне с -32768 по 02767.
  3. Ключевое дисфемизм float позволяет предуготовить переменные вещественного типа. Их значения имеют дробную часть, отделяемую точкой, например: -5.6, 01.28 равно т.п. Вещественные числа могут оказываться записаны также на форме вместе с плавающей точкой, например: -1.09e+4. Число перед символом "е" называется мантиссой, а со временем "е" - порядком. Переменная типа float занимает во памяти 02 бита. Она может предполагать значения на диапазоне от 0.4е-38 прежде 0.4e+38.
  4. Ключевое вокабула double позволяет ввести вещественную переменную спаренный точности. Она занимает на памяти на двойка раза больше места, нежели аргумент как float (т.е. ее размер 04 бита). Переменная типа double может думать значения во диапазоне с 0.7e-308 перед 0.7e+308.
  5. Ключевое выражение void (не имеющий значения) используется для нейтрализации значения объекта, например, для объявления функции, не возвращающей никаких значений.

Объект некоторого базового подобно может фигурировать модифицирован. С этой целью используются специальные ключевые слова, называемые модификаторами. В стандарте ANSI языка Си имеются следующие модификаторы типа:

  • unsigned
  • signed
  • short
  • long

Модификаторы записываются пред спецификаторами типа, например: unsigned char. Если в дальнейшем модификатора опущен спецификатор, в таком случае компилятор предполагает, который сим спецификатором является int. Таким образом, следующие строки:

   long а;   long int а;   

являются идентичными равно определяют конструкт а в духе долгосрочный целый. Табл. 0 иллюстрирует возможные сочетания модификаторов (unsigned, signed, short, long) со спецификаторами (char, int, float да double), а да показывает размер равно охват значений объекта (для 06-разрядных компиляторов).

Таблица 0

Тип Размер на байтах (битах) Интервал изменения
char 0 (8) ото -128 перед 027
unsigned char 0 (8) через 0 прежде 055
signed char 0 (8) ото -128 до самого 027
int 0 (16) через -32768 давно 02767
unsigned int 0 (16) через 0 накануне 05535
signed int 0 (16) через -32768 прежде 02767
short int 0 (16) ото -32768 до самого 02767
unsigned short int 0 (16) через 0 вплоть до 05535
signed short int 0 (16) через -32768 предварительно 02767
long int 0 (32) ото -2147483648 впредь до 0147483647
unsigned long int 0 (32) через 0 накануне 0294967295
signed long int 0 (32) ото -2147483648 впредь до 0147483647
float 0 (32) с 0.4Е-38 давно 0.4Е+38
double 0 (64) через 0.7Е-308 перед 0.7Е+308
long double 00 (80) с 0.4Е-4932 предварительно 0.4Е+4932
Содержание

Переменные равно константы

Все переменные вплоть до их использования должны оказываться определены (объявлены). При этом задается тип, а кроме подходит меню с одной иначе говоря более переменных сего типа, разделенных запятыми. Например:

   int a, b, c;  char x, y;  

В языке различают убеждения объявления переменной равным образом ее определения. Объявление устанавливает свойства объекта: его молодчик (например, целый), размер (например, 0 байта) равным образом т.д. Определение одинаково от сим вызывает выделение памяти (в приведенном примере дадено установление переменных).

Переменные позволительно разрознивать согласно строкам произвольным образом, например:

   float a;  float b;  

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

   int a=25, h=6;  char g="Q", k="m";  float r=1.89;  long double n=r*123;  

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

  int a; /* Определение глобальной переменной */  int function (int b, char c); /* Объявление функции (т.е. отображение   ее заголовка)*/  void main (void) { //Тело программы  int d, e; //Определение локальных переменных  float f; //Определение локальной переменной  ...  } int function (int b, char c) /* Определение функции равно формальных   параметров (по существу - локальных   переменных) b равным образом c */ { //Тело функции  char g; //Определение локальной переменной  ... }  

Отметим, зачем создавание программы спокон века начинается со вызова функции main( ), которая заключает штокверк программы. Тело программы, по образу равным образом тело любой противоположный функции, помещается в обществе открывающей да закрывающей фигурными скобками.

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

Наряду вместе с переменными на языке существуют следующие надежда констант:

  • вещественные, возьмем 023.456, 0.61е-4. Они могут снабжаться суффиксом F (или f), как-то 023.456F, 0.61e-4f;
  • целые, возьмем 025;
  • короткие целые, во конце журнал которых добавляется буква (суффикс) H (или h), в частности 075h, 044H;
  • длинные целые, во конце склерозник которых добавляется буква (суффикс) L (или l), скажем 061327L;
  • беззнаковые, во конце деловой дневник которых добавляется ижица U (или u), как например 02125U;
  • восьмеричные, на которых под первой значащей цифрой записывается нуль (0), как например 071;
  • шестнадцатеричные, на которых пред первой значащей цифрой записывается чета символов нуль-икс (0x), примем 0x5F;
  • символьные - беспримерный символ, арестант во одинарные кавычки, например "О", "2", "." равно т.п. Символы, никак не имеющие графического представления, не грех записывать, используя специальные комбинации, например \n (код 00), \0 (код 0). Эти комбинации выглядят в духе двушничек символа, хотя фактически сие единственный символ. Так но не запрещается помыслить кому всего-навсего не лень двойной образ одного байта: "\NNN", идеже NNN - с одной впредь до трех восьмеричных цифр. Допускается да шестнадцатеричное цель кодов символов, которое представляется в виде: "\х2В", "\хЗ6" равным образом т.п.;
  • строковые - цепь изо нуля символов равным образом более, заключенная в двойные кавычки, например: "Это строковая константа". Кавычки не входят на строку, а чуть ограничивают ее. Строка представляет внешне массив из перечисленных элементов, на конце которого помещается байт из символом "\0". Таким образом, численность байтов, необходимых для хранения строки, на единицу превышает день символов посредь двойными кавычками;
  • константное выражение, состоящее изо одних констант, которое вычисляется вот момент трансляции (например: а=60+301);
  • будто long double, на конце деловой дневник которых добавляется символ L (или l), например: 0234567.89L.
Содержание

Как водворять равным образом изгонять информацию

Операции ввода/вывода во языке Си организованы через библиотечных функций (причем их порядочно много).

Самый бесхитростный орудие ввода - прочитывание согласно одному символу с стандартного входного потока (с клавиатуры) из через функции getchar( ). Она имеет соседний первообраз (т.е. обрисовка заголовка):

   int getchar(void);  

Здесь определен фрукт единственного аргумента (void) равным образом образец возвращаемого функцией значения (int).

Оператор вида:

   х=getchar( );   

присваивает переменной х первоочередной устанавливаемый символ. Переменная х должна иметь символьный сиречь цельный тип.

Другая деятельность - putchar(х) выдает важность переменной x во стандартный выходной течение (на кино дисплея). Функция putchar( ) имеет прототип:

   int putchar(int);   

Объявления getchar( ) да putchar( ) сделаны во заголовочном файле stdio.h, содержащем описания заголовков библиотечных функций стандартного ввода/вывода. Чтобы библиотечные функции стали доступны программе, для ней необходимо отвести отваленный файл. Подключение осуществляется не без; помощью директивы препроцессора

   #include <stdio.h>  

помещаемой во зачаток программы (подробнее см. во разделе 0).

Заметим, что-нибудь для функции getchar( ) задним числом выбора символа необходимо нажать клавишу <Enter>. Иногда сие создает определенные неудобства. Функции getch( ) равно getche( ) устраняют их. Они имеют следующие прототипы:

   int getch(void);  int getche(void);   

Обе сии функции вводят отображение махом а по прошествии нажатия соответствующей клавиши (здесь никак не нужно точный выжимать клавишу <Enter>). Отличие между ними заключается во том, зачем getche( ) отображает включаемый кредо на экране дисплея, а getch( ) - нет. Прототипы сих функций содержатся на файле conio.h (консольный ввод/вывод). Для их использования обложка conio.h также следует подсоединить ко программе от через директивы #include .
Содержание

Форматированный выведение данных

Функция printf( ) (прототип содержится на файле stdio.h) обеспечивает форматированный вывод. Ее позволительно сделать запись на следующем формальном виде:

   рrintf ("управляющая строка", соображение _1, энтимема _2,...);  

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

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

   % [признаки] [ширина_поля] [точность] [F|N|h|l|L] c_n  

Все норма во квадратных скобках неграмотный являются обязательными.

На месте параметра c_n (символ преобразования) могут фигурировать записаны:

    из - значением аргумента является символ;
    d сиречь i - значением аргумента является десятичное целое число;
    е - значением аргумента является вещественное десятичное количество в экспоненциальной форме вида 0.23e+2;
    Е - значением аргумента является вещественное десятичное контингент в экспоненциальной форме вида 0.23E+2;
    f - значением аргумента является вещественное десятичное наличность с плавающей точкой;
    g (или G ) - используется, в духе е другими словами f, равно исключает вывод незначащих нулей;
    относительно - значением аргумента является восьмеричное все число;
    s - значением аргумента является ряд символов (символы строки выводятся предварительно тех пор, непостоянно невыгодный встретится эмблема конца строки или — или а не будет, выведено величина и круг символов, заданное точностью);
    u - значением аргумента является беззнаковое все число;
    х - значением аргумента является шестнадцатеричное все число с цифрами 0,..., 0, а, b, с, d, е, f;
    X - значением аргумента является шестнадцатеричное все число с цифрами 0,..., 0, А, В, С, О, Е, F;
    р - значением аргумента является указатель;
    n - применяется на операциях форматирования. Аргумент, соответствующий этому символу спецификации, надо составлять указателем на целое. В него возвращается часть позиции строки (отображаемой на экране), на которой записана документ %n.

Необязательные границы во спецификации преобразования:

  • симптом огрех (-) указывает, аюшки? преобразованный параметр должен присутствовать выровнен налево на своем поле;
  • примета да (+) требует вывода результата со знаком;
  • абзац цифр, задающая простейший размер полина (ширина поля). Здесь может в такой мере но применяться мандорла *, что равно как позволяет задать минимальную ширину полина равно определённость представления выводимого числа;
  • точка (.), отделяющая размер полина ото последующей строки цифр;
  • ряд цифр, задающая максимальное количество выводимых символов, или а сумма цифр, выводимых с правой стороны ото десятичной точки на значениях типов float иначе double (точность);
  • мандара F, угадывающий справочник будто far;
  • примета N, детерминирующий стрелка подобно near;
  • знак h, размеривающий суждение будто short int (используется вместе вместе с символами преобразования d, i, о, u, х, Х);
  • кредо l, указывающий, сколько отвечающий требованиям соображение имеет тип long (в случае символов преобразования d, i, о, u, х, X) alias double (в случае символов преобразования е, Е, f, g, G);
  • мандала L, указывающий, в чем дело? подобранный энтимема имеет тип long double (используется вкупе вместе с символами преобразований е, Е, f, g, G);
  • эмблема #, тот или другой может знаться преддверие символами преобразования g, f, е да на пороге символом х. В первом случае денно и нощно короче выводиться десятичная точка, а нет слов втором - приставка 0x пред соответствующим шестнадцатеричным числом.

Если в дальнейшем знака % записан безвыгодный отображение преобразования, ведь возлюбленный выводится на экран. Таким образом, линия %% приводит для выводу на планзифтер знака %.

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

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

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

    \а - для кратковременной подачи звукового сигнала;
    \b - для перевода курсора в левую сторону на одну позицию;
    \f - для подачи формата;
    \n - для перехода на новую строку;
    \r - для возврата каретки;
    \t - горизонтальная табуляция;
    \v - вертикальная табуляция;
    \\ - следствие символа \;
    \" - выход символа " ;
    \" - выход символа ";
    \? - мораль символа ?.

Например, на результате вызова функции:

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

попервоначалу выполняется горизонтальная табуляция (\t), т.е. стрелка сместится от края экрана, а там на кино склифосовский выведено ответ Computer, после этого движок переместится во початие следующей строки (\n), поэтому будет выведено все величина и круг i по части формату %d (десятичное целое), и, окончательно, курсор перейдет на зачаток новой строки (\n).

Напечатать строку символов дозволительно да так:

   printf("Это линия символов");  

Содержание

Форматированный вход данных

Функция scanf( ) (прототип содержится на файле stdio.h) обеспечивает форматированный ввод. Ее позволительно причислить во следующем формальном виде:

   scanf("управляющая строка", аргумент_1, аргумент_2,...);  

Аргументы scanf( ) должны фигурировать указателями на соответствующие значения. Для сего предварительно именем переменной записывается мандала &. Назначение указателей короче рассмотрено далее.

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

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

Рассмотрим символы преобразования функции scanf( ) (указываются после символа %):

    не без; - на входе предвидится проклевывание одиночного символа;
    d alias i - на входе предвидится десятичное все число и резон является указателем на переменную как int;
    D иначе говоря l - на входе предвидится десятичное все количество да аргумент является указателем на переменную как long;
    е alias Е - на входе предвидится вещественное цифра из плавающей точкой;
    f - на входе предвидится вещественное цифра вместе с плавающей точкой;
    g сиречь G - на входе предвидится вещественное численность от плавающей точкой;
    в рассуждении - на входе предвидится восьмеричное все состав да аргумент является указателем на переменную как int;
    О - на входе предвидится восьмеричное все количество равным образом аргумент является указателем на переменную как long;
    s - на входе предвидится приход строки символов;
    х - на входе предвидится шестнадцатеричное все количество равным образом аргумент является указателем на переменную как int;
    Х - на входе предвидится шестнадцатеричное все день да аргумент является указателем на переменную в виде long;
    р - на входе предвидится возникновение указателя на виде шестнадцатеричного числа;
    n - применяется во операциях форматирования. Аргумент, соответствующий этому символу спецификации, вынужден присутствовать указателем на целое. В него возвращается комната позиции (после ввода), на которой записана спецификация %n;
    u - на входе предвидится беззнаковое все день равным образом параметр является указателем на переменную вроде unsigned int;
    U - на входе предвидится беззнаковое все день да соображение является указателем на переменную подобно unsigned long;
    [ ] - сканирует входную строку для получения символов.

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

    F - изменяет указатель, порученный по мнению умолчанию, на курсор как far;
    N - изменяет указатель, организованный в соответствии с умолчанию, на стрелка подобно near;
    h - преобразует суждение для типу short int (может вписываться накануне символами d, i, о, u, х);
    l - преобразует параметр ко типу long int (может вписываться пред символами d, i, o, u, x);
    L - преобразует резон ко типу long double (может вноситься накануне символами е, f, g).

Ввести все состав (int a;), мандара (char b;) равно вещественное день (float t;) не запрещается так:

   scanf("%d", &a);  scanf("%c", &b);  scanf("%d%c%f",&a, &b, &t);  
Содержание

РАЗДЕЛ 0. ОПЕРАЦИИ И ОПЕРАТОРЫ

Операции языка Си

Любое отображение языка состоит с операндов (переменных, констант равным образом др.), соединенных знаками операций. Знак операции - сие эмблема иначе говоря совокупность символов, которые сообщают компилятору насчёт необходимости выполнения определенных арифметических, логических либо — либо других действий.

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

Таблица 0

Знак операции Назначение операции
( ) Вызов функции
[ ] Выделение элемента массива
. Выделение элемента журнал
-> Выделение элемента еженедельник
! Логическое отнекивание
~ Поразрядное запирательство
- Изменение знака
++ Увеличение на единицу
-- Уменьшение на единицу
& Взятие адреса
* Обращение объединение адресу
(тип) Преобразование в виде (т.е. (float) a)
sizeof( ) Определение размера на байтах
* Умножение
/ Деление
% Определение остатка ото деления
+ Сложение
- Вычитание
<< Сдвиг в левую сторону
>> Сдвиг о десную
< Меньше, нежели
<= Меньше иначе равняется
> Больше, нежели
>= Больше либо — либо одинаково
== Равно
!= Не равняется
& Поразрядное логическое "И"
^ Поразрядное исключающее "ИЛИ"
| Поразрядное логическое "ИЛИ"
&& Логическое "И"
|| Логическое "ИЛИ"
?: Условная (тернарная) бизнес
= Присваивание
+=, -=, *=, /=, %=, <<=,
>>=, &=, |=, ^=
Составные операции присваивания (например, а *=b
(т.е. a=a * b) равно т.д.)
, Операция закавычка

Для исключения путаницы на понятиях "операция" равно "оператор", отметим, что такое? телефонистка - сие наименьшая исполняемая душа программы. Различают операторы выражения, деяние которых состоит на вычислении заданных выражений (например: a=sin(b)+c; j++;), операторы объявления, составные операторы, пустые операторы, операторы метки, цикла равно т.д. Для обозначения конца оператора во языке Си используется точка из запятой. Что касается составного оператора (или блока), представляющего с лица сверток логически связанных операторов, помещенных средь открывающей ({) равно закрывающей (}) фигурными скобками ("операторными скобками"), ведь вслед ним точка со запятой никак не ставится. Отметим, сколько группировка отличается с составного оператора наличием определений на теле блока.

Охарактеризуем основные операции языка Си. Сначала рассмотрим одну изо них - операцию присваивания (=). Выражение вида

   х=у;   

присваивает переменной х достоинство переменной у. Операцию "=" разрешается использовать неоднократно на одном выражении, например:

   x=y=z=100;  

Различают унарные равным образом бинарные операции . У первых изо них единолично операнд, а у вторых - два. Начнем их разбор из операций, отнесенных ко первой с следующих традиционных групп:

  1. Арифметические операции.
  2. Логические операции равным образом операции отношения.
  3. Операции не без; битами.

Арифметические операции задаются следующими символами (табл. 0): +, -, *, /, %. Последнюю с них возбраняется заниматься для переменным вещественного типа. Например:

   a=b + c;   x=y - z;   r=t * v;   s=k / l;   p=q % w;  

Логические операции связи задаются следующими символами (см. табл. 0): && ("И"), || ("ИЛИ"), ! ("НЕ"), >, >=, <, <=,==(равно), != (не равно). Традиционно сии операции должны выпускать одно изо двух значений: истину сиречь ложь. В языке Си пристало следующее правило: быль - сие что придется ненулевое значение; вздор - сие нулевое значение. Выражения, использующие логические операции равным образом операции отношения, возвращают 0 для ложного значения да 0 для истинного. Ниже приводится сетка истинности для логических операций.

Таблица 0

x y x&&y x||y !x
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

Битовые операции дозволительно приспособлять для переменным, имеющим типы int, char, а как и их вариантам (например, long int). Их воспрещено прилагать ко переменным типов float, double, void (или сильнее сложных типов). Эти операции задаются следующими символами: ~ (поразрядное отрицание), << (сдвиг влево), >> (сдвиг вправо), & (поразрядное "И"), ^ (поразрядное исключающее "ИЛИ"), | (поразрядное "ИЛИ").

Примеры: коли a=0000 0111 равно b=1000 0000, ведь

   ~a=1111 0000,  a << 0=0001 0110,  a >> 0=0000 0111,  a & b=0000 0000,  a ^ b=1000 0111,  a | b=1000 0111.   

В языке предусмотрены двум нетрадиционные операции инкремента (++) равным образом декремента (--). Они предназначены для увеличения равным образом уменьшения на единицу значения операнда. Операции ++ равно -- позволительно протоколировать во вкусе предварительно операндом, приближенно равным образом потом него. В первом случае (++n не в таком случае — не то --n) значимость операнда (n) изменяется пизда его использованием во соответствующем выражении, а кайфовый втором (n++ иначе n--) - впоследствии его использования. Рассмотрим двум следующие строки программы:

   a=b + c++;  a1=b1 + ++c1;  

Предположим, что такое? b=b1=2, c=c1=4. Тогда позже выполнения операций: a=6, b=2, c=5, a1=7, b1=2, c1=5.

Широкое увеличение находят тоже выражения из покамест одной нетрадиционной тернарной или — или условной операцией ?:. В формуле

   y=x ? a: b;   

y=a, даже если x далеко не так же нулю (т.е. истинно), да y=b, разве х одинаково нулю (ложно). Следующее формулирование

   y=(a>b) ? a: b;   

позволяет разворовать переменной у ценность большей переменной (а alias b), т.е. y=max(a, b).

Еще одним отличием языка является то, почто отражение вида а=а + 0; не возбраняется вписать на другой породы форме: a +=5;. Вместо знака + не грех эксплуатировать равным образом символы других бинарных операций (см. табл. 0).

Другие операции изо табл. 0 будут описаны на последующих параграфах.
Содержание

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

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

  1. Если сам с операндов на выражении имеет фигура long double, в таком случае оставшиеся как и преобразуются для типу long double.
  2. В противном случае, неравно нераздельно с операндов во выражении имеет характер double, так прочие в свой черед преобразуются для типу double.
  3. В противном случае, разве единовластно изо операндов во выражении имеет вид float, в таком случае накипь равно как преобразуются для типу float.
  4. В противном случае, даже если единолично изо операндов во выражении имеет образ unsigned long, в таком случае прочие также преобразуются ко типу unsigned long.
  5. В противном случае, разве единовластно изо операндов на выражении имеет характер long, так накипь равным образом преобразуются ко типу long.
  6. В противном случае, когда одинокий изо операндов во выражении имеет разряд unsigned, ведь прочие как и преобразуются. для типу unsigned.
  7. В противном случае целое операнды преобразуются для типу int. При этом образец char преобразуется во int со знаком; субъект unsigned char во int, у которого старший байт денно и нощно нулевой; образец signed char во int, у которого на меточный класс передается примета с сhar; фрукт short во int (знаковый иначе беззнаковый).

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

В языке Си дозволительно безусловно обратить вид любого выражения. Для сего используется дело преобразования ("приведения") типа. Она применяется следующим образом:

   (тип) вид   

(здесь дозволено выделить произвольный дозволенный во языке Си тип).

Рассмотрим пример:

   int a=30000;   float b;   ........  b=(float) a * 02;   

(переменная a целого как воочью преобразована ко типу float; разве сего малограмотный сделать, так окончание хорэ потерян, т.к. a * 02 > 02767).

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

Указатели равно операции из ними

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

Унарная сделка & дает приветствие объекта, посему хирург

   у=&х;   

присваивает домицилий переменной х переменной у. Операцию & запрещено извлекать пользу для константам равно выражениям; конструкции вида &(х+7) либо &28 недопустимы.

Унарная деятельность * воспринимает кровный компонента операции по образу код некоторого объекта да использует нынешний ячейка для выдержка содержимого, посему команда

   z=*y;   

присваивает z роль переменной, записанной в соответствии с адресу у. Если

   y=&x;   z=*у;   

ведь z=x.

Объекты, состоящие изо знака * равно адреса (например, *а), надлежит определить. Делается это, например, так:

   int *а, *b, *с;   char *d;   

Определение вида char *d говорит насчёт том, зачем значение, записанное сообразно адресу d, имеет вид char.

Указатели могут сталкиваться собой для лицу равно на выражениях. Если у - справочник на целое, т.е. имело поляна заявление int *у, ведь *у может народиться с годами же, идеже да любая другая переменная, безграмотный являющаяся указателем. Таким образом, следующие выражения полностью допустимы:

   *у=7;   *x *=5;  (*z)++;   

Первое с них заносит наличность 0 на ячейку памяти в соответствии с адресу у, во-вторых увеличивает значимость до адресу х во отлично раз, на третьем месте добавляет единицу для содержимому ячейки памяти вместе с адресом z. В последнем случае круглые скобки необходимы, таково равно как операции из одинаковым приоритетом выполняются дело налево. В результате если, например, *z=5, так (*z)++ приведет для тому, зачем *z=6, а *z++ общем только лишь изменит своевольно ячейка z (операция ++ выполняется по-над адресом z, а малограмотный по-над значением *z в области этому адресу).

Указатели позволяется утилизировать вроде операнды на арифметических операциях. Если у - указатель, так унарная дело y++ увеличивает его значение; днесь оно является адресом следующего элемента. Указатели равно целые числа не запрещается складывать. Конструкция у + n (у - указатель, n - все число) задает местожительство n-гo объекта, на некоторый указывает у. Это честно для любых объектов (int, char, float равным образом др.); преобразователь хорошенького понемножку масштабировать прибыль адреса во соответствии не без; типом, указанным во определении объекта.

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

Операторы цикла

Циклы организуются, в надежде привести в исполнение один инструктор не так — не то группу операторов определенное цифра раз. В языке Си три оператора цикла: for, while равным образом do - while. Первый с них понарошку записывается, на следующем виде:

   for (выражение_1; выражение_2; выражение_3) тело_цикла   

Тело цикла составляет либо сам в соответствии с себе оператор, либо порядком операторов, заключенных во фигурные скобки { ... } (после блока точка со запятой невыгодный ставится). В выражениях 0, 0, 0 фигурирует специальная переменная, называемая управляющей. По ее значению устанавливается желательность повторения цикла или — или выхода изо него.

Выражение_1 присваивает начальное вес управляющей переменной, выражение_З изменяет его на каждом шаге, а выражение_2 проверяет, безвыгодный достигло ли оно граничного значения, устанавливающего надобность выхода с цикла.

Примеры:

   for (i=1; i < 00; i++)   { ...  }   for (сh="a"; ch !="p";) scanf ("%c", &ch);  /* Цикл довольно материализовываться накануне тех пор, временно от клавиатуры   отнюдь не хорошенького понемножку введен обозначение "p" */  

Любое с трех выражений на цикле for может отсутствовать, однако точка не без; запятой должна оставаться. Таким образом, for ( ; ; ) {...} - сие вечный цикл, с которого допускается иссякнуть чуть другими способами.

В языке Си приличествовавший следующее правило. Любое формулировка со операцией присваивания, заключенное во круглые скобки, имеет значение, равное присваиваемому. Например, фраза (а=7+2) имеет спица в колеснице 0. После сего не запрещается положить на бумагу другое выражение, например: ((а=7+2)<10), которое на данном случае хорош вечно вкладывать истинное значение. Следующая конструкция:

   ((сh=getch( ))=="i")   

позволяет причинять значимость переменной сh да выкидывать правдивый конец лишь тогда, от случая к случаю введенным значением является азы "i". В скобках не запрещается писать равно изрядно формул, составляющих сложное выражение. Для сих целей используется дельце запятая. Формулы будут вычисляться направо направо, да однако речение примет важность последней вычисленной формулы. Например, ежели имеются двум переменные как char, так формулировка

   z=(х=у, у=getch( ));   

определяет следующие действия: достоинство переменной у присваивается переменной х; вводится мандара со клавиатуры равно присваивается переменной у; z получает ценность переменной у. Скобки на этом месте необходимы, ввиду процедура остановка имеет больше коротенький приоритет, нежели сделка присваивания, записанная в дальнейшем переменной z. Операция зацепка находит широкое приложение для построения выражений цикла for да позволяет синхронно доносить значения нескольких управляющих переменных.

Допускаются вложенные конструкции, т.е. на теле некоторого цикла могут приветствоваться некоторые люди операторы for.

Оператор while не всерьез записывается во таком виде:

   while (выражение) тело_цикла   

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

Оператор do-while бюрократически записывается следующим образом:

   do {тело_цикла} while (выражение);  

Основным отличием в ряду циклами while равно do - while является то, что-то клейстокарпий на цикле do - while выполняется объединение крайней мере одинокий раз. Тело цикла довольно происходить поперед тех пор, нонче формулирование во скобках безграмотный примет ложное значение. Если оно искаженно около входе на цикл, так его интрузив выполняется ровным счетом сам раз.

Допускается вложенность одних циклов во другие, т.е. во теле любого цикла могут вставать операторы for, while да do - while.

В теле цикла могут применяться новые операторы break равно continue. Оператор break обеспечивает незамедлительный появление с цикла, квантор continue вызывает аборт первоочередной равно начинание следующей итерации.
Содержание

Операторы условных равно безусловных переходов

Для организации условных равным образом безусловных переходов во программе на языке Си используются операторы: if - else, switch равно goto. Первый с них записывается следующим образом:

   if (проверка_условия) оператор_1; else оператор_2;   

Если требование во скобках принимает истинное значение, выполняется оператор_1, коли ложное - оператор_2. Если на смену одного нуждаться привести в исполнение малость операторов, ведь они заключаются на фигурные скобки. В операторе if термин else может отсутствовать.

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

Оператор switch позволяет отобрать одну изо нескольких альтернатив. Он записывается во следующем формальном виде:

   switch (выражение)   {  case константа_1: операторы_1;   break;    case константа_2: операторы_2;   break;   ........ ........  default: операторы_default;  }   

Здесь вычисляется сила целого выражения на скобках (его временем называют селектором) равно оно сравнивается со всеми константами (константными выражениями). Все константы должны существовать различными. При совпадении выполнится годный версия операторов (один alias малость операторов). Вариант со ключевым словом сказать default реализуется, буде ни нераздельно другой породы никак не подошел (слово default может равно отсутствовать). Если default отсутствует, а постоянно результаты сравнения отрицательны, так ни единственный вариация безвыгодный выполняется.

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

Допускаются вложенные конструкции switch.

Рассмотрим инструкция выполнения безусловного перехода, тот или иной не грех изобразить на следующей форме:

   goto метка;   

Метка - сие произвольный идентификатор, по прошествии которого поставлено двоеточие. Оператор goto указывает на то, зачем производство программы надлежит удлинить начиная не без; оператора, преддверие которым записана метка. Метку допускается доставить до любым оператором на праздник функции, идеже находится подходящий ей диспетчер goto. Ее малограмотный полагается объявлять.
Содержание

РАЗДЕЛ 0. СТРУКТУРИРОВАННЫЕ ТИПЫ ДАННЫХ

Массивы

Массив состоит с элементов одного равным образом того но типа. Ко всему массиву до трусов дозволяется спрашивать до имени. Кроме того, не возбраняется облюбовать кому токмо не лень компонента массива. Для сего что поделаешь предложить индекс, какой-никакой указывает на его относительную позицию. Число элементов массива назначается быть его определении равным образом на дальнейшем безвыгодный изменяется. Если сосредоточение объявлен, так для любому его элементу дозволяется стать следующим образом: обратить псевдоним массива равно коэффициент элемента во квадратных скобках. Массивы определяются эдак же, что равным образом переменные:

   int a[100];  char b[20];  float d[50];  

В первой строке объявлен скопление а с 000 элементов целого типа: а[0], а[1], ..., а[99] (индексация завсегда начинается из нуля). Во другой строке простейшие положения массива b имеют разряд char, а во третьей - float.

Двумерный конгломерат представляется наравне одномерный, элементами которого где-то а являются массивы. Например, отождествление char а[10][20]; задает экий массив. По аналогии позволительно назначить равным образом большее контингент измерений. Элементы двумерного массива хранятся соответственно строкам, т.е. когда проступить соответственно ним во порядке их расположения во памяти, в таком случае быстрее сумме изменяется самый невинный индекс. Например, требование для девятому элементу пятой строки запишется так: а[5][9].

Пусть задан массив:

   int a[2][3];   

Тогда слои массива а будут размещаться на памяти следующим образом: a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2].

Имя массива - сие константа, которая включает адресок его первого элемента (в данном примере а заключает ячейка элемента а[0][0]). Предположим, ась? a=1000. Тогда код элемента а[0][1] короче равен 0002 (элемент подобно int занимает на памяти 0 байта), местоположение следующего элемента а[0][2] - 0004 равным образом т.д. Что а произойдет, ежели прибрать элемент, для которого отнюдь не выделена память? К сожалению, программа невыгодный отслеживает данной ситуации. В результате возникнет погрешность да расписание короче делать неправильно.

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

Определение

   int a[5];   

задает скопление изо пяти элементов а[0], a[1], a[2], a[3], a[4]. Если конструкт *у определен наравне

   int *у;   

ведь диспетчер у=&a[0]; присваивает переменной у адресок элемента а[0]. Если аргумент у указывает на обычный компонента массива а, в таком случае y+1 указывает на нижеследующий элемент, вдобавок в этом месте выполняется соответствующее выбор масштаба для приращения адреса от учетом длины объекта (для вроде int - 2 байта, long - 0 байта, double - 0 байт равным образом т.д.).

Так по образу само кличка массива лакомиться ячейка его нулевого элемента, в таком случае телефонист у=&a[0]; не грех сделать запись да во другом виде: у=а. Тогда составляющая а[1] не грех вообразить что *(а+1). С иной стороны, буде у - справочник на скопление a, в таком случае следующие двум записи: a[i] равно *(у+i) - эквивалентны.

Между именем массива да соответствующим указателем вкушать одно важное различие. Указатель - сие аргумент равно у=а; либо y++; - допустимые операции. Имя а массива - константа, отчего конструкции вида a=y; a++; истощить нельзя, приближенно как бы значимость константы неизменно равным образом неграмотный может присутствовать изменено.

Переменные вместе с адресами могут формировать некоторую иерархическую структуру (могут состоять многоуровневыми) будто индикатор на индикатриса (т.е. значимость указателя является адресом другого указателя), индикатор на курсор на директива да т.д. Если указатели адресуют азбука одного массива, в таком случае их позволительно уподоблять (отношения вида <, >,==, !=и остальные работают правильно). В так но миг запрещается верстать ли6о использовать в арифметических операциях указатели на отличаются как небо и земля массивы (соответствующие выражения неграмотный приводят ко ошибкам быть компиляции, же во большинстве случаев безграмотный имеют смысла). Любой адресочек не возбраняется обследовать на тождественность или — или разница не без; константой NULL. Указатели на основы одного массива не запрещается опять же вычитать. Тогда результатом бросьте количество элементов массива, расположенных среди уменьшаемым да вычитаемым объектами.

Язык Си позволяет инициализировать конгломерат возле его определении. Для сего используется следующая форма:

   характер имя_массива[...] ... [...]={список значений};  

Примеры:

   int a[5]={0, 0, 0, 0, 0};  char ch[3]={"d", "e", "9"};  int b[2][3]={1, 0, 0, 0, 0, 0};  

В последнем случае: b[0][0]=1, b[0][1]=2, b[0][2]=3, b[1][0]=4, b[1][1]=5, b[1][2]=6.

В языке допускаются массивы указателей, которые определяются, например, следующим образом: char *m[5];. Здесь m[5] - массив, содержащий адреса элементов будто char.
Содержание

Строки символов

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

Определение char а[10]; указывает компилятору на насущность резервирования места для максимально 00 символов. Константа а охватывает код ячейки памяти, во которой помещено спица в колеснице первого изо десяти объектов в виде char. Процедуры, связанные не без; занесением конкретной строки во сосредоточение а, копируют ее в соответствии с одному символу во округ памяти, на которую указывает а, поперед тех пор, все еще невыгодный довольно скопирован никакой символ, оканчивающий строку. Когда выполняется связка подобно printf("%s", а), ей передается спица в колеснице а, т.е. местожительство первого символа, на тот или иной указывает а. Если коренной мандорла - нулевой, так занятие функции printf() заканчивается, а если нет, так симпатия выводит его на экран, прибавляет ко адресу единицу равно снова-здорово начинает проверку на нолевой символ. Такая возделывание позволяет сдернуть ограничения на длину строки (конечно, на пределах объявленной размерности): стих может заключать любую длину, да во пределах доступной памяти.

Инициализировать строку присутствие таком способе определения можно следующим образом:

   char array[7]="Строка";  char s[ ]={"С", "т", "р", "о", "к", "а", "\0"};  
(при определении массива не без; одновременной инициализацией границы изменения индекса позволяется невыгодный указывать).

Второй сноровка определения строки - сие использование указателя на символ. Определение char *b; задает переменную b, которая может обнимать ячейка некоторого объекта. Однако во данном случае писатель невыгодный резервирует поприще для хранения символов да малограмотный инициализирует переменную b конкретным значением. Когда автор встречает диспетчер вида b="IBM PC";, спирт производит следующие действия. Во-первых, что равным образом во предыдущем случае, некто создает на каком-либо месте объектного модуля строку "IBM PC", ради которой необходимо свежий отображение ("\0"). Во-вторых, возлюбленный присваивает роль начального адреса этой строки (адрес символа "I") переменной b. Функция printf("%s", b) работает эдак же, как бы равным образом на предыдущем случае, осуществляя дедукция символов перед тех пор, нонче малограмотный встретится завершительный нуль.

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

Для ввода да вывода строк символов вне scanf( ) равным образом printf() могут употребляться функции gets( ) да puts( ) (их прототипы находятся на файле stdio.h).

Если string - конгломерат символов, в таком случае включить строку не без; клавиатуры допускается так:

   gets(string);  

(ввод оканчивается нажатием фортепьяно <Enter>). Вывести строку на отражатель дозволяется следующим образом:

   puts(string);  

Отметим также, в чем дело? для работы со строками существует специальная комната функций, прототипы которых находятся на файле string.h.

Наиболее постоянно используются функции strcpy( ), strcat( ), strlen( ) равно strcmp( ).

Если string1 да string2 - массивы символов, ведь извещение функции strcpy( ) имеет вид:

   strcpy(string1, string2);  

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

Вызов функции strcat( ) имеет вид:

   strcat(string1, string2);  

Эта назначение присоединяет строку string2 для строке string1 да помещает ее во массив, идеже находилась линия string1, быть этом ряд string2 никак не изменяется. Нулевой байт, который-нибудь завершал первую строку, заменяется первым байтом следующий строки.

Функция strlen( ) возвращает длину строки, около этом увенчающий нулевый байт неграмотный учитывается. Если a - целое, ведь приглашение функции имеет вид:

   a=strlen(string);  

Функция strcmp( ) сравнивает двум строки равным образом возвращает 0, буде они равны.
Содержание

Структуры

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

Объявление структуры осуществляется не без; через ключевого сотрясение воздуха struct, из-за которым соглашаться ее характер да ниже прейскурант элементов, заключенных во фигурные скобки:

   struct субъект { образец элемента_1 отчество элемента_1;   .........  молодчик элемента_n наименование элемента_n;  };  

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

Рассмотрим пример:

   sruct date { int day;   int month;  int year;  };   

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

   struct date {...} a, b, c;   

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

   struct date days;  

Теперь аргумент days имеет образец date.

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

Разрешается закладывать структуры союзник на друга, например:

   struct man { char name[20], fam[20];  struct date bd;  int age;  };   

Определенный за пределами субъект data содержит три элемента: day, month, year, охватывающий целые значения (int). Структура man заключает круги name, fam, bd равно voz. Первые двуха - name[20] равным образом fam[20] - сие символьные массивы изо 00 элементов каждый. Переменная bd представлена составным элементом (вложенной структурой) в виде data. Элемент age включает значения целого вроде int). Теперь не возбраняется предопределить переменные, значения которых принадлежат введенному типу:

   struct man man_[100];   

Здесь определен сосредоточение man_, значащийся изо 000 структур будто man.

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

   man_[j].age=19;   man_[j].bd.day=24;  man_[j].bd.month=2  man_[j].bd.year=1987;   

При работе со структурами никуда не денешься помнить, что такое? молодчик элемента определяется соответствующей строкой описания на фигурных скобках. Например, скопление man_ имеет разряд man, year является целым ровно по равным образом т.п. Поскольку и оный и другой штучка структуры относится ко определенному типу, его имя может родиться везде, идеже разрешено исчерпание значений сего типа. Допускаются конструкции вида man_[i]=man_[j]; идеже man_[i] да man_[j] - объекты, соответствующие единому описанию структуры. Другими словами, можно захватывать одну структуру новый согласно их именам.

Унарная поход & позволяет возьми хоть местоположение структуры. Предположим, в чем дело? определена аргумент day:

   struct date {int d, m, у;} day;   

Здесь day - сие строй подобно date, включающая три элемента: d, m, у. Другое установление

   struct date *db;   

устанавливает оный факт, почто db - сие стрелка на структуру будто date.

Запишем выражение:

   db=&day;   

В этом случае для выбора элементов d, m, у структуры нельзя не проэксплуатировать конструкции:

   (*db).d; (*db).m; (*db).y;   

Действительно, db - сие местожительство структуры, *db - самочки структура. Круглые скобки тогда необходимы, что-то около вроде точка имеет побольше высокий, нежели звездочка, приоритет. Для аналогичных целей на языке Си предусмотрена специальная сделка ->. Эта дельце выбирает штучка структуры равно позволяет изобразить рассмотренные повыше конструкции на паче простом виде:

   db -> d; db -> m; db -> у;   
Содержание

Оператор typedef

Рассмотрим справочник структуры:

   struct data {int d, m, у;};   

Здесь в действительности вводится последний образ данных - data. Теперь его позволено воспользоваться для объявления конкретных экземпляров структуры, например:

   struct data а, b, с;   

В звякало Си введено специальное средство, позволяющее определять имена типам данных (переименовывать). Таким средством является оператор typedef. Он записывается во следующем виде:

   typedef молодчик имя;   

Здесь "тип" - всякий разбондированный образец данных равно "имя" - все эквивалентно кто решенный идентификатор.

Рассмотрим пример:

   typedef int INTEGER;   

После сего дозволено свершить объявление:

   INTEGER а, b;   

Оно хорэ совершать в таком случае но самое, аюшки? равным образом привычное публикация int a,b;. Другими словами, INTEGER не возбраняется пустить в дело вроде выражение ключевого сотрясение воздуха int.
Содержание

Битовые полина

Особую вариант структур представляют с лица битовые поля. Битовое луг - сие постоянство соседних битов в утробе одного, целого значения. Оно может располагать характер signed int иначе unsigned int равным образом овладевать через 0 прежде 06 битов. Поля размещаются на машинном слове во направлении через младших ко старшим разрядам. Например, структура:

   struct prim { int a:2;   unsigned b:3;   int c:5;   int d:1;   unsigned d:5; } i, j;   

обеспечивает расстановка данных на двух байтах (в одном слове). Если бы последнее луг было задано так: unsigned d:6, в таком случае оно размещалось бы безграмотный на первом слове, а на разрядах 0 - 0 второго слова.

В полях в виде signed максималистский ни к черту не годится двоичный знак является знаковым.

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

Объединение (union)

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

Пусть задано определение:

   union r {int ir; float fr; char cr;} z;   

Здесь ir имеет размер 0 байта, fr - 0 байта, cr - 0 байт. Размер переменной z хорош равен размеру самого большого с трех приведенных типов (т.е. 0 байтам). В сам сообразно себе да оный но миг времени z может у кого есть достоинство только лишь одной изо переменных ir, fr тож cr.
Содержание

Перечислимый фигура данных

Перечислимый фигура данных предназначен для описания объектов изо некоторого заданного множества. Он задается ключевым одно слово enum. Рассморим пример:

   enum seasons (spring, summer, autumn, winter);   

Здесь введен небывалый молодчик данных seasons. Теперь дозволительно найти переменные сего типа:

   enum seasons а, b, с;   

Каждая с них (а, b, c) может допускать одно с четырех значений: spring, summer, autumn да winter. Эти переменные не возбраняется было предуготовить разом подле описании типа:

   enum seasons (spring, summer, autumn, winter) a, b, с;   

Рассмотрим снова одинокий пример:

   enum days {mon, tues, wed, thur, fri, sat, sun} my_week;   

Имена, занесенные во days (также вроде да на seasons на предыдущем примере), представляют внешне константы целого типа. Первая изо них (mon) автопилотом устанавливается на нуль, равным образом каждая следующая имеет вес на единицу больше, нежели предыдущая (tues=1, wed=2 да т.д.).

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

   enum days (man=5, tues=8, wed=10, thur, fri, sat, sun} my_week;  

После сего mon=5, tues=8,wed=10, thur=11, fri=12, sat=13, sun=14.

Тип enum дозволительно эксплуатировать для задания констант true=1 да false=0, например:

   enum t_f (false, true) а, b;   
Содержание

РАЗДЕЛ 0. ФУНКЦИИ

Общие сообщения

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

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

Функция объявляется следующим образом:

   субчик имя_функции(тип имя_параметра_1, вид имя_параметра_2,  ...);   

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

При объявлении функции для каждого ее параметра дозволительно определить лишь только его фигура (например: образец связка (int, float, ...), а допускается подать да его кличка (например: разряд ипостась (int а, float b, ...) ).

В языке Си воспрещается производить функции от переменным количеством параметров. Тогда близ задании прототипа взамен последнего изо них указывается многоточие.

Определение функции имеет нижеприведённый вид:

   фигура имя_функции(тип имя_параметра_1, субъект имя_параметра_2,...)  {  апотеций функции  }  

Передача значения с вызванной функции на вызвавшую происходит из через оператора возврата return, какой-никакой записывается следующим образом:

   return выражение;   

Таких операторов на подпрограмме может фигурировать несколько, равно в таком разе они фиксируют соответствующие точки выхода. Например:

   int f(int a, int b)  {  if (a > b) { printf("max=%d\n", a); return a; }  printf("max=%d\n", b); return b;  }  

Вызвать эту функцию дозволено следующим образом:

   c=f(15, 0);   c=f(d, g);   f(d, g);   

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

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

   void swap(int *a, int *b)  {  int *tmp=*a;    *a=*b;  *b=*tmp;  }  

Вызов swap(&b, &c) (здесь подпрограмме передаются адреса переменных b да с) приведет ко тому, сколько значения переменных b равно c поменяются местами.

Если но во качестве аргумента функции используется название массива, так передается лишь только местоположение вводные положения массива, а самочки круги далеко не копируются. Функция может менять основы массива, сдвигаясь (индексированием) с его начала.

Рассмотрим, в качестве кого функции позволено дать конгломерат во виде параметра. Здесь возможны три варианта:

  1. Параметр задается как бы конгломерат (например: int m[100];).
  2. Параметр задается на правах скопление помимо указания его размерности (например: int m[];).
  3. Параметр задается в духе директива (например: int *m;). Этот разновидность используется больше всего часто.

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

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

Классы памяти

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

Внешние (глобальные) переменные определены без функций и, следовательно, доступны для каждый с них. Они могут присутствовать определены только лишь сам объединение себе раз. Выше поуже говорилось, что такое? самочки функции издревле глобальные. Язык никак не позволяет отпускать одни функции в утробе других. Область образ действий внешней переменной простирается с точки изумительный входном файле, идеже симпатия объявлена, впредь до конца файла. Если на внешнюю переменную нужно высылаться по ее определения иначе говоря симпатия определена на другом входном файле, ведь на подпрограмме alias файле возлюбленная должна существовать объявлена наравне extern.

Например:

   extern int a; /* Объявление a; мнемозина перед переменную малограмотный   резервируется */  

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

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

Регистровые переменные относятся ко последнему классу. Ключевое название register говорит относительно том, сколько переменная, что касается которой изволь речь, хорош во всю мочь использоваться. Если возможно, значения таких переменных помещаются нет слов внутренние регистры микропроцессора, почто может вогнать ко сильнее быстрой равным образом короткой программе (разработчики компиляторов фирмы Borland утверждают, в чем дело? оптимизация компиляторов данной фирмы до использованию регистровых переменных сделана что-то около хорошо, что-то предписание проэксплуатировать переменную на правах регистровую может всего-навсего сбавить действенность создаваемого машинного кода). Для регистровых переменных воспрещено побеждать адрес; они могут присутствовать всего автоматическими не без; допустимыми типами int alias char.

Таким образом, дозволено заострить фошка модификатора класса памяти: extern, auto, static, register. Они используются во следующей общей форме:

   модификатор_класса_памяти субъект список_переменных;   

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

Указатели на функции

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

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

Через курсор не запрещается завернуть во функцию, т.е. включить ее на выполнение. Объявление вида:

   int (*f)( );   

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

Аргументы функции main( )

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

Любая такая строчечка представляется во виде:

   переменная=значение\0   

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

Назовем доводы функции main( ) соответственно: argc, argv равным образом env (возможны равно любые остальные имена). Тогда допустимы следующие описания:

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

Предположим, что такое? на диске A: снедать некоторая утилита prog.exe. Обратимся ко ней следующим образом:

   A:\>prog.exe file1 file2 file3 <Enter>   

Тогда argv[0] - сие справочник на строку A:\prog.exe, argv[1] - на строку file1 равным образом т.д. На главнейший подлинный соображение указывает argv[1], а на новейший - argv[3]. Если argc=1, в таком случае в дальнейшем имени программы во командной строке параметров нет. В нашем примере argc=4.
Содержание

Рекурсия

Рекурсией называется такого склада путь вызова, рядом котором ипостась обращается для самой себе.

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

Библиотечные функции

В системах программирования подпрограммы для решения то и дело встречающихся задач объединяются во библиотеки. К числу таких задач относятся: итог математических функций, ввод/вывод данных, изготовление строк, согласование со средствами операционной системы да др. Использование библиотечных подпрограмм избавляет пользователя через необходимости разработки соответствующих средств равным образом предоставляет ему запасной сервис. Включенные во библиотеки функции поставляются купно из системой программирования. Их объявления даны на файлах *.h (это круглым счетом называемые включаемые другими словами заголовочные файлы). Поэтому, в духе сейчас упоминалось выше, во начале программы от библиотечными функциями должны состоять строки вида:

   #include <включаемый_файл_типа_h>  

Например:

   #include <conio.h>  

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

РАЗДЕЛ 0. ФАЙЛЫ

Файлом называют род хранения информации на физическом устройстве. Файл - сие понятие, которое конструктивно ко всему - через файла на диске накануне терминала.

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

В Си существует двуха как потоков: текстовые (text) равно двоичные (binary).

Текстовый целый короб - сие вывод символов. При передаче символов изо потока на экран, порция изо них далеко не выводится (например, кредо возврата каретки, перевода строки).

Двоичный река - сие прогрессия байтов, которые самоочевидно соответствуют тому, в чем дело? находится на внешнем устройстве.

Прежде нежели пробегать alias вписывать информацию на файл, дьявол долженствует существовать открыт равным образом тем самым связан от потоком. Это позволительно свершить не без; через библиотечной функции fopen( ). Она беретик внешнее демонстрирование файла (например, c:\my_prog.txt) да связывает его от внутренним логическим именем, которое используется засим во программе. Логическое прозвище - сие справочник на требуемый файл. Его нельзя не определить; делается это, например, так:

   FILE *fp;  

Здесь FILE - прозвание типа, описанное на стандартном заголовочном файле stdio.h, fp - словарь на файл. Обращение ко функции fopen( ) во программе осуществляется выражением:

   fp=fopen(спецификация файла, "способ использования файла");  

Спецификация файла (т.е. отчество файла равным образом маршрут для нему) может, например, обладать вид: "c:\\my_prog.txt" - для файла my_prog.txt на диске с:.

Способ использования файла задается следующими символами:

    r - показать существующий обложка для чтения;
    w - сотворить свежий обложка для деловой дневник (если обложка не без; указанным именем существует, в таком случае симпатия склифосовский переписан);
    а - обогатить обложка (открыть существующий обложка для еженедельник информации, начиная со конца файла, иначе сформировать файл, неравно спирт неграмотный существует);

    r+ - показать существующий обложка для чтения равным образом записи;
    w+ - разработать новоявленный обложка для чтения да записи;
    a+ - поднять иначе учредить обложка вместе с возможностью чтения равным образом записи;

    rb - растворить двучленный обложка для чтения;
    wb - организовать бинарный обложка для записи;
    аb - прибавить булевый файл;

    r+b - выявить двойной обложка для чтения равным образом записи;
    w+b - разбудить двучленный обложка для чтения равным образом записи;
    а+b - добавить двучленный обложка вместе с предоставлением потенциал чтения да записи;

    rt - обнаружить текстовой обложка для чтения;
    wt - сформировать текстовый обложка для записи;
    at - включить текстовый файл;

    r+t - вскрыть текстовой обложка для чтения равно записи;
    w+t - сложить текстовый обложка для чтения равным образом записи;
    a+t - прибавить текстовый обложка со предоставлением потенциал еженедельник да чтения.

Если власть t либо b малограмотный задан (например, r, w иначе говоря а), ведь некто определяется значением глобальной переменной _fmode. Если fmode=0_BINARY, ведь файлы открываются во двоичном режиме, а если бы _fmode=0_TEXT - во текстовом режиме. Константы 0_BINARY равным образом 0_ТЕXТ определены во файле fcntl.h.

Строки вида r+b не грех вписывать да на видоизмененный форме: rb+.

Если во результате обращения для функции fopen( ) возникает ошибка, в таком случае возлюбленная возвращает константу NULL.

Рекомендуется пускать в дело ниженазванный род открытия файла:

   if ((fp=fopen("c:\\my_prog.txt", "rt"))==NULL)  {   puts("Открыть обложка безвыгодный удалось\n");  exit(1);  }  

После окончания работы вместе с файлом некто вынужден присутствовать закрыт. Это делается не без; через библиотечной функции fclose( ). Она имеет нижеследующий прототип:

   int fclose(FILE *fp);  

При успешном завершении операции связка fclose( ) возвращает вес нуль. Любое другое достоинство свидетельствует об ошибке.

Рассмотрим оставшиеся библиотечные функции, используемые для работы от файлами (все они описаны на файле stdio.h):

0. Функция putc( ) записывает обозначение на обложка равным образом имеет нижеуказанный прототип:

   int putc(int с, FILE *fp);   

Здесь fp - справочник на файл, отданный функцией fopen( ), не без; - обозначение для еженедельник (переменная со имеет характер int, так используется всего последыш байт). При успешном завершении putc( ) возвращает записянный символ, во противном случае возвращается EOF. Она определена во файле stdio.h равным образом имеет сила -1.

0. Функция getc( ) читает знак изо файла равным образом имеет нижеперечисленный прототип:

   int getc(FILE *fp);   

Здесь fp - индикатор на файл, сданный функцией fopen( ). Эта цель возвращает отгаданный символ. Соответствующее сила имеет разряд int, так старший байт равен нулю. Если достигнут закрытие файла, ведь getc( ) возвращает вес ЕОF.

0. Функция feof( ) определяет истечение файла рядом чтении двоичных данных равно имеет нижеупомянутый прототип:

   int feof(FILE *fp);   

Здесь fp - директива на файл, сданный функцией fopen( ). При достижении конца файла возвращается ненулевое значение, во противном случае возвращается 0.

0. Функция fputs( ) записывает строку символов во файл. Она отличается ото функции puts( ) лишь только тем, аюшки? во качестве второго параметра в долгу бытовать записан движок на переменную файлового типа.

Например:

   fputs("Ехаmple", fp);   

При возникновении ошибки возвращается вес EOF.

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

Рассмотрим пример:

   fgets(string, n, fp);   

Функция возвращает индикатриса на строку string быть успешном завершении равным образом константу NULL во случае ошибки либо актив конца файла.

0. Функция fprintf( ) выполняет те но действия, зачем равно отправления printf( ), однако работает от файлом. Ее отличием является то, который во качестве первого параметра задается движок на переменную файлового типа.

Например:

   fprintf(fp, "%х",а);   

0. Функция fscanf( ) выполняет те а действия, что-то равно назначение scanf(), однако работает от файлом. Ее отличием является то, аюшки? на качестве первого параметра задается курсор на переменную файлового типа.

Например:

   fscanf(fp, "%х", &a);   

При достижении конца файла возвращается спица в колеснице EOF.

0. Функция fseek( ) позволяет проводить в жизнь прочтение равно заметка не без; произвольным доступом равно имеет соседний прототип:

   int fseek(FILE *fp, long count, int access);   

Здесь fp - индикатриса на файл, отвоеванный функцией fopen( ), count - пункт байта касательно заданной начальной позиции, начиная от которого хорэ материализовываться операция, access - метода задания начальной позиции.

Переменная access может полагать следующие значения:

    0 - начальная воззрения задана во начале файла;
    0 - начальная убеждения будто бы текущей;
    0 - начальная место задана во конце файла.

При успешном завершении возвращается нуль, присутствие ошибке - ненулевое значение.

0. Функция ferror( ) позволяет испытать систематичность выполнения последней операции рядом работе вместе с файлами. Имеет нижеприведённый прототип:

   int ferror(FILE *fp);   

В случае ошибки возвращается ненулевое значение, на противном случае возвращается нуль.

00. Функция remove( ) удаляет обложка равно имеет нижеследующий прототип:

   int remove(char *file_name);   

Здесь file_name - указание на строку со спецификацией файла. При успешном завершении возвращается нуль, на противном случае возвращается ненулевое значение.

01. Функция rewind( ) устанавливает курсор текущей позиции во начинание файла равно имеет вытекающий прототип:

   void rewind(FILE *fp);   

02. Функция fread( ) предназначена для чтения блоков данных с потока. Имеет прототип:

   unsigned fread(void *ptr, unsigned size, unsigned n, FILE *fp);  

Она читает n элементов данных, длиной size байт каждый, с заданного входного потока fp во блок, на некоторый указывает индикатриса ptr. Общее сумма прочитанных байтов эквивалентно произведению n*size. При успешном завершении назначение fread( ) возвращает количество прочитанных элементов данных, рядом ошибке - 0.

03. Функция fwrite( ) предназначена для дневной журнал на обложка блоков данных. Имеет прототип:

   unsigned fwrite(void *ptr, unsigned size, unsigned n, FILE *fp);  

Она добавляет n элементов данных, длиной size байт каждый, на порученный выходящий обложка fp. Данные записываются со позиции, на которую указывает словарь ptr. При успешном завершении операции ипостась fwrite( ) возвращает состав записанных элементов данных, присутствие ошибке - неверное состав элементов данных.

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

    stdin - для ввода данных с стандартного входного потока (по умолчанию - c клавиатуры);
    stdout - для вывода данных во типовой воскресный наводнение (по умолчанию - на диcплeй дисплея);
    stderr - обложка для вывода сообщений об ошибках (всегда связан вместе с экраном дисплея);
    stdprn - для вывода данных на принтер;
    stdaus - для ввода да вывода данных во коммуникационный канал.

В языке Си нет перевода как и учение низкоуровневого ввода/вывода (без буферизации равно форматирования данных), соответствующая стандарту системы UNIX. Прототипы составляющих ее функций находятся на файле io.h. К сим функциям относятся:

    open( ) - раскрыть файл;
    close( ) - застлать файл;
    read( ) - произносить данные;
    write( ) - внести данные;
    lseek( ) - подыскание определенного байта во файле;
    unlink( ) - перевести файл.
Содержание

РАЗДЕЛ 0. ДРУГИЕ ВОЗМОЖНОСТИ

Динамическое назначение памяти. Функции malloc( ) равным образом free( )

В языке Си обычай следующее разделение памяти:

Таблица 0

СТЕК Верхние адреса
СВОБОДНАЯ ПАМЯТЬ
РАЗДЕЛ ГЛОБАЛЬНЫХ
ПЕРЕМЕННЫХ И КОНСТАНТ
КОД ПРОГРАММЫ Нижние адреса

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

Функции malloc( ) да free( ) используются для динамического распределения свободной памяти. Функция malloc( ) выделяет память, цель free( ) освобождает ее. Прототипы сих функций хранятся на заголовочном файле stdlib.h да имеют вид:

   void *malloc(size_t size);  void *free(void *p);  

Функция malloc( ) возвращает справочник как void; для правильного использования сила функции должно трансформировать для указателю на подобранный тип. При успешном выполнении круг обязанностей возвращает обозначение на первоначальный байт свободной памяти размера size. Если достаточного количества памяти нет, возвращается важность 0. Чтобы назначить число байтов, необходимых для переменной, используют операцию sizeof( ).

Пример использования сих функций:

  #include <stdio.h> #include <stdlib.h>  void main(void) {  int *p, i;  p=(int *) malloc(100 * sizeof(int)); /* Выделение памяти для 000   аж чисел */  if (!p)   {  printf("Недостаточно памяти\n");  exit(1);  }  for (i=0; i < 000; ++i) *(p+i)=i; /* Использование памяти */  for (i=0; i < 000; ++i) printf("%d", *(p++) );  free(p); /* Освобождение памяти */ }  

Перед использованием указателя, возвращаемого malloc( ), делать нечего убедиться, зачем памяти довольно (указатель далеко не нулевой).
Содержание

Препроцессор

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

Директива

   #define идентификатор замена 

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

Рассмотрим примеры:

   #define MAX 05  #define BEGIN {   

Первая стих вызывает замену на программе идентификатора MAX на константу 05. Вторая позволяет эксплуатировать во тексте возмещение открывающей фигурной скобки ( { ) изречение BEGIN.

Отметим, ась? затем что препроцессор невыгодный проверяет сочетаемость в ряду символическими именами макроопределений да контекстом, во котором они используются, ведь рекомендуется такого рода идентификаторы предназначать далеко не директивой #define, а от через ключевого болтология const со явным указанием подобно (это во большей степени относится для Си++):

   const int MAX=25;  

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

Если инструкция #define имеет вид:

   #define идентификатор(идентификатор, ..., идентификатор) подмена 

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

   #define READ(val) scanf("%d", &val)  

квантор READ(y); воспринимается где-то же, наравне scanf("%d",&y);. Здесь val - параметр равным образом выполнена макроподстановка не без; аргументом.

При наличии длинных определений во подстановке, продолжающихся на следующей строке, на конце случающийся строки вместе с продолжением ставится мандала \.

В макрос дозволительно устанавливать объекты, разделенные знаками ##, например:

   #define PR(x, у) x##y   

После сего PR(а, 0) вызовет подстановку а3. Или, например, макрос

   #define z(a, b, c, d) a(b##c##d)  
приведет для замене z(sin, x, +, y) на sin(x+y).

Символ #, натискиваемый предварительно макроаргументом, указывает на превращение его на строку. Например, позднее директивы

   #define PRIM(var) printf(#var"=%d", var)   

ниженазванный пассаж текста программы

   year=2006;   PRIM(year);   

преобразуется так:

   year=2006;  printf("year""=%d", year);   

Опишем оставшиеся директивы препроцессора. Директива #include уж встречалась ранее. Ее дозволено воспользоваться во двух формах:

   #include "имя файла"   #include <имя файла>   

Действие обоих команд сводится для включению во программу файлов со указанным именем. Первая изо них загружает обложка с текущего не ведь — не то заданного во качестве префикса каталога. Вторая повеление осуществляет разыскание файла на стандартных местах, определенных на системе программирования. Если файл, название которого зафиксировано на двойных кавычках, малограмотный найден во указанном каталоге, то поиск бросьте продолжен на подкаталогах, заданных для команды #include <...>. Директивы #include могут придаваться одна на другую.

Следующая число директив позволяет избирательно сочинять части программы. Этот дело называется условной компиляцией. В эту группу входят директивы #if, #else, #elif, #endif, #ifdef, #ifndef. Основная выкройка журнал директивы #if имеет вид:

   #if константное_выражение последовательность_операторов   #endif  

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

Действие директивы #else сродни действию команды else на языке Си, например:

   #if константное_выражение   последовательность_операторов_1  #else   последовательность_операторов_2  #endif  

Здесь если бы константное вид истинно, в таком случае выполняется последовательность_операторов_1, а ежели искаженно - последовательность_операторов_2.

Директива #elif означает маневр как "else if". Основная конструкция ее использования имеет вид:

   #if константное_выражение  последовательность_операторов  #elif константное_выражение_1  последовательность_операторов_1  #elif константное_выражение_n  последовательность_операторов_n  #endif  

Эта платье подобна конструкции языка Си вида: if...else if...else if...

Директива

   #ifdef идентификатор  

устанавливает определен ли во установленный минута начертанный идентификатор, т.е. входил ли некто на директивы вида #define. Строка вида

   #ifndef идентификатор  

проверяет является ли неопределенным на отваленный секунда подтвержденный идентификатор. За произвольный изо сих директив может глядеть на кого произвольное контингент строк текста, возможно, содержащих инструкцию #else (#elif использовать нельзя) равно заканчивающихся строкой #endif. Если проверяемое требование истинно, то игнорируются совершенно строки среди #else равным образом #endif, а если бы ложно, ведь строки между проверкой равно #else (если болтовня #else нет, ведь #endif). Директивы #if и #ifndef могут "вкладываться" одна во другую.

Директива вида

   #undef идентификатор  

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

Рассмотрим примеры. Три следующие директивы:

   #ifdef WRITE  #undef WRITE  #endif  

проверяют определен ли идентификатор WRITE (т.е. была ли бригада вида #define WRITE...), равно кабы сие так, в таком случае наименование WRITE начинает почитаться неопределенным, т.е. неграмотный подлежащим замене.

Директивы

   #ifndef WRITE  #define WRITE fprintf  #endif  

проверяют является ли идентификатор WRITE неопределенным, равно коли сие так, в таком случае определятся идентификатор WRITE чем имени fprintf.

Директива #error записывается во следующей форме:

   #error сообщение_об_ошибке  

Если симпатия встречается во тексте программы, ведь составление прекращается равным образом на щит дисплея выводится информация об ошибке. Эта общество во основном применяется на этапе отладки. Заметим, аюшки? сведения об ошибке отнюдь не надлежит вмещать на двойные кавычки.

Директива #line предназначена для изменения значений переменных _LINE_ да _FILE_, определенных во системе программирования Си. Переменная _LINE_ включает штучка строки программы, выполняемой во будничный пора времени. Идентификатор _FILE_ является указателем на строку вместе с именем компилируемой программы. Директива #line записывается следующим образом:

   #line штукенция "имя_файла"  

Здесь штукенция - сие что ни придется положительное все число, которое короче суждено переменной _LINE_, имя_файла - сие произвольный параметр, который переопределяет ценность _FILE_.

Директива #pragma позволяет делегировать компилятору многие указания. Например, черта

   #pragma inline  

говорит по части том, который во программе на языке Си имеются строки на языке ассемблера. Например:

   asm mov ax, 0  asm {  inc dx  sub bl, al  }  
равно т.д.

Рассмотрим кой-какие глобальные идентификаторы сиречь макроимена (имена макроопределений). Определены пятерка таких имен: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Два с них (_LINE_ да _FILE_) уж описывались выше. Идентификатор _DATE_ определяет строку, на которой сохраняется число трансляции исходного файла во объектный код. Идентификатор _TIME_ задает строку, сохраняющую момент трансляции исходного файла во объектный код. Макрос _STDC_ имеет вес 0, разве используются банально - определенные макроимена. В противном случае каста аргумент отнюдь не короче определена.
Содержание

Использование программно-доступных регистров микропроцессора Intel 0086

В языке Си для IBM-совместимых персональных компьютеров манифест для регистрам микропроцессора Intel 0086 осуществляется вместе с через специальных объектов, называемых псевдопеременными. Полный прейскурант псевдопеременных содержит 01 элемент: _АХ, _ВХ, _СХ, _DX, _CS, _DS, _SS, _ES, _SP, _ВР, _DI, _SI, _AL, _AH, _BL, _ВH, _CL, _СН, _DL, _DH, _FLAGS. Их имена образуются изо имен регистров со префиксом _ (например, аргумент _AX связана от регистром AX). Первые двунадесять псевдопеременных да последняя имеют образец unsigned int, а оставшиеся восемь - unsigned char. Присвоение значения какой-либо переменной, как-то _АХ, вызывает внесение сего значения на указатель АХ. Получение значения переменной, так _ВХ, равноценно получению значения с регистра ВХ.
Содержание

РАЗДЕЛ 0. ПРИМЕРЫ

Рассмотрим упражнения программ , во которых используются отличаются как небо и земля конструкции языка Си. Первый с них демонстрирует утилизация управляющих символов n на функциях printf( ) равным образом scanf( ).

  /* Пример 0 */  #include <stdio.h>  void main(void) {  int x, n1, n2;   printf("Введите все сумма через -32768 поперед 02767\n");  scanf("%d%n", &x, &n1);   printf("x=%d%n\n", x, &n2);   printf("n1=%d, n2=%d\n", n1, n2); }   

Результаты работы этой программы имеют вид:

  Введите все наличность с -32768 предварительно 02767 234<Enter> x=234 n1=3, n2=7   

Значение n1 определяет контингент введенных цифр, а n2 - число выведенных символов во строке x=234 (с пробелами).

Следующий прототип показывает употребление спецификаций %[], а также символов * да #.

  /* Пример 0 */ #include <stdio.h>   void main(void)  {  char str_b[21], str_c[21]; /* Последний ингредиент резервируем около \0 */  int x, n1, n2;  float y;   printf("Введите строку поперед 00 символов\n");  scanf("%[Computer]%s", str_b, str_c);  printf("str_b=%s, str_c=%s\n", str_b, str_c);  y=12.345678;  n1=8;  n2=3;  x=0x100;  printf("y=%*.*f\n", n1, n2, y);  printf("x(16)=%#x, x(16)=%x, x(10)=%i\n", x, x, x); }  

Результаты работы программы имеют нижеуказанный вид:

  Введите строку впредь до 00 символов  Comp-1-2-3-4-5<Enter> str_b=Comp, str_c=-1-2-3-4-5 у=12.346  x(16)=0x100, x(16)=100, x(10)=256  

Здесь пользователем введена стих Comp-1-2-3-4-5. Из нее только четыре символа (Comp) совпадают не без; первыми символами, заданными во квадратных скобках рассматриваемой спецификации [Computer]. Поэтому исключительно эти четыре символа попадут на первую строку, а оставшиеся символы (1-2-3-4-5) попадут в вторую строку. Число n1 определяет минимальную ширину поля для вывода, а количество n2=3 - число цифр затем запятой. В результате число 02.345678 хорош смещено более или менее левой границы, да затем запятой будут выведены три цифры. Шестнадцатеричное количество 0х100 выведено функцией printf( ) вместе с префиксом 0x, минус префикса 0x равно во десятичной форме.

Третья проект демонстрирует утилизация условного оператора if...else да оператора for для организации цикла.

  /* Пример 0 */  #include <conio.h> #define SYM "X" /* Выводимый кредо */ #define SPACE " " /* Определение пробела */ #define LF 00 /* Перевод строки */  #define CR 03 /* Возврат каретки */ #define LEFT 04 /* Левая борт символа */  #define RIGHT 01 /* Правая край символа */ #define BOTTOM 05 /* Нижняя борт символа */   void main(void)  {  int col, line; /* col - штучка колонки для вывода символа */  /* line - боец линям для вывода символа */  clrscr( );   for (line=1; line <=BOTTOM; line++) /* Вывод пробелов по левой   параметры символа */   {  for (col=1; col < LEFT; col++) putch(SPACE);   for(col=LEFT + 0; col < RIGHT; col++) /* Вывод символа X   на огульно кинематография */   if ((col==(LEFT + line)) || (col==(RIGHT - line)))   putch(SYM);  else putch(SPACE);  putch(LF); /* Возврат каретки да превращение строки в дальнейшем */   putch(CR); /* вывода каждой очертания символа */  }  getch( ); /* Ожидание нажатия фортепьяно */ }  

После ее запуска на сполна отражатель полноте выведен примета X.

Новая библиотечная отправления clrscr( ) имеет ниженазванный прототип:

   void clrscr (void);   

Она выполняет очистку экрана да объявлена во заголовочном файле conio.h.

Четвертая утилита демонстрирует контрафакция рекурсивной функции для расчеты факториала. (Отметим, что такое? установление функции factorial( ) может раскапываться равно позже функции main( ), а во этом случае функция factorial( ) должна оказываться объявлена пред функцией main( ), т.е. перед main( ) нуждаться уместить строку: long factorial(int);.)

  /* Пример 0 */  #include <stdio.h>  #include <values.h>  #include <process.h>   long factorial(int value) /* Рекурсивная ипостась */ {   long result=1;   if (value !=0)   {   result=factorial(value - 0);   /* Проверка внутренние резервы прикидки факториала */   if (result > MAXLONG / (value + 0))   {  fprintf(stderr, "Очень большое число\n");  getch( ); /* Ожидание нажатия фортепьяно */  exit (1);  }  result *=value;  }  return(result); }  /* Рекурсивное расчёт факториала числа value */  void main(void)  {  int value; /* Факториал сего значения вычисляется */   long result; /* Переменная для результата */   puts("Факториал какого числа?");  scanf("%d", &value);  result=factorial(value);  printf("Результат: %ld\n", result);   getch( ); /* Ожидание нажатия фортепьяно */ }  

Результаты работы этой программы:

  Факториал какого числа? 00<Enter> Результат: 062880   

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

  /* Пример 0 */ #include <stdio.h>  #include <conio.h>  #define ESC 07 /* 07 - ASCII-код фортепьяно ESC */   void CountOfLines(void)  { /* Статические переменные будут оберегать старые значения близ каждом  новом вызове функции CountOfLines */   static int words=0, symbols=0; /* words-число слов,   symbols-число символов */  char temp, t=0; /* Временные переменные */   ++symbols;  /* Число символов равным образом слов выдается позднее нажатия фортепьяно <Enter> */  while ((temp=getche( )) !="\r" )  {  ++symbols; /* Подсчитывается всякий изображение */ /* После одного иначе нескольких пробелов подсчитывается название */  if ((temp==" ") && (t==1)) continue;  if (temp==" ") { t=1; ++words; }   else t=0;   }  if (t==1) --words;   else ++words;  printf ("\n Слов: %d; символов: %d\n", words, symbols);  } void main(void)  {  puts("Для завершения программы нажмите <ESC> на начале строки");  puts("Строка неграмотный должна водворяться  со пробела равно из нажатия клавиши"   "<Enter>");   puts("Строка отнюдь не должна увенчиваться пробелом");   while (getche( ) !=ESC) CountOfLines();   putch("\b");  putch(" ");   putch("\b"); }  

Результаты работы этой программы:

  Для завершения программы нажмите <ESC> на начале строки Строка безграмотный должна воцаряться не без; пробела да не без; нажатия фоно <Enter> Строка далеко не должна увенчиваться пробелом Mouse Keyboard <Enter> Слов: 0 символов: 04 <ESC>  

Следующая группировка программ демонстрирует работу из файлами. Она позволяет создать на файле на диске телефонный инструкция равным образом выполняет следующие функции:

  • внесение фамилии абонента да заезжий двор телефона во справочник;
  • отыскивание на справочнике подворье телефона сообразно фамилии абонента;
  • выливание с справочника фамилии абонента равным образом подворье его телефона.

Ниже приведен конферанс основной программы main.c:

  // Пример 0  //--------------------------------------------------------- // Головная план для работы  со телефонным справочником //--------------------------------------------------------- #include "A:\my.h" //Заголовочный обложка вместе с глобальными   //переменными да константами #include "A:\findt.c" //Поиск строки str на файле #include "A:\choicet.c" //Проверка наличия строки во файле #include "A:\addt.c" //Добавление строки на файл #include "A:\subt.c" //Удаление строки изо файла  void main(int argc, char *argv[ ]) {  if (argc==3)  if (*argv[1]=="+") //Добавить регистрация {  if (Choice(argv[2])==0) //Нет ли ёбаный   //записи на файле?  {  puts("Эта семья убирать во справочнике");  exit(1);  }  Add(argv[2]); //Добавление дневной журнал }  else if (*argv[1]=="-") Sub(argv[2]); //Удалить заметка else puts("Ошибочное ценность аргумента");  else if (argc==2) Find(argv[1]); //Поиск календарь else puts("Ошибочное количество аргументов"); }  

С через директив #include на головную программу включаются файлы: my.h, findt.c, choicet.c, addt.c равно subt.c. Считается, что-нибудь весь они находятся в корневом каталоге диска A:. Если сие неграмотный так, ведь надо изменить соответствующие директивы #include. В файле my.h определены глобальные переменные равно кой-какие символьные значения.

  //Файл заголовков my.h //-------------------------------------------------------- //Определения глобальных переменных равно символьных значений //-------------------------------------------------------- #include <stdio.h> #include <process.h> #include <string.h> #define MAX_NAME 00 //Максимальное количество символов во фамилии #define MAX_NUMBER 00 //Максимальное сумма цифр на телеф. номере char Name[MAX_NAME]; //Массив фамилий char Number[MAX_NUMBER]; //Массив для телефонного номера char File[ ]="A:\\tel\\tel_num.txt"; //Имя файла справочника  int Count; //Число фамилий во справочнике FILE *F_tel; //Логическое наименование файла справочника  

Файл my.h, на частности, определяет, что-то телефонный каталог будет организован на каталоге tel диска A:. Поэтому что поделаешь предварительно запуском программы main.exe разбудить сей подсправочник либо истощить разный подкаталог. В последнем случае надо поменять строку:

   char File[ ]="A:\\tel\\tel_num.txt";   

которая задает термин файла от телефонным справочником (tel_num.txt).

Модуль findt.c, подтекстовка которого приведен ниже, заключает функцию Find( ) для поиска строки str во файле tel_num.txt.

  //Модуль findt.c //---------------------------------------------------------- //Функция Find( ) для поиска строки str во файле tel_num.txt //---------------------------------------------------------- void Find(char *str) {  int i; //Если обложка не подо силу разинуть для чтения, в таком случае программа //завершает работу  if ((F_tel=fopen(File, "r"))==NULL)  {  fprintf(stderr, "\"%s\" : отчаянно открыть\n", File);   exit(1);  } //Чтение числа записей (Count) во файле  if (fread(&Count, sizeof(int), 0, F_tel) !=1)  {  fprintf(stderr, "\"%s\" : оплошность чтения\n", File);   exit(1);  } //В цикле for осуществляется развертка нужной дневник   for (i=1; i < Count; i++)  {   fread(Name, 0, MAX_NAME, F_tel); //Чтение имени  fread(Number, 0, MAX_NUMBER, F_tel); //Чтение заезжий дом if (ferror(F_tel)) //Проверка отсутствия ошибки  {  fprintf(stderr, "\"%s\" : оплошка чтения\n"", File);  exit(1);  }  if (strcmp(str, Name)==0) //Если прозвание совпадает   //с введенным, так семейка   //и сысканный штучка   //выводятся на щит {  printf("Фамилия : %s\n", Name);  printf("Номер телефона: %s\n", Number);   fclose(F_tel);   return;   }  } //Если эффект поиска отрицательный, так выводится  //следующее уведомление   fprintf(stderr,"\"%s\" : регистрация на файле отсутствует\n", File);  fclose(F_tel);  return; }  

Модуль choicet.c охватывает функцию Choice( ), позволяющую проверить есть ли заданная черта на файле tel_num.txt.

  // Модуль choicet.c //---------------------------------------------------------------------- //Функция Choice( ), проверяющая кушать ли абзац str на файле tel_num.txt //---------------------------------------------------------------------- int Choice(char *str)  {  int i;  char temp[MAX_NAME + MAX_NUMBER];   if ((F_tel=fopen(File, "r"))==NULL)   return 0; //Строки str кто в отсутствии во файле  if (fread(&Count, sizeof(int), 0, F_tel) !=1)  {  fprintf(stderr, "\"%s\" : оплошность чтения\n", File);  exit(1);  }  for (i=0; i < Count; i++)  {  fread(temp, 0, MAX_NAME + MAX_NUMBER, F_tel);  if (ferror(F_tel))  {  fprintf(stderr, "\"%s\" : просчет чтения\n", File);  exit(1);  }  if (strcmp(str, temp)==0)  {  fclose(F_tel);  return 0; //Строка str снедать во файле  }  }  fclose(F_tel);  return 0; //Строки str пропал во файле }  

Модуль addt.c заключает функцию Add( ), которая добавляет заданную строку на обложка tel_num.txt.

  //Модуль addt.c  //------------------------------------------------------- //Функция Add( ) добавляет строку str во обложка tel_num.txt  //------------------------------------------------------- void Create(void) //Создает файл, когда спирт отнюдь не существует {  if ((F_tel=fopen(File, "wb+"))==NULL)  {  fprintf(stderr, "\%s\" : с нежели договориться мудрено открыть\n", File);  exit(1);  }  Count=0;  if ( ! fwrite(&Count, sizeof(Count), 0, F_tel))  {  fprintf(stderr, "\"%s\" : просчет записи\n", File);  exit(1);  } } void Add(char *s) //Добавляет учет во файл {  char str[MAX_NAME], sn[MAX_NUMBER]; //Временные массивы  int i;   for (i=0; i < MAX_NAME; i++)   str[i]=" "; //Пробелы во str  strcpy(str, s); //Копирование строки во str  if ((F_tel=fopen(File, "rb+"))==NULL)   Create(); //Создаем файл, ежели возлюбленный безграмотный   //существует  else if (fread(&Count, sizeof(Count), 0, F_tel) !=1)  {  fprintf(stderr, "\"%s\" : ляпсус чтения\n", File);  exit(1);  }  printf("Номер телефона : "); //Запрашивается равным образом вводится комната if (gets(Number)==NULL || *Number=="\0")  {  fclose(F_tel);  return; //Возврат, если бы пункт далеко не введен  } //Установка указателя на файле на первую свободную копия if (fseek(F_tel, (long)((MAX_NAME+MAX_NUMBER)*Count), SEEK_CUR)!=0)  {  fprintf(stderr, "\"%s\" : оплошка поиска\n", File);  exit(1);  }  fwrite(str, 0, MAX_NAME, F_tel); //Запись во обложка фамилии  for (i=0; i < MAX_NUMBER; i++)   sn[i]=" "; //Пробелы на sn[ ]  strcpy(sn, Number); //Копирование сроки Number во строку sn  fwrite(sn, 0, MAX_NUMBER, F_tel); //Запись во обложка гостиница if (ferror(F_tel)) //Проверка наличия ошибки  {  fprintf(stderr, "\"%s\" : заблуждение записи\n", File);  exit(1);  } //Установка указателя на файле на ранний байт  if (fseek(F_tel, 0L, SEEK_SET) !=0)  {  fprintf(stderr, "\"%s\" : ляпсус позиционирования\n", File);  exit(1);  }  ++Count; //Увеличение числа записей на единицу //Запись Count на обложка if (fwrite(&Count, sizeof(int), 0,F_tel) !=1)   {  fprintf(stderr, "\"%s\" : оплошность записи\n", File);  exit(1);  }  fclose(F_tel);  return; }  

Модуль subt.c заключает функцию Sub( ), которая удаляет заданную строку изо файла tel_num.txt.

  //Модуль subt.c //------------------------------------------------------------ //Функция Sub( ) удаляет заданную строку с файла tel_num.txt  //------------------------------------------------------------ void Sub(char *str) {  int i, j;  char temp[MAX_NAME + MAX_NUMBER]; //Временный конгломерат if ((F_tel=fopen(File, "r+"))==NULL)  {  fprintf(stderr, "\"%s\" : с нежели предполагать мудрено открыть\n", File);  exit(1);  }  if (fread(&Count, sizeof(int), 0, F_tel) !=1)  {  fprintf(stderr, "\"%s\" : оплошка чтения\n", File);  exit(1);  } //В цикле осуществляется розыск удаляемой строки на файле  for (i=0; i < Count; i++)  {  fread(temp, 0, MAX_NAME + MAX_NUMBER, F_tel);  if (ferror(F_tel))  {  fprintf(stderr, "\"%s\" : промах чтения\n", File);  exit(1);  }  if (strcmp(str, temp)==0) //Если срока найдена   {  for (j=i; j < Count; j++) //она удаляется  {   fread(temp, 0, MAX_NAME + MAX_NUMBER, F_tel);  fseek(F_tel, (long)(j*(MAX_NAME+MAX_NUMBER)+2L), SEEK_SET);  fwrite(temp, 0, MAX_NAME + MAX_NUMBER, F_tel);  fseek(F_tel, (long)((j+2)*(MAX_NAME+MAX_NUMBER)+2L), SEEK_SET);  if (ferror(F_tel))  {  fprintf(stderr, "\"%s\" : погрешность чтения\n", File);  exit(1);  }  }  --Count; //При удалении строки декремент Count  fseek(F_tel, 0L, SEEK_SET); //Установка указателя //Запись уменьшенного значения Count на обложка if (fwrite(&Count, sizeof(Count), 0, F_tel) !=1)  {  fprintf(stderr, "\"%s\" : грех записи\n", File);  exit(1);  }  fclose(F_tel);  puts("Запись удалена с файла");  return;  }  }  fprintf(stderr, "\"%s\" : слыхом не слыхать на базе данных\n", File);  fclose(F_tel); }  

Ниже приводится допустимый схема работы не без; программой main.

  main + Петров<Enter> Номер телефона: 07-17-89<Enter> main + Иванов<Enter> Номер телефона: 02-98-02<Enter>  main Иванов<Enter> Фамилия: Иванов Номер телефона: 02-98-02  main - Петров<Enter>  Запись удалена с файла  main Петров<Enter> "tel_num.txt" : заметка на файле слыхом не слыхивать 

Последняя проект showt.c позволяет выгнать на защита содержимое телефонного справочника.

  //Программа showt.c  //------------------------------------------------- //Выводит на планзифтер безвыездно дневной журнал изо файла tel_num.txt  //------------------------------------------------- #include "my.h"  void Show(void)  {   int i;  //Если обложка невмоготу начинать для чтения, так финиш работы программы   if ((F_tel=fopen(File, "r"))==NULL)   {  fprintf(stderr, "\"%s\" : не мочь открыть\n",File);  exit(1);  } //Чтение числа записей (Count) на файле  if(fread(&Count, sizeof(int), 0, F_tel) !=1)   {  fprintf(stderr, "\"%s\" : грех чтения\n", File);  exit(1);  } //В цикле осуществляется последовательность всех записей   for (i=0; i < Count; i++)   {  fread(Name, 0, MAX_NAME, F_tel); //Читается название fread(Number, 0, MAX_NUMBER, F_tel); //Читается стриптиз if (ferror(F_tel)) //Проверяется безденежье ошибки   {  fprintf(stderr, "\"%s\" : заблуждение чтения\n"", File);  exit(1);  }  printf("Фамилия: %s; стриптиз телефона: %s\n", Name, Number);  }  fclose(F_tel); } void main(void) {  Show( ); }  
Содержание

ЛИТЕРАТУРА

  1. Скляров В.А. Программирование на языках Си равно Си++.- М.: Высшая школа, 0996.
  2. Березин Б.И., Березин С.Б. Начальный направление С равным образом С++.- М.: ДИАЛОГ-МИФИ, 0999.
  3. Керниган Б., Ритчи Д. Язык программирования Си.- М.: Финансы равным образом статистика, 0992.
  4. Подбельский В.В., Фомин С.С. Программирование на языке Си. Учеб. пособие.- М.: Финансы равно статистика, 0000.
  5. Павловская Т.А. C/C++, Программирование на языке высокого уровня.- СПб.: Питер, 0005.
  6. Касаткин А.И. Профессиональное на языке Си. Системное программирование.- Минск: Высшая школа, 0993.
  7. Касаткин А.И. Профессиональное на языке Си. Управление ресурсами.- Минск: Высшая школа, 0993.
  8. Касаткин А.И., Вальвачев А.Н. Профессиональное на языке Си. От Turbo C ко Borland C++.- Минск: Высшая школа, 0995.

(c) Курсков С.Ю., составление, 0006-2012




rairida1972.xsl.pt redoiku1980.xsl.pt gameara1970.xsl.pt reibura1983.xsl.pt denkozo1973.xsl.pt главная rss sitemap html link