Главная > Уроки > Арифметические действия в языке Си

Записывайся на этот курс на Stepike!

Арифметические действия в языке Си

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

Компилятор языка Си понимает все основные арифметические операции, которые вам известны со школы. Плюс есть несколько дополнительных.

Основные арифметические операторы языка Си.

+ оператор сложения
- оператор вычитания
* оператор умножения
% оператор взятия остатка от деления
/ оператор деления

Следующая программа иллюстрирует использование первых четырёх из них. Кстати, обратите внимание на то, как с помощью функции printf вывести на экран символ %.

Листинг 1.

#include <stdio.h>
int main(void){
  int a=7, b=2;
  int res;

  res = a+b;
  printf("%d + %d = %d\n",a,b,res);
  res = a-b;
  printf("%d - %d = %d\n",a,b,res);
  res = a*b;
  printf("%d * %d = %d\n",a,b,res);
  res = a%b;
  printf("%d %% %d = %d\n",a,b,res);
  
  return 0;
}

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

 Использование арифметических действий в Си

Рис.5 Использование арифметических действий в Си.

Всё чётко и понятно. Никаких неожиданностей. А теперь попробуем получить частное двух чисел. Т.к. результат должен получиться 3.5, то res объявим как float.

Листинг 2.

#include <stdio.h>
int main(void){
  int a=7, b=2;
  float res;

  res = a/b;
  printf("%d / %d = %f\n",a,b,res);

  return 0;
}

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

Целочисленное деление.

При делении значение целого типа на значение целого типа результат тоже получается целого типа.

Так уж устроен язык Си. Поэкспериментируйте, попробуйте любые другие целые числа.

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

Пример: Как получить результат целочисленного деления

7/2 = 3.5 → 3
11/3 = 3.66 → 3
2/5 = 0.4 → 0

Для того чтобы получить тот результат, который мы в данном случае ожидаем, одно из значений нужно сделать вещественным. Сделать это проще простого. Для этого необходимо рядом с ним в скобках записать float.

Посмотрим на нашем примере:

Листинг 3.

#include <stdio.h>
int main(void){
  int a=7, b=2;
  float res;

  res = (float)a/b;
  printf("%d / %d = %f\n",a,b,res);

  return 0;
}

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

Явное преобразование (приведение) типа.

Если какое-то значение нужно привести к другому типу, нужно перед этим значением в скобках написать название требуемого типа.

Листинг 4. Примеры явного преобразования типа

int a=7, b;
float g= 9.81,v;

b = (int) g; //приводим значение 9.81 к типу int, получим 9
v= (float)a; // приводим значение 7 к типу float, получим 7.0

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

Обратите внимание, что, когда мы преобразовываем целое значение в вещественное, ничего особенного не происходит, т.к. вещественные числа включают в себя целые.

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

Картинка, показывающая различия между операциями взятие остатка, целочисленного деления и обычного деления.

Деление, целочисленное деление и остаток от деления. Отличия

Рис.2 Деление, целочисленное деление и остаток от деления.

Сохрани в закладки или поддержи проект.

Практика

Решите предложенные задачи:

Для удобства работы сразу переходите в полноэкранный режим

Исследовательские задачи для хакеров

  1. Подумайте и приведите примеры, когда обычное деление не имеет смысла. Например, деление трёх лицензионных ключей от программы между двумя людьми. Зачем кому-то нужна половина лицензионного ключа? (если, конечно, он не занимается reverse engineering).
  2. Что происходит при делении на ноль в вашей системе?

Дополнительные материалы

  1. Дополнительные задачи с автоматической проверкой решения из курса " Введение в программирование (C++) " от компании Яндекс. не беспокойтесь, что курс по С++. Удаляйте заготовку из поля для решения и спокойно вставляйте код на Си. Проверяющая система его будет нормально воспринимать.

Оставить комментарий

Чтобы код красиво отображался на странице заключайте его в теги [code] здесь писать код [/code]

Комментарии

Andrey Kakurin
Добрый день! Не могу решить эту задачу, пытался ввести число как 3 разных переменных, но тогда оно записывается в столбик, ни как не могу придумать алгоритм сам, а пользоваться чужими не хочу, дайте пожалуйста подсказку=)
KaDeaT

Всегда пожалуйста!
Если я правильно понимаю, то речь идёт о задаче в Шаге 6. Мои подсказки будут следующие.

  • Стандартной функции для этой операции нет. )
  • Вам нужно получить отдельные разряды числа. Заведите, например, для каждого разряда (сотни, десятки и единицы) отдельную переменную.
  • Вам потребуются операции остаток от деления и деление нацело. Вычислите, например, результаты следующих выражений 123%10 и 123/100. Подумайте как их можно использовать, чтобы получить отдельный разряды числа.

Удачи!

Coolmen
почему не принимает?
#include <stdio.h>

int main() {
int dog,d1,d2,d3,summa;
dog = 123;
d1 = dog / 100;
d2 = dog / 60;
d3 = dog / 40;
summa = d1 + d2 + d3;
printf("%d",summa);

return 0;
}
KaDeaT
Поясните, пожалуйста, а что вы хотите сделать? И где у вас не принимает?
Ильяс Татарский
Вот, вроде же, правильно (эт я про шестую задачу) считает.
#include <stdio.h>

int main() {
int dog,d1, d2, d3, d4;
dog = 123;
d1=123%10;
d2=123%100/10;
d3=123/100;
d4 = d1+d2+d3;
printf("%dn", d4);
return 0;
}
KaDeaT
Эта программа работает только для одного конкретного числа 123, а нужно написать так, чтобы работало для любого трёхзначного числа.
Евгений
#include <stdio.h>
int main(void){
int a=12, b=25;
float res;

res = a*2+b*2;
printf("%.0fn",a,b,res);

return 0;
}

почему пишет что ответ у меня не правильный ответ должен быть 74 и у меня такой ответ выводит 74
KaDeaT
Не совсем понял вопрос, но вот, например, в выводе printf у вас один спецификатор, а вывести вы хотите 3 переменных.
не_робот_я
В задаче с Гиллом Байтсом мы обнуляем переменную float pi = 0; - зачем это нужно?
KaDeaT
Это правила хорошего стиля. Т.к. изначально во всех переменных лежит мусор.
Anton
Доп. задачки хороши, особенно последняя.
Jurij
Здравствуйте.
Всё получается как у Вас в примерах. Но есть одно маленькое "НО". В примере деления 7 на 2 у меня у меня в консоли показывает не 3,5 - а 3,500000. Как убрать лишние нули? Или это фича консоли?
KaDeaT
Вам нужно изменить формат вывода. Посмотрите, как это сделать, в 3 уроке курса: http://youngcoder.ru/lessons/3/formatnyi_vyvod_printf.php
Доброжелатель
Это гениально, давать задание с условием if, когда мы его ещё не прошли...Я сидел пол часа и думал, как это всё можно сделать без if...А оказалось с ним и надо было...
KaDeaT
Нет, так не оказалось.

Все задачи этого урока можно решить средствами, которые разобраны в уроке. Конструкцию if-else использовать не требуется. =)
KaDeaT
Вам нужно изменить формат вывода. Посмотрите, как это сделать, в 3 уроке курса: http://youngcoder.ru/lessons/3/formatnyi_vyvod_printf.php
Андрей Муравьев
Добрый день)
Подскажите, пожалуйста.. Явное присвоение типа возможно только при полной записи выражения? При сокращенной не смог.. ((
Например:
[ case '+': (float)a+=b; printf("%.2f",a); break;]
KaDeaT
Нельзя использовать приведение типа в левой части оператора присваивания. Поэтому не работает.
Evgeny


int main(void) {
int a=12, b=25, res=a+a+b+b;
printf("%d",res);// put your code here
return 0;
}

пишет ошибку, чт не так?
KaDeaT
Какую именно ошибку?
Роман
Для тех, кто жестко затупил (как я на пару часов) поясняю: нужно использовать scanf и вводить число в форму, которая ниже кода.
Константин
Как можно определить четность без условных операторов?
Решение только одно, это определение остатка после деления на 2, если нацело, то четное, с остатком - нечетное. Как еще можно?
KaDeaT
Например, можно посмотреть на самый младший бит (самый правый) в двоичном представлении числа.

2 -- 10
3 -- 11
7 -- 111
73 -- 1001001
255 -- 11111111
256 -- 100000000
Алексей
Доброго времени суток!

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

Теперь к вопросу по задаче про периметр.
Написал код (ниже), запустил программу, в графе "Test output", как и положено, получил ответ 74... Но программа не принимает ответ: "Failed test #2 of 10. Wrong answer".
Подскажите, пожалуйста, на что ругается?

 #include <stdio.h>

int main(void) {
int dlina=25, shirina=12, res;
res=dlina*2+shirina*2;
printf("%dn",res);
return 0;
}


С уважением, Алексей
valeriy bezhevets
Задача 48

вроде бы правильно срабатывает,
но решение не принятно
не понимаю почему
#include <stdio.h>

int main()
{
int a, b;
float c;
scanf("%d%d%f", &a, &b, &c);
printf("%.2fn", (b - a) * c);
return 0;
}
uranchik
Подскажите, пожалуйста, почему не принимает код?
#include <stdio.h>

int main() {
float nach, kon;
float pr;
scanf("%f %f %f", &nach, &kon, &pr);

float schet;
schet = pr*(kon - nach);



printf("%.2f", schet);

return 0;
}
Щур Владимир
Доброго времени суток!
Подскажите пожалуйста, почему не принимает мой код:
#include <stdio.h>
int main(void) {
int nac_mes, kon_mes;
float stoimost, oplata;
scanf("%i", &nac_mes);
scanf("%i", &kon_mes);
scanf("%f", &stoimost);
oplata = (kon_mes - nac_mes) * stoimost;
printf("%.2f", oplata);
return 0;
}

Oleg
добрый день, не могу решить задачу. ошибка - неправильный ответ.
[#include <stdio.h>
int main(void)
{

float a, b, c, res;

scanf ("%f", &a);
scanf ("%f", &b);
scanf ("%f", &c);
res = (b - a) * c;
printf("%.2f", res);
return 0;
}]
Obelix
#include <stdio.h>

int main() {
int a,b;
float c,d;
scanf("%d",&a);
scanf("%d",&b);
scanf("%f",&c);
d = (b - a) * c;
printf("%.2f", d);
return 0;
}

Ожидаемый ответ 40.00,
Полученный ответ 40.00,
Ошибка: неправильный ответ.
Чо?
Владимир
Добрый день!
При решении данной задачи выдается ошибка "Failed test #2 of 11. Wrong answer", хотя решение выходит правильно. Сумма любых трехзначных чисел считается правильно. Объясните что не так?
#include <stdio.h>

int main() {
int a=123;
printf("%dn",a/100+(a%100)/10+a%10);
return 0;
}

Екатерина
Задание 46, выдает ошибку
Failed test #2 of 10. Wrong answer

#include <stdio.h>

int main() {
int a=12,b=25,c;
c=2*a+2*b;
printf("%d",c);
return 0;
}

пробовала и float в c

int a=12,b=25;
float c;
c=2*a+2*b;
printf("%.0f",c);


ответ 74 в обоих случаях, программа не принимает