LINUX.ORG.RU

Начал изучение С, есть вопросы.


0

2

Начал изучать Си. Книга «Харви Дейтел. Пол Дейтел. Как программировать на С». Там на 128 странице есть задание. «Разработайте программу на Си для ввода пройденного расстояния в километрах и объема каждой заправки в литрах. Программа должна вычислять и отображать на экране количество пройденных километров на литр для каждой заправки авто. После обработки всей входной информации программа должна вычислить и вывести общее количество пройденных километров на литр по всем заправкам.»
.. Введите расход бензина (-1, если ввод закончен): 12.8
..Введите пройденный путь: 287
Для этой заправки получено километр/литр 22.42
.. Введите расход бензина (-1, если ввод закончен): 10.3
..Введите пройденный путь: 200
Для этой заправки получено километр/литр 22.42
.. Введите расход бензина (-1, если ввод закончен): 5
..Введите пройденный путь: 120
Для этой заправки получено километр/литр 22.42
.. Введите расход бензина (-1, если ввод закончен): -1
Среднее число километров/литр 21.60
Я не прошу что бы за меня решали задачу.
Вот мой код, буду благодарен за дельные советы, прошу конструктивной критики.

#include <stdio.h>

int main()

{
float srednee, rashod, s, kmlitr, summa;
int a;
a = 0;
rashod = 0;
while (rashod != -1)
  {
	printf("Введите расход бензина (-1 если ввод закончен):");
	scanf("%f", &rashod);
	printf("Введите пройденный путь:");
	scanf("%f", &s);
	kmlitr = s / rashod;
	printf("kmlitr %.2f\n", kmlitr);
		if (rashod > 0)
			summa += kmlitr;
		if (rashod > 0) a++;
	srednee = summa / a;
  }

printf("Средний расход бензина %.2f", srednee);
return 0;
}
Может задачу и можно решить по-другому, но я только в начале прочтения книги. Что конкретно у меня не получается:
1. Если ввести -1, то все равно выводится вопрос о пройденном пути, и только потом заканчивает считаться среднее.
2. Знаю что задача не сложна сама по себе, но в книге до этой задачи не давались примеры хоть сколько похожие.
3. Что может посоветуете от себя (книги, сайты, может есть у кого целые задания - желательно с решением - НО заглядывать не буду пока не решу саму задачу). Это здорово помогло бы мне продвинуться.
З.Ы: Учусь программировать в Линуксе (Agiliya 8), я в 10 классе.

1) Забыл проверку на -1 сразу после ввода;
2) Керниган, Ритчи - Язык программирования C;
3) Структура и Интерпритация компьютерных программ, глава 1, подглава 1;
4) Город какой?
5) Если есть у кого книга «Программирование на языке C» за авторством Стефана Кочана - возьми почитать. Мне лично понравилось начало. А больше тебе и не надо пока.

TheKnight ★★★
()

1. Первый scanf вынеси за начало цикла. Еще надо аккуратно будет обработать этот вариант, чтобы при расчете среднего прога не делила на ноль.

3. Книжку Кернигана и Ритчи «Язык программировнаия си» (2ое издание). Это учебник, написанный авторами языка, must read:)

yura_ts ★★
()

Agiliya 8

в 10 классе.

DoctorSinus, смешные у вашего дистра пользователи.

Арч теперь не модный, а Агилия. Посоны одобряют :3

А по теме : Читай Кернигана и Ритчи. :)

thelonelyisland ★★★
()

> linux.org.ru
> прошу конструктивной критики.

мдя :)

0. форматирование — ужс…

0.5. учи английский.

1. подумай и ответь, где и как должна происходить проверка на вводимое значение.

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

3. тебе тоже Богатырева посоветовать? ;)

arsi ★★★★★
()

У тебя проблемы не с C, а с основами построения алгоритмов.
К сожалению книжек не посоветую.

trex6 ★★★★★
()

Керниган и ричи - «Язык программирования Си». Там все подробно разобрано.

2. Знаю что задача не сложна сама по себе, но в книге до этой задачи не давались примеры хоть сколько похожие.

Решать нужно те задачи, которые до этого не решал.

Ты случайно бейсик не изучал?

Deleted
()

По коду:

1. Если ввести -1, то все равно выводится вопрос о пройденном пути, и только потом заканчивает считаться среднее.

Замени

while (rashod != -1)
на вечный цикл
 for(;;)
, и добавь после введения расхода проверку на -1
         if (consum == -1)
            break;

Deleted
()
Ответ на: комментарий от TheKnight

> Ты про Богатырёв А. «Руководство полного идиота по программированию (на языке Си)»?

точно. только я обычно сюда линк даю.

> Кому кстати уже успел посоветовать?

т.к. первый раз мне эта книга попалась на глаза примерно 8 лет назад, вспомнить всех, кому её советовал, будет проблематично :)

arsi ★★★★★
()
Ответ на: комментарий от thelonelyisland

DoctorSinus, смешные у вашего дистра пользователи.


Что за дурацкое отношение к людям, основанное на их возрасте? ТС не кидает дефолтные скрины в галерею, не вбрасывает в толксах, он просит помощи в самообразовании. А вы сразу какашками.

Dragon59 ★★
()

Что за идиотская привычка делать подобные программы интерактивными?

anonymous
()
Ответ на: комментарий от anonymous

Что за идиотская привычка делать подобные программы интерактивными?

Люто плюсую. Все учебники содержат такие нелепости, вместо того чтобы давать реальные примеры.

geekless ★★
()
Ответ на: комментарий от thelonelyisland

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

novichek01
() автор топика
Ответ на: комментарий от Deleted

Совсем чуть-чуть паскаль (в школе программирование в 11 классе, 2 семестр, но это еще не скоро), и то будет тоже паскаль.

novichek01
() автор топика
Ответ на: комментарий от anonymous

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

novichek01
() автор топика
Ответ на: комментарий от Deleted

for(;;)

, и добавь после введения расхода проверку на -1

if (consum == -1) break; глянул на перед, там идет изучение for, но на данный момент я изучил только до своего момента, и полученных знаний не хватает что бы решить поставленную задачу правильно и красиво. Но я подумал если авторы книги дали задачу и показали как делать похожие, то проблем быть не должно, но видимо что то я не дочитал, или надо почитать те книги что мне советуют (тогда будет толк).

novichek01
() автор топика
Ответ на: комментарий от thelonelyisland

Это уже другой вопрос. Я, например, не делаю ошибок только потому, что в слове Arch трудно сделать ошибку.

CYB3R ★★★★★
()
Ответ на: комментарий от CYB3R

В написании-то да. А уж как его только не называли при мне. И арк, и арх, и арщ)

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

все равно как зацикливаться.

Или что, проблема в наличии break? Ну без этого циклы как-то неполноценно были бы даны, поэтому можно смело использовать, даже если ты «забежишь наперед» - лучше сразу писать правильно, чем костыли городить. А то привычка выработается.

cdshines ★★★★★
()
Ответ на: комментарий от novichek01

Бесконечный цикл можно также и while(1) было сделать, но в K&R используется for(;;). Советую K&R, это лучшее, с чего можно изучать Си.

Deleted
()
Ответ на: комментарий от geekless

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

CYB3R ★★★★★
()
Ответ на: комментарий от geekless

Как по мне, так while(1) читается гораздо лучше, чем ктулху-смайлик for(;;).

Никогда не замечал О_о.

Тем более нужно использовать for(;;), ибо символизирует Ктулху!

Deleted
()
Ответ на: комментарий от thelonelyisland

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

ggrn ★★★★★
()
Ответ на: комментарий от thelonelyisland

мне бы было лень ставить лялих(1), искать учебник(2),пытаться писать код(3),региться на форуму что бы задать вопрос(4) ради вые...на перед однаклассниками.

а если и так, то не дадут 100%

ggrn ★★★★★
()
Ответ на: комментарий от thelonelyisland

Я слышал что с возрастом приходит мудрость, а мне кажется что ко многим возраст приходит один. Установил Линукс не для того тчо бы сказать что я какой то ботаник (кстати не ботаник, довольно таки ленив). Начал изучать для себя, да у меня есть в этом проблемы, буду их решать когда будет время (стараюсь уделять то время какое получается). Спасибо всем кто помогает советами, буду читать дальше и решать задачи дальше.

novichek01
() автор топика
Ответ на: комментарий от novichek01

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

Обновления без необходимости - плохо.

Deleted
()
#include <stdio.h>

int main()

{
float srednee, rashod, s, kmlitr, summa;
int a;
a = 0;
rashod = 0;
while (rashod != -1)/*floating point comparison  with integer? Might not always work! */
  {
	printf("Введите расход бензина (-1 если ввод закончен):");
	scanf("%f", &rashod);
        /* check end of input here!*/
	printf("Введите пройденный путь:");
	scanf("%f", &s);
	kmlitr = s / rashod; /* if  0.0 == rashod, crash! And what about -0.5?*/
	printf("kmlitr %.2f\n", kmlitr);
		if (rashod > 0)/* Why? If it is 0, program crashes*/
                                        /* if it is < 0 then the previous line outputs nonsense */
			summa += kmlitr;
		if (rashod > 0) a++; /*better ++a. Why two if? Use one if for block*/
	srednee = summa / a; /* this is better outside the loop*/
  }

printf("Средний расход бензина %.2f", srednee);
return 0;
}
anonymous
()
Ответ на: комментарий от ggrn

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

кстати, почему арч у многих так ассоциируется со школьниками? я знаю всего одного школьника на арче.

wasd
()
Ответ на: комментарий от anonymous

while (rashod != -1)

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

uint8_t * pReg = (uint8_t *) 0x1234;
// Wait for register to become non-zero
while (*pReg == 0) { } // Do something else
В этом случае, почти наверняка будет сбой, как только вы включите оптимизацию. Компилятор сгенерирует ассемблерный код подобный этому:
mov ptr, #0x1234
mov a, @ptr
loop:
bz loop
Логическое обоснование оптимизатора довольно простое: уже считав значение переменной в аккумулятор (вторую строка кода), нет необходимости считывать его заново, поскольку значение всегда будет тем же. Таким образом, в третьей строке мы окажемся в бесконечном цикле. Чтобы заставить компилятор сделать то, что нам нужно, мы изменим описание на:
uint8_t volatile * pReg = (uint8_t volatile *) 0x1234;
Ассемблерный код теперь выглядит следующим образом:
mov ptr, #0x1234
loop:
mov a, @ptr
bz loop
Требуемый ход процесса достигнут.



Мне кажется, или тут именно такая ситуация?

wasd
()
Ответ на: комментарий от Dragon59

Приплюсую. А то так отобьют мотивацию у чувака.

Deleted
()
Ответ на: комментарий от wasd

Мне кажется, или тут именно такая ситуация?

Кажется.

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

anonymous
()

1. Замени на do-while цикл.
3. Книжка Кернигана и Риччи.

Переменные лучше так не называть - лучше ангийские аналоги. Например вместо srednee пиши mean, summa -> sum, rashod -> consumption какой-нибудь, да и вообще учи английский, пригодится и не раз. Float используй только для opengl, в остальных случаях используй double. «Защита от дурака» отсутствует. Что будет если в rashod напишут 0? Зачем так писать:

if (rashod > 0)
   summa += kmlitr;
if (rashod > 0) a++;
? Можно всё в один операторный блок объеденить.
if (rashod > 0) {
   summa += kmlitr;
   a++;
}
Короче читай книжек больше и разных. Потом берись программировать. Да ещё и на С.

nanoolinux ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.