Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
1

Выделить преобразование температур в отдельную функцию. (Керниган и Ритчи: Упражнение 1.15)

10.05.2016, 14:57. Показов 3018. Ответов 11

Author24 — интернет-сервис помощи студентам
Немного сцитирую:
Итак, мы имеем функцию power и главную функцию main, пользующуюся ее услугами, так что вся программа выглядит следующим образом:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 int power(int m, int n);  
/* тест функции power */ 
int main()
 {
     int i; 
    for (i = 0; i < 10; ++i)        
 printf("%d %d %d\n", i, power(2,i), power(-3, i)); 
    return 0;
 }  
/* возводит base в п-ю степень; n >= 0 */ 
int power(int base, int n) 
{
     int i, p;     p = 1;     for (i = 1; i <= n; ++i)     
    p = p * base;    
 return p;
 }
Определение любой функции имеет следующий вид:
тип-результата имя-функции (список параметров, если он есть)
{
объявления
инструкции
}

Вопросы:
1: Почему Первая часть программы не может отдельно работать от второй (или наоборот)? (ошибка на скриншоте)
2: Почему компилятор не ругается на то, что base не инициализирован (когда программа в исходном виде) и какой тогда должен получаться результат?
3: Почему в power 1 - стоит переменная m, если она нигде не используется?
4: Где здесь функция? Их 2 все-таки или это одно целое? (т.к. по отдельности работать не хочет)
5: Функция power подразумевает x^y (power (x,y) ), тогда почему p=p*base, если base это условно "х"? А вроде бы сказано, что base возводится в n-ую степень.
6: Одно из заданий в конце темы - Упражнение 1.15. Перепишите программу преобразования температур, выделив само преобразование в отдельную функцию.
Существует программа:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>  
#include <iostream>
/* печать таблицы температур по Фаренгейту и Цельсию для fahr = 0, 20, ..., 300 */
int main()
{
    int fahr, celsius;     int lower, upper, step;
    lower = 0; /* нижняя граница таблицы температур */     upper = 300; /* верхняя граница */     step = 20; /* шаг */
    fahr = lower;    
    setlocale(0, "");
    while (fahr <= upper)
    {
        celsius = 5 * (fahr - 32) / 9;         printf("%d\t%d\n Значение", fahr, celsius);         fahr = fahr + step; 
    }
}
Как это записать через функцию? Надеюсь это не сложно и вы поможете мне.

Заранее спасибо
Миниатюры
Выделить преобразование температур в отдельную функцию. (Керниган и Ритчи: Упражнение 1.15)   Выделить преобразование температур в отдельную функцию. (Керниган и Ритчи: Упражнение 1.15)  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.05.2016, 14:57
Ответы с готовыми решениями:

Керниган/Ритчи упражнение 1.20
&quot;Упражнение 1.20. Напишите программу detab, заменяющую символы табуляции во вводимом тексте нужным...

Керниган Ритчи Упражнение 2.2
Добрый день. Помогите начинающему разобраться пожалуйста. Само задание я решил, но...

Керниган/Ритчи упражнение 1.22
&quot;Упражнение 1.22. Напишите программу, печатающую символы входного потока так, чтобы строки текста...

Керниган, Ритчи, указатели и упражнение 5.3
Добрый день! &quot;Напишите свою версию функции strcat, ... с применением указателей.&quot; void...

11
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
10.05.2016, 15:44 2
Судя по всему, вы не дочитали раздел.
Цитата Сообщение от ixarek Посмотреть сообщение
1: Почему Первая часть программы не может отдельно работать от второй (или наоборот)? (ошибка на скриншоте)
Потому, что в вашем листинге есть две части:
-- объявление прототипа функции (строка 2)
-- реализация функции (строка 12 и ниже)
Говоря простым языком:
чтобы работало, нужно иметь и первое и второе. Если есть прототип, но нет реализации естесственно работать не будет
То есть. Вы вызываете функцию. Должно быть четко понятно, что она делает. У вас на скрине реализация отсутствует. Что делать неясно. Ошибка.
Цитата Сообщение от ixarek Посмотреть сообщение
2: Почему компилятор не ругается на то, что base не инициализирован (когда программа в исходном виде) и какой тогда должен получаться результат?
Потому, что это аргумент функции. Он получает значение в момент вызова функции.
Цитата Сообщение от ixarek Посмотреть сообщение
3: Почему в power 1 - стоит переменная m, если она нигде не используется?
В объявлении прототипа функции разрешается давать аргументам другие имена, чем в реализации. То есть по факту это тот же base.
Цитата Сообщение от ixarek Посмотреть сообщение
4: Где здесь функция? Их 2 все-таки или это одно целое? (т.к. по отдельности работать не хочет)
В данном коде их 3:
-- главная функция main
-- power
-- printf
Цитата Сообщение от ixarek Посмотреть сообщение
5: Функция power подразумевает x^y (power (x,y) ), тогда почему p=p*base, если base это условно "х"? А вроде бы сказано, что base возводится в n-ую степень.
Вы заметили, что там еще и цикл есть?

Восполните пробелы в знаниях, а потом дальше дерзайте.
1
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
10.05.2016, 16:17  [ТС] 3
1: Что тогда означает строка с 3 по 11?
2: (2: Почему компилятор не ругается на то, что base не инициализирован (когда программа в исходном виде) и какой тогда должен получаться результат?
Потому, что это аргумент функции. Он получает значение в момент вызова функции.) - какое же значение он тогда получает?
5: Цикл говорит - пока i не станет меньше n делать то то, но чему тогда равно n? Оно используется только в условии и не имеет начального значения? (Он получает значение в момент вызова функции.) - какое же значение он тогда получает?)

Вы уж извините, но не понимаю до сих пор
Миниатюры
Выделить преобразование температур в отдельную функцию. (Керниган и Ритчи: Упражнение 1.15)  
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
10.05.2016, 16:24 4
Цитата Сообщение от ixarek Посмотреть сообщение
1: Что тогда означает строка с 3 по 11?
Прочитайте, что вы написали:
Цитата Сообщение от ixarek Посмотреть сообщение
Определение любой функции имеет следующий вид:
тип-результата имя-функции (список параметров, если он есть)
{
объявления
инструкции
}
Теперь посмотрите на указанные вами строки. И подумайте.
Цитата Сообщение от ixarek Посмотреть сообщение
какое же значение он тогда получает?
Посмотрите, что у вас передано в месте вызова функции power.
Цитата Сообщение от ixarek Посмотреть сообщение
5: Цикл говорит - пока i не станет меньше n делать то то, но чему тогда равно n? Оно используется только в условии и не имеет начального значения? (Он получает значение в момент вызова функции.) - какое же значение он тогда получает?)
Аналогично.
0
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
10.05.2016, 16:39  [ТС] 5
Цитата Сообщение от HighPredator Посмотреть сообщение
Прочитайте, что вы написали:
Сообщение от ixarek
Определение любой функции имеет следующий вид:
тип-результата имя-функции (список параметров, если он есть)
{
объявления
инструкции
}
Хорошо, если это объявления и инструкции (что вроде бы понятно т.к. она так и должна действовать), то
Цитата Сообщение от HighPredator Посмотреть сообщение
Потому, что в вашем листинге есть две части:
-- объявление прототипа функции (строка 2)
-- реализация функции (строка 12 и ниже)
Говоря простым языком:
чтобы работало, нужно иметь и первое и второе. Если есть прототип, но нет реализации естесственно работать не будет
То есть. Вы вызываете функцию. Должно быть четко понятно, что она делает. У вас на скрине реализация отсутствует. Что делать неясно. Ошибка.
Первая часть - я вызвал функцию, там все вполне понятно что она делает (это получается прототип?), после идет (как вы говорите - реализация). Мне неясен смысл реализации. Одно перемножается на другое и что?
Цитата Сообщение от HighPredator Посмотреть сообщение
Посмотрите, что у вас передано в месте вызова функции power.
Получается Base =0? Вы имеете в ввиду, что передача в месте вызова функции это return 0;? Просто я только сейчас с ним столкнулся и не очень понимаю, что с этим делать.
Цитата Сообщение от HighPredator Посмотреть сообщение
5: Цикл говорит - пока i не станет меньше n делать то то, но чему тогда равно n? Оно используется только в условии и не имеет начального значения? (Он получает значение в момент вызова функции.) - какое же значение он тогда получает?)
Аналогично.
У меня в 6: - задание, если бы вы смогли бы решить это, то я лично бы посидел, поразбирал код, ибо чую, что вопросы будут нескончаемыми
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
10.05.2016, 16:49 6
Цитата Сообщение от ixarek Посмотреть сообщение
это получается прототип?
Прочтите еще раз мой пост выше и узрите, в какой строчке я вам показал прототип. Затем найдите в коде места вызова. Убедитесь, что это разные места.
Цитата Сообщение от ixarek Посмотреть сообщение
Мне неясен смысл реализации.
Реализация -- это конкретно то, что функция делает. А прототип -- это формальное ее описание вида:
тип-результата имя-функции (список параметров, если он есть)
Цитата Сообщение от ixarek Посмотреть сообщение
Получается Base =0?
Найдите место вызова функции power. Еще раз книгу почитайте если надо.
0
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
10.05.2016, 17:07  [ТС] 7
Прототип - получается это только строка №2

Имел ввиду не "что такое реализация функции" а как она тут представлена. То есть Перемножение первого на второе и это получается степень второго???.

Цитата Сообщение от HighPredator Посмотреть сообщение
Найдите место вызова функции power. Еще раз книгу почитайте если надо.
тут 2 места вызова функции power и мне тут ничего не говорит чему равен Base.
Собственно о книге. Там сосвсем немного написано, поэтому я даже сюда это выложу

Кликните здесь для просмотра всего текста
Функции в Си играют ту же роль, что и подпрограммы и функции в Фортране или процедуры и функции в Паскале. Функция обеспечивает удобный способ отдельно оформить некоторое вычисление и пользоваться им далее, не заботясь о том, как оно реализовано. После того, как функции написаны, можно забыть, как они сделаны, достаточно знать лишь, что они умеют делать. Механизм использования функции в Си удобен, легок и эффективен. Нередко вы будете встречать короткие функции, вызываемые лишь единожды; они оформлены в виде функции с одной-единственной целью — получить более ясную программу.
До сих пор мы пользовались готовыми функциями вроде main, getchar и putchar, теперь настала пора нам самим написать несколько функций. В Си нет оператора возведения в степень вроде ** в Фортране. Поэтому проиллюстрируем механизм определения функции на примере функции power(m, n), которая возводит целое m в целую положительную степень n. Так, power(2, 5) имеет значение 32. На самом деле для практического применения эта функция малопригодна, так как оперирует лишь малыми целыми степенями, однако она вполне может послужить иллюстрацией. (В стандартной библиотеке есть функция pow(x, у), вычисляющая ху.)
Итак, мы имеем функцию power и главную функцию main, пользующуюся ее услугами, так что вся программа выглядит следующим образом:
#include <stdio.h> int power(int m, int n);
/* тест функции power */ main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n", i, power(2,i), power(-3, i)); return 0; }
/* возводит base в п-ю степень; n >= 0 */ int power(int base, int n) { int i, p; P = 1; for (i = 1; i <= n; ++i) p = p * base; return p; }
Определение любой функции имеет следующий вид:
тип-результата имя-функции (список параметров, если он есть) { объявления инструкции }
Определения функций могут располагаться в любом порядке в одном или в нескольких исходных файлах, но любая функция должна быть целиком расположена в каком-то одном. Если исходный текст программы распределен по нескольким файлам, то, чтобы ее скомпилировать и загрузить, вам придется сказать несколько больше, чем при использовании одного файла; но это уже относится к операционной системе, а не к языку. Пока мы предполагаем, что обе функции находятся в одном файле, так что будет достаточно тех знаний, которые вы уже получили относительно запуска программ на Си.
В следующей строке из функции main к power обращаются дважды.
printf("%d %d %d\n", i, power(2,i), power(-3,1));
При каждом вызове функции power передаются два аргумента, и каждый раз главная программа main в ответ получает целое число, которое затем приводится к должному формату и печатается. Внутри выражения power(2,1) представляет собой целое значение точно так же, как 2 или i. (Не все функции в качестве результата выдают целые значения; подробно об этом будет сказано в главе 4.)
В первой строке определения power:
int power(int base, int n)
указываются типы параметров, имя функции и тип результата. Имена параметров локальны внутри power, это значит, что они скрыты для любой другой функции, так что остальные подпрограммы могут свободно пользоваться теми же именами для своих целей. Последнее утверждение справедливо также для переменных i и р: i в power и i в main не имеют между собой ничего общего.
Далее параметром мы будем называть переменную из списка параметров, заключенного в круглые скобки и заданного в определении функции, а аргументом — значение, используемое при обращении к функции. Иногда в том же смысле мы будем употреблять термины формальный аргумент и фактический аргумент.
Значение, вычисляемое функцией power, возвращается в main с помощью инструкции return. За словом return может следовать любое выражение:
return выражение;
Функция не обязательно возвращает какое-нибудь значение. Инструкция return без выражения только передает управление в ту программу, которая ее вызвала, не передавая ей никакого результирующего значения. То же самое происходит, если в процессе вычислений мы выходим на конец функции, обозначенный в тексте последней закрывающей фигурной скобкой. Возможна ситуация, когда вызывающая функция игнорирует возвращаемый ей результат.
Вы, вероятно, обратили внимание на инструкцию return в конце main. Поскольку main есть функция, как и любая другая, она может вернуть результирующее значение тому, кто ее вызвал, — фактически в ту среду, из которой была запущена программа. Обычно возвращается нулевое значение, что говорит о нормальном завершении выполнения. Ненулевое значение сигнализирует о необычном или ошибочном завершении. До сих пор ради простоты мы опускали return в main, но с этого момента будем задавать return как напоминание о том, что программы должны сообщать о состоянии своего завершения в операционную систему.
Объявление
int power(int m, int n);
стоящее непосредственно перед main, сообщает, что функция power ожидает двух аргументов типа int и возвращает результат типа int. Это объявление, называемое прототипом функции, должно быть
согласовано с определением и всеми вызовами power. Если определение функции или вызов не соответствует своему прототипу, это ошибка.
Имена параметров не требуют согласования. Фактически в прототипе они могут быть произвольными или вообще отсутствовать, т.е. прототип можно было бы записать и так:
int power(int, int);
Однако удачно подобранные имена поясняют программу, и мы будем часто этим пользоваться.
Историческая справка. Самые большие отличия ANSI-Си от более ранних версий языка как раз и заключаются в способах объявления и определения функций. В первой версии Си функцию power требовалось задавать в следующем виде:
/* power: возводит base в n-ю степень; n >= 0 */ /* (версия в старом стиле языка Си) */ power(base, n) int base, n; ( int i, p;
P = 1; for (i = 1; i <= n; ++i) p = p * base; return p; }
Здесь имена параметров перечислены в круглых скобках, а их типы заданы перед первой открывающей фигурной скобкой. В случае отсутствия указания о типе параметра, считается, что он имеет тип int. (Тело функции не претерпело изменений.)
Описание power в начале программы согласно первой версии Си должно было бы выглядеть следующим образом:
int power();
Нельзя было задавать список параметров, и поэтому компилятор не имел возможности проверить правильность обращений к power. Так как при отсутствии объявления power предполагалось, что функция возвращает значение типа int, то в данном случае объявление целиком можно было бы опустить.
Новый синтаксис для прототипов функций облегчает компилятору обнаружение ошибок в количестве аргументов и их типах. Старый синтаксис объявления и определения функции все еще допускается стандартом ANSI, по крайней мере, на переходный период, но если ваш компилятор поддерживает новый синтаксис, мы настоятельно рекомендуем пользоваться только им.
Упражнение 1.15. Перепишите программу преобразования температур, выделив само преобразование в отдельную функцию.
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
10.05.2016, 17:45 8
Цитата Сообщение от ixarek Посмотреть сообщение
ничего не говорит чему равен Base
Вы просто думать не хотите. Вот у вас место вызова.
C
1
printf("%d %d %d\n", i, power(2,i), power(-3, i));
Что передается в качестве аргументов? Двойка и i в первом вызове, минус три и i во втором вызове. Base какой параметр по порядку в описании? Первый. Так чему равно Base в каждом вызове?
0
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
10.05.2016, 18:02  [ТС] 9
Цитата Сообщение от HighPredator Посмотреть сообщение
Так чему равно Base в каждом вызове?
И чему он равен? 2 или -3? А при следующем цикле он опять примет одно из этих значений?
0
6045 / 2160 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
10.05.2016, 20:18 10
Цитата Сообщение от ixarek Посмотреть сообщение
или
Откуда или? Вы хоть смысл слова "или" знаете? Вот у вас вызов:
C
1
power(2,i)
чему равно Base
?
0
0 / 0 / 0
Регистрация: 06.05.2016
Сообщений: 8
10.05.2016, 23:40  [ТС] 11
Ну по идее 2м). Но тут же и -3 есть)
0
0 / 0 / 1
Регистрация: 21.09.2017
Сообщений: 5
12.10.2017, 06:28 12
Вот мой вариант, вроде бы работает:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
 
float celsfn (float m);
 
main () {
     float fahr, celsius;
     int step, upper, lower;
     
     lower = 0;
     upper = 300;
     step = 20;
     fahr = lower;
     printf ("Fahr\tCelsius\n");
     
     while (fahr <= upper) {
           printf ("%3.0f\t%6.2f\n", fahr, celsfn(fahr));
           fahr += step;
     }
     getch();
     return 0;
}
 
float celsfn (float fahr) {
      float celsius;
      
      celsius = (5.0/9.0) * (fahr - 32);
      return celsius;
}
0
12.10.2017, 06:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.10.2017, 06:28
Помогаю со студенческими работами здесь

Упражнение 1-22. Книга Керниган и Ритчи. Просьба помоч.
Всем привет. Я узучаю язык &quot;C&quot; около недели по книге &quot;Керниган и Ричи&quot;. И вот у меня появились...

Ритчи и Керниган
В этом учебники в некоторых примерах прототип функции объявляется внутри другой функции. Доля того,...

Керниган/ритчи задачи 1.18
Упражнение 1.18. Напишите программу, которая будет в каждой вводимой строке заменять стоящие подряд...

Указатели, Керниган и Ритчи 5.4
Здравствуйте, нужна помощь начинающему. Читаю Керниган и Ритчи и не могу понять следующую вещь:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru