|
1 | 1 | ## Дополнительные материалы |
2 | 2 |
|
3 | | -1. пока нет |
| 3 | +1\. Представьте: вы написали программу «sum2». Вы знаете, как она работает, потому что сами её создали. Но когда программу запустит другой человек, он увидит просто пустой экран и мигающий курсор. Что делать дальше? Что вводить? |
| 4 | + |
| 5 | +Одним из вариантов решения этой проблемы -- подсказать пользователю, что от него требуется. Давайте посмотрим на пример: |
| 6 | + |
| 7 | +Следующая программа считает количество каллорий, расходуемое на базовый обмен веществ по формуле Миффлина-Сан Жеора. Для расчета нужны: возраст, рост и вес. |
| 8 | + |
| 9 | +Листинг 10. Программа рассчёта базового обмена веществ (BMR, basal metabolic rate) |
| 10 | +```c |
| 11 | +#include <stdio.h> |
| 12 | + |
| 13 | +int main(void) |
| 14 | +{ |
| 15 | + int age, height, weight; |
| 16 | + double bmr_male, bov_female; |
| 17 | + |
| 18 | + printf("Enter your age (in years, integer number):\n"); |
| 19 | + scanf("%d", &age); // считываем целое значение в переменную age |
| 20 | + |
| 21 | + printf("Enter your height (in centimeters, integer number):\n"); |
| 22 | + scanf("%d", &height); // считываем значение в переменную height |
| 23 | + |
| 24 | + printf("Enter your weight (in kilograms, integer number):\n"); |
| 25 | + scanf("%d", &weight); // считываем значение в переменную weight |
| 26 | + |
| 27 | + bmr_male = 10*weight + 6.25*height - 5*age + 5; |
| 28 | + bmr_female = 10*weight + 6.25*height - 5*age - 161; |
| 29 | + |
| 30 | + printf("| BMR |\n"); |
| 31 | + printf("| male | female |\n"); |
| 32 | + printf("|%8.2f|%8.2f|\n", bmr_male, bmr_female); |
| 33 | + |
| 34 | + return 0; |
| 35 | +} |
| 36 | +``` |
| 37 | +
|
| 38 | +
|
| 39 | +2\. В уроке сказано, что при передаче переменных в функцию `scanf` необходимо перед именем переменной добавлять значок `&`. Но почему? Зачем это нужно? Всё дело в том, как в языке Си устроена передача аргументов в функцию. |
| 40 | +
|
| 41 | +Когда вы передаете переменную в функцию, происходит следующее: |
| 42 | +1. В памяти компьютера для этой переменной выделяется новое место; |
| 43 | +2. Значение переменной копируется в это место; |
| 44 | +3. Функция работает только с этой копией. |
| 45 | +
|
| 46 | +Это называется =передача по значению (pass by value)=. |
| 47 | +
|
| 48 | +Вернёмся к нашей любимой аналогии с коробками. Представьте, что у вас есть коробка с важным числом (переменная). Когда вы вызываете функцию, вы не отдаете ей свою коробку, а делаете временную копию и отдаете её. Что бы функция ни делала с этой копией, ваша оригинальная коробка в безопасности. |
| 49 | +
|
| 50 | +Но функция `scanf` -- это особый случай. Эта функция должна **записать** новое значение в вашу переменную. Копия тут не прокатит -- нужен доступ к оригиналу. Поэтому мы используем `&`. В этом случае функция получает не какую-то там жалкую копию, а информацию о том, где в памяти находится наша переменная, а потому может записать в неё введенное пользователем значение. |
| 51 | +
|
| 52 | +Логика в этом примерно следующая. Мы относимся к любым функциям как к потенциально опасным объектам, которые могут повредить данные. Поэтому по умолчанию функции получают только копии данных -- это защищает от случайных изменений. А чтобы позволить функции работать с оригинальными данными, мы должно совершить сознательное действие -- передать адрес переменной. |
| 53 | +
|
| 54 | +Мы ещё подробнее обсудим этот механизм, когда будем изучать, как можно создавать собственные функции. |
| 55 | +
|
| 56 | +
|
| 57 | +
|
| 58 | +3\. У функции `printf` есть специальный спецификатор `%p`, который используется, чтобы вывести адрес на экран. |
| 59 | +
|
| 60 | +```c |
| 61 | +#include <stdio.h> |
| 62 | +
|
| 63 | +int main(void) |
| 64 | +{ |
| 65 | + int x = 10; |
| 66 | +
|
| 67 | + printf("value x:\t %d\n", x); // выводим значение переменной |
| 68 | + printf("address:\t %p\n", &x); // выводим адрес переменной в памяти |
| 69 | + |
| 70 | + return 0; |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +Более того, для хранения адреса можно использовать специальный тип переменных, который называется =указателями=. Ближе к концу курса мы познакомимся поближе с этим понятием. |
| 75 | + |
| 76 | + |
| 77 | +4\. В некоторых случаях функция `scanf` может вернуть отрицательное число (обычно `-1`). Это происходит в случаях, когда произошла ошибка чтения потока (например, в потоке не оказалось данных) или был достигнут конец файла (например, если поток был связан с каким-то текстовым файлом). |
0 commit comments