Язык Си в примерах/Учимся складывать: различия между версиями

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
Использовано «:» для выделения пояснений (был: пробел → <pre />.)
м Замена <tt /> на <code />; избыточные <big /> и <font /> вокруг <source />; {{SUBPAGENAME}}; пробелы.
Строка 1: Строка 1:
{{Содержание «Язык Си в примерах»}}
{{Содержание «Язык Си в примерах»}}


Разнообразные вычисления &mdash;
Разнообразные вычисления &mdash;
моделирование, решение алгебраических и дифференциальных уравнений &mdash;
моделирование, решение алгебраических и дифференциальных уравнений &mdash;
это то, для чего и создавались первые компьютеры.
это то, для чего и создавались первые компьютеры.
Строка 7: Строка 7:
Начнём со сложения двух чисел.
Начнём со сложения двух чисел.


В нашей программе будут две целочисленные переменные: <tt>а</tt> и <tt>b</tt>. Это
В нашей программе будут две целочисленные переменные: <code>а</code> и <code>b</code>. Это
две ячейки памяти, в которых могут храниться целые числа из определенного диапазона значений
две ячейки памяти, в которых могут храниться целые числа из определенного диапазона значений
(в [[w:Машинное слово|32-разрядной архитектуре]] от <math>-2^{31}</math> до <math>2^{31}-1</math>).
(в [[w:Машинное слово|32-разрядной архитектуре]] от <math>-2^{31}</math> до <math>2^{31}-1</math>).


Переменные объявляются в начале тела функции <tt>main</tt> &mdash; после открывающей фигурной скобки.
Переменные объявляются в начале тела функции <code>main</code> &mdash; после открывающей фигурной скобки.
Объявление начинается со слова, обозначающего тип переменных, имена которых перечисляются через запятую
Объявление начинается со слова, обозначающего тип переменных, имена которых перечисляются через запятую
после обозначения типа.
после обозначения типа.
<big><source lang="c">
<source lang="c">
int a, b;
int a, b;
</source></big>
</source>


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


К первой группе относятся:
К первой группе относятся:
* <tt>char</tt> — один байт, обычно 8 бит.
* <code>char</code> — один байт, обычно 8 бит.
* <tt>short</tt> — короткое число, чаще всего в 2 раза короче, чем int.
* <code>short</code> — короткое число, чаще всего в 2 раза короче, чем int.
* <tt>int</tt> — обычное число, на x86 32 бита.
* <code>int</code> — обычное число, на x86 32 бита.
* <tt>long</tt> — длинное число, на x86 32 бита, но на 64-битных x86-системах в зависимости от компилятора может быть как 32 бита, так и 64.
* <code>long</code> — длинное число, на x86 32 бита, но на 64-битных x86-системах в зависимости от компилятора может быть как 32 бита, так и 64.
* <tt>long long</tt> — очень длинное число, обычно 64 бита.
* <code>long long</code> — очень длинное число, обычно 64 бита.


Целые числа могут быть знаковые (как положительные, так и отрицательные) и беззнаковые (только положительные). По умолчанию числа знаковые, и чтобы сделать их беззнаковыми, необходимо написать слово <tt>unsigned</tt> перед названием типа.
Целые числа могут быть знаковые (как положительные, так и отрицательные) и беззнаковые (только положительные). По умолчанию числа знаковые, и чтобы сделать их беззнаковыми, необходимо написать слово <code>unsigned</code> перед названием типа.


Точный размер целых чисел указан в заголовочном файле <tt>limits</tt>.
Точный размер целых чисел указан в заголовочном файле <code>limits</code>.


Ко второй группе относятся:
Ко второй группе относятся:
* <tt>float</tt> — 32 бита.
* <code>float</code> — 32 бита.
* <tt>double</tt> — 64 бита.
* <code>double</code> — 64 бита.


Особые величины этих типов даны в заголовке <tt>float</tt>.
Особые величины этих типов даны в заголовке <code>float</code>.


Вот текст программы, складывающей два введенных целых числа:
Вот текст программы, складывающей два введенных целых числа:
<big><source lang="c">
<source lang="c">
#include <stdio.h>
#include <stdio.h>
int main () {
int main () {
Строка 47: Строка 47:
return 0;
return 0;
}
}
</source></big>
</source>


Функция <tt>scanf</tt>, также как и <tt>printf</tt>, определена в библиотеке <tt>stdio</tt>.
Функция <code>scanf</code>, также как и <code>printf</code>, определена в библиотеке <code>stdio</code>.
Эта функция считывает данные, которые пользователь (тот, кто
Эта функция считывает данные, которые пользователь (тот, кто
запустит вашу программу) вводит с клавиатуры. Слово <tt>scan</tt>
запустит вашу программу) вводит с клавиатуры. Слово <code>scan</code>
означает «считывать данные», а <tt>print</tt> &mdash; «печатать данные».
означает «считывать данные», а <code>print</code> &mdash; «печатать данные».
Буква «f» в конце соответствует первой букве английского слова
Буква «f» в конце соответствует первой букве английского слова
«formatted», то есть <tt>scanf</tt> и <tt>printf</tt> есть функции для
«formatted», то есть <code>scanf</code> и <code>printf</code> есть функции для
форматированного ввода и вывода данных.
форматированного ввода и вывода данных.


Первый аргумент у функции <tt>scanf</tt> &mdash; это <tt>"%d%d"</tt> (то, что стоит между открывающей скобкой и первой запятой).
Первый аргумент у функции <code>scanf</code> &mdash; это <code>"%d%d"</code> (то, что стоит между открывающей скобкой и первой запятой).
Первый аргумент является описанием формата входных данных, то есть описание типа данных, которые (как мы ожидаем) введёт пользователь.
Первый аргумент является описанием формата входных данных, то есть описание типа данных, которые (как мы ожидаем) введёт пользователь.
Второй и третий аргументы являются указателями (создаются символом «&amp;») на переменные <tt>a</tt> и <tt>b</tt>. Указатели нужны для того, чтобы передать функции не значения этих переменных, а их адреса — местоположения в памяти, по которым функция будет записывать значения.
Второй и третий аргументы являются указателями (создаются символом «&amp;») на переменные <code>a</code> и <code>b</code>. Указатели нужны для того, чтобы передать функции не значения этих переменных, а их адреса — местоположения в памяти, по которым функция будет записывать значения.
В этой программе мы ожидаем, что пользователь введет два целых числа.
В этой программе мы ожидаем, что пользователь введет два целых числа.


Строка 65: Строка 65:
Обычно, после него идет один или два символа, определяющих тип входных данных. Формат "%d" соответствует целому числу в десятичной системе счисления (decimal integer). Если вы напишете "%x", то функция будет ожидать ввода целого числа, записанного в шестнадцатиричной системе счисления.
Обычно, после него идет один или два символа, определяющих тип входных данных. Формат "%d" соответствует целому числу в десятичной системе счисления (decimal integer). Если вы напишете "%x", то функция будет ожидать ввода целого числа, записанного в шестнадцатиричной системе счисления.


Подробнее об спецификациях форматах ввода/вывода можно прочитать в документации (для Unix систем):
Подробнее об спецификациях форматах ввода/вывода можно прочитать в документации (для Unix систем):


bash$ man 3 printf
bash$ man 3 printf
bash$ man 3 scanf
bash$ man 3 scanf


Первый аргумент команды <tt>man</tt> есть номер раздела документации.
Первый аргумент команды <code>man</code> есть номер раздела документации.
Помощь по языкам Си/Си++ находится в третьем разделе.
Помощь по языкам Си/Си++ находится в третьем разделе.


Строка 82: Строка 82:
Причём, программа выводит результаты вычислений два раза &mdash; сначала
Причём, программа выводит результаты вычислений два раза &mdash; сначала
в обычном виде, а потом со специальным форматированием.
в обычном виде, а потом со специальным форматированием.
Формат <tt>"%10.3lf"</tt> соответствует выводу числа типа <tt>double</tt>,
Формат <code>"%10.3lf"</code> соответствует выводу числа типа <code>double</code>,
при котором под запись числа выделяется ровно 10 позиций (если это возможно),
при котором под запись числа выделяется ровно 10 позиций (если это возможно),
а после запятой пишется ровно три знака. Равнение происходит по правому краю.
а после запятой пишется ровно три знака. Равнение происходит по правому краю.


<big><source lang="c">
<source lang="c">
/* Программа "Арифметические операции с числами с плавающей точкой" */
/* Программа "Арифметические операции с числами с плавающей точкой" */
#include <stdio.h>
#include <stdio.h>
Строка 99: Строка 99:
return 0;
return 0;
}
}
</source></big>
</source>


В этой программе мы встречаемся с оператором <tt>while</tt>. Конструкция
В этой программе мы встречаемся с оператором <code>while</code>. Конструкция
<big><source lang="c">
<source lang="c">
while ( A ) B;
while ( A ) B;
</source></big>
</source>


означает буквально следующее:
означает буквально следующее:


: Пока выполнено условие <tt>A</tt> делать <tt>B</tt>.
: Пока выполнено условие <code>A</code> делать <code>B</code>.


или, другими словами,
или, другими словами,


: Выполнять в цикле <tt>B</tt>, проверяя перед каждой итерацией, что выполнено условие <tt>A</tt>.
: Выполнять в цикле <code>B</code>, проверяя перед каждой итерацией, что выполнено условие <code>A</code>.


В нашем случае <tt>A</tt> есть
В нашем случае <code>A</code> есть


scanf("%lf%lf", &a, &b) == 2.
scanf("%lf%lf", &a, &b) == 2.
Строка 125: Строка 125:
арифметических операций, пока пользователь не введёт что-нибудь непохожее на число.
арифметических операций, пока пользователь не введёт что-нибудь непохожее на число.


Цикл <tt>while</tt> закончится тогда, когда функция <tt>scanf</tt> не сможет успешно считать два числа.
Цикл <code>while</code> закончится тогда, когда функция <code>scanf</code> не сможет успешно считать два числа.


Заметьте, что после каждой команды стоит точка с запятой.
Заметьте, что после каждой команды стоит точка с запятой.
Строка 132: Строка 132:
==Примечания==
==Примечания==


# {{note|char}} Переменные типа <tt>char</tt>, <tt>short</tt>, <tt>int</tt> можно печатать, используя формат "%d". Также этот формат можно использовать для печати значений [[Язык Си в примерах/Указатели в языке Си|указателей]] (номера ячейки памяти).
# {{note|char}} Переменные типа <code>char</code>, <code>short</code>, <code>int</code> можно печатать, используя формат "%d". Также этот формат можно использовать для печати значений [[Язык Си в примерах/Указатели в языке Си|указателей]] (номера ячейки памяти).
[[Категория:Язык Си в примерах|Учимся складывать]]
[[Категория:Язык Си в примерах|{{SUBPAGENAME}}]]

Версия от 21:56, 29 января 2014

Язык Си в примерах


  1. Компиляция программ
  2. Простейшая программа «Hello World»
  3. Учимся складывать
  4. Максимум
  5. Таблица умножения
  6. ASCII-коды символов
  7. Верхний регистр
  8. Скобочки
  9. Факториал
  10. Степень числа
  11. Треугольник Паскаля
  12. Корень уравнения
  13. Система счисления
  14. Сортировка
  15. Библиотека complex
  16. Сортировка на основе qsort
  17. RPN-калькулятор
  18. RPN-калькулятор на Bison
  19. Простая грамматика
  20. Задача «Расчёт сопротивления схемы»
  21. Простая реализация конечного автомата
  22. Использование аргументов командной строки
  23. Чтение и печать без использования stdio
  24. Декодирование звукозаписи в формате ADX
  25. Другие примеры

Разнообразные вычисления — моделирование, решение алгебраических и дифференциальных уравнений — это то, для чего и создавались первые компьютеры. Давайте и мы научимся использовать компьютер для вычислений. Начнём со сложения двух чисел.

В нашей программе будут две целочисленные переменные: а и b. Это две ячейки памяти, в которых могут храниться целые числа из определенного диапазона значений (в 32-разрядной архитектуре от до ).

Переменные объявляются в начале тела функции main — после открывающей фигурной скобки. Объявление начинается со слова, обозначающего тип переменных, имена которых перечисляются через запятую после обозначения типа.

 int a, b;

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

К первой группе относятся:

  • char — один байт, обычно 8 бит.
  • short — короткое число, чаще всего в 2 раза короче, чем int.
  • int — обычное число, на x86 32 бита.
  • long — длинное число, на x86 32 бита, но на 64-битных x86-системах в зависимости от компилятора может быть как 32 бита, так и 64.
  • long long — очень длинное число, обычно 64 бита.

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

Точный размер целых чисел указан в заголовочном файле limits.

Ко второй группе относятся:

  • float — 32 бита.
  • double — 64 бита.

Особые величины этих типов даны в заголовке float.

Вот текст программы, складывающей два введенных целых числа:

 #include <stdio.h>
 int main () {
     int a, b;
     printf ("Введите два числа: \n");
     scanf ("%d%d", &a, &b);
     printf ("%d\n", a + b);
     return 0;
 }

Функция scanf, также как и printf, определена в библиотеке stdio. Эта функция считывает данные, которые пользователь (тот, кто запустит вашу программу) вводит с клавиатуры. Слово scan означает «считывать данные», а print — «печатать данные». Буква «f» в конце соответствует первой букве английского слова «formatted», то есть scanf и printf есть функции для форматированного ввода и вывода данных.

Первый аргумент у функции scanf — это "%d%d" (то, что стоит между открывающей скобкой и первой запятой). Первый аргумент является описанием формата входных данных, то есть описание типа данных, которые (как мы ожидаем) введёт пользователь. Второй и третий аргументы являются указателями (создаются символом «&») на переменные a и b. Указатели нужны для того, чтобы передать функции не значения этих переменных, а их адреса — местоположения в памяти, по которым функция будет записывать значения. В этой программе мы ожидаем, что пользователь введет два целых числа.

Символ % служебный, с него начинается описание формата. Обычно, после него идет один или два символа, определяющих тип входных данных. Формат "%d" соответствует целому числу в десятичной системе счисления (decimal integer). Если вы напишете "%x", то функция будет ожидать ввода целого числа, записанного в шестнадцатиричной системе счисления.

Подробнее об спецификациях форматах ввода/вывода можно прочитать в документации (для Unix систем):

bash$ man 3 printf
bash$ man 3 scanf

Первый аргумент команды man есть номер раздела документации. Помощь по языкам Си/Си++ находится в третьем разделе.

Следует отметить, что для каждого типа данных существует несколько форматов, и наоборот, для разных типов можно использовать один и тот же формат[1].

Приведенная программа умеет складывать только целые числа. Если вы хотите складывать действительные числа, то эту программу нужно несколько модифицировать. Ниже приведена программа, которая считывает два действительных числа и выводит результат четырех арифметических операций: сложения, вычитания, умножения и деления. Причём, программа выводит результаты вычислений два раза — сначала в обычном виде, а потом со специальным форматированием. Формат "%10.3lf" соответствует выводу числа типа double, при котором под запись числа выделяется ровно 10 позиций (если это возможно), а после запятой пишется ровно три знака. Равнение происходит по правому краю.

 /* Программа "Арифметические операции с числами с плавающей точкой" */
 #include <stdio.h>
 int main () {
    double a, b;
    printf ("Введите два числа: ");
    while(scanf ("%lf%lf", &a, &b) == 2 ) {
        printf ("%lf %lf %lf %lf\n", a + b, a - b, a * b, a / b );
        printf ("a + b=%10.3lf\n a - b=%10.3lf\n a * b=%10.3lf\n a / b=%10.3lf\n",
                  a + b, a - b, a * b, a / b );
    }
    return 0;
 }

В этой программе мы встречаемся с оператором while. Конструкция

 while ( A ) B;

означает буквально следующее:

Пока выполнено условие A делать B.

или, другими словами,

Выполнять в цикле B, проверяя перед каждой итерацией, что выполнено условие A.

В нашем случае A есть

scanf("%lf%lf", &a, &b) == 2.

Что соответствует логическому выражению:

пользователь ввёл два действительных числа, и они удачно считаны в переменные a и b.

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

Цикл while закончится тогда, когда функция scanf не сможет успешно считать два числа.

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

Примечания

  1. ^  Переменные типа char, short, int можно печатать, используя формат "%d". Также этот формат можно использовать для печати значений указателей (номера ячейки памяти).