Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
Shults99
Зарегистрирован: 15.01.2006 Сообщения: 6
|
Добавлено: Вс Янв 15 2006 10:49 Заголовок сообщения: printf |
|
|
Помогите, плз, решить задачу.
Почему в этом коде в ответ на printf("%d",na); турбо Си++ печатает 4935?
Код: | #include<stdio.h>
void main (void)
{
char s[1200];
int na, i, ne, ni, no, nu, ny, nae, nju, nja;
printf("Vvedite stroku:\n");
gets(s);
while (s[i] != '\0')
switch (s[i++])
{
case 'a':
na++;
break;
case 'e':
ne++;
break;
case 'и':
ni++;
break;
case 'о':
no++;
break;
case 'у':
nu++;
break;
case 'ы':
ny++;
break;
case 'э':
nae++;
break;
case 'ю':
nju++;
break;
case 'я':
nja++;
break;
default:
break;
}
printf("%d",na);
getch();
}
|
|
|
Вернуться к началу |
|
|
September
Зарегистрирован: 14.11.2004 Сообщения: 109 Откуда: Saint-Petersburg
|
Добавлено: Вс Янв 15 2006 11:00 Заголовок сообщения: |
|
|
Попробуйте инитнуть переменные n..
То есть
int na = 0...
Может поможет. |
|
Вернуться к началу |
|
|
GREA
Зарегистрирован: 14.05.2003 Сообщения: 758 Откуда: Новосибирск
|
Добавлено: Вс Янв 15 2006 11:13 Заголовок сообщения: |
|
|
Потому что это не паскаль и не Васик и начальные значения ВСЕГДА нужно явно задавать. |
|
Вернуться к началу |
|
|
Shults99
Зарегистрирован: 15.01.2006 Сообщения: 6
|
Добавлено: Вс Янв 15 2006 12:40 Заголовок сообщения: |
|
|
GREA писал(а): | Потому что это не паскаль и не Васик и начальные значения ВСЕГДА нужно явно задавать. |
Извините, господа - хрен поймешь
На Си можно программировать только тогда, когда его достаточно изучишь. |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вс Янв 15 2006 15:37 Заголовок сообщения: |
|
|
Shults99 писал(а): |
На Си можно программировать только тогда, когда его достаточно изучишь. |
В вашем случае это особенно актуально...
Кроме того, что вы не инициализируете переменные есть и еще один грешок. Вот вы тут считываете количество введенных определенных символов в строке. А теперь подумайте, какие изменения придется вносить при использовании еще одного символа, который нужно считывать?
попробуем переработать решение в стиле Си:
Код: |
#include <stdio.h>
#include <conio.h>
#define STR_SIZE 1200
/* Система ждет от вас что вы ей что-то скажите а вы ее так кидаете, что main возвращает void, эт конечно не ошибка, но... Этим можно пользоваться, например сделать аварийное завершение не функцией exit(1), а return 1;*/
int main(void)
{
/* индекс*/
int i;
/* s мнемонически непонятна и не несет никакой информации кроме типа переменной, впрочем в данном случае это не так важно, но нужно приучать себя, 1200 странная длина для строки ну да ладно*/
char str[STR_SIZE];
/* А теперь создадим массив переменных в котором будут считаться количества вхождения, что вам 1Кб памяти жалко, сколько ее у вас на компе?*/
int numOfInputChar[256];
for(i=0; i<256; i++)
{
numOfInputChar[i]=0;
}
/* инициализацция закончена*/
/* едем дальше, использование fprintf поможет отладить программу, если вы будете писать данные и брать их из файла, и никогда, НИКОГДА не пишите в строку формата строку со смыслом, вот это уже ошибка, которая может привести к очень песчальным последствиям*/
fprintf(stdout, "%s", "Vvedite stroku: \n");
/* Опять же воспользуемся аналогом, хоть и не полным fgets, но fgets позволяет ограничивать длину строки*/
fgets(str, STR_SIZE, stdin);
/* Цикл while здесь вовсе неуместен, вместо него надо использовать for, обратите внимание условие s[i]!='\0' не проверяется если не выполнено условие i<STR_SIZE*/
for(i=0; i<STR_SIZE?s[i]!='\0':0; i++)
numOfInputChar[s[i]]++;
fprintf(stdout, "%s%c%s%d", "Количество вхождение символа ", 'a',
": ", numOfCharInput['a']);
getch();
return 0;
} |
Это решение гораздо быстрее, а главное расширяемость его повышается. Конечно вы можете сказать, а если использовать Unicode. Тогда проблема решается с помощью ассоциативного массива, который правда придется реализовать, но НИКАК не switch.
И еще это решение в стиле Си. Не стоит использовать его в Си++ или Джава... |
|
Вернуться к началу |
|
|
Shults99
Зарегистрирован: 15.01.2006 Сообщения: 6
|
Добавлено: Вс Янв 15 2006 21:01 Заголовок сообщения: |
|
|
Намастэ, Kefir.
Вообще, невезуха у меня с Си.
Во-первых нет справки на русском в Турбо Си++ - так было в TP хорошо..
Во-вторых "актуально" в моем случае действительно, потому, что после Турбо Паскаля не вкурю никак.. Вроде бы столько возможностей, а вроде и ограничения откуда ни возьмись. Ну, да ладно.
/* Система ждет от вас что вы ей что-то скажите а вы ее так кидаете, что main возвращает void, эт конечно не ошибка, но... Этим можно пользоваться, например сделать аварийное завершение не функцией exit(1), а return 1;*/
Return записывает значение и выходит, как бы локально - т.е. не вообще из проги, а .. из цикла, например. Exit записывает значения и файлы и завершает прогу, если не ошибаюсь. В чем разница, если бы функция была пуста (void)?
Вот - пожалуйста, видим свободу в программировании, подобно свободе мышления. Можно записать просто main ( ), можно void main(void), а можно int main(void)!! Int, я думал, используется при инициализации переменных, а он в "обозначении" программы :о0
/* s мнемонически непонятна и не несет никакой информации кроме типа переменной, впрочем в данном случае это не так важно, но нужно приучать себя, 1200 странная длина для строки ну да ладно*/
1200 переправлял на 25.
Выше GREA говорит, что переменные нужно всегда явно задавать. ?
/*вам 1Кб памяти жалко, сколько ее у вас на компе?*/
У нефтяников крутые компы. Это по умолчанию. )
Код: | int numOfInputChar[256]; |
Что-то имена переменных интересные пошли. Вдруг что, я программлю на Турбо С++
Далее без комментов. Просто скажу, как бы мой препад (хорошо, что техникум дистанционный)
не нашел много для себя полезного в работах ученика.
Ты сам проверял программу в работе? Я некоторые недочеты поправил, а вот строка
Код: | fprintf(stdout, "%s%c%s%d", "Kolichestvo vhozhdenie simvola ", 'a',": ", numOfInputChar['a']); |
выдает ошибку в numOfInputChar - я не знаю, как исправить.
THANKS!
P.S. Что необходимо знать (базис) для успешного овладения С? |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вс Янв 15 2006 22:34 Заголовок сообщения: |
|
|
По программе, все работает если подправить имена переменных. Правда нет у меня Borland C 3.1. Там могут быть 2 проблемы: 1 - слишком длинное имя переменной, 2 - может не произойти автоматического преобразования символа 'a' в тип int. Для этого используем конструкцию
Код: | numOfInputChar[(int)'a'] |
А вообще, если что-то не работает принято выдавать полное сообщение об ошике.
О ключевом слове return. В Си есть функции и их много. Но самая первая которая вызывается это функция main, по идее ее вызывает система. Ну это так своими словами... Система ждет от программы кода возврата, как правило (хотя исключений я не видел) 0 означает что программа отработала корректно, все остальное - код ошибки... Так вот точно так же как из любой функции можно выйти вернув какое-то значение с помощью return, так же и из программы можно выйти вызвав в main return с кодом возврата. exit как правило используется для аварийного завершения...
Я не инициализаровал строку, а зачем если вы ее вводите... Сутьв том, что в отличие от некоторых языков в которых все пременные по умолчанию равны 0, в Си это не определено...
Что касается имен переменных. Я сам с этим сталкивался. Многие преподы еще из тех времен, когда длина переменной ограничивалась 8 символами. По моему до сих пор в стандарте ANSI C. Значимыми символами в имени переменной являются первые 31. Дело в том что такое ограничение на длину переменной резко упрощает и ускоряте компиляторы. Но это уже прошлый век. Пролемы скорости компиляции практически отсутствуют.
Программы чаще читаются чем пишутся. Поэтому текст программы должен быть максимально понятным большинству программистов. Вы конечно можете написать короткое имя переменной и поянить его в комментарии, но в этом случае вы ограничите круг читающих носителями вашего языка. Комментарии нужны и очень, но чем больше код несет информации для программиста тем лучьше...
Что нужно знать:
А вам нужно Си или Си++?
Если вы уже попрограммировали, то купите наконец какую-нибудь книжку, только пожалуйста не антикварную версию Кернигана и Ричи. Мне вот очень нравятся труды Шилда (или Шилдта). Только смотрите, чтобы это была книжка по Си или Си++, а не по конкретной среде разработки...
Я думаю, что и без всяких советов вы с легкостью освоите синтаксис языка, вот в этом месте важно понимать, что синтаксисом язык не заканчивается. Внимательно следите за тем, что является хорошим тоном программирования, а что нет... Например использование goto, switch, лесенки if..else if..else if..else, слишком длинные функции и т.д. - все это является признаками плохого проектирования. Я не исключаю, что их использование может быть оправдано, но честно говоря никогда не видел... Если у вас в программе появилась подобная конструкция, надо задуматься и рассмотреть другие варианты реализации. |
|
Вернуться к началу |
|
|
Shults99
Зарегистрирован: 15.01.2006 Сообщения: 6
|
Добавлено: Вс Янв 15 2006 23:14 Заголовок сообщения: |
|
|
Вывод можно сделать такой: чтобы хорошо подтягиваться, нужно... подтягиваться. В моем случае это надо делать много. Спасибо ещё раз за ответы. Я покопаюсь и, если захочу, разберусь. |
|
Вернуться к началу |
|
|
kocherman
Зарегистрирован: 06.01.2006 Сообщения: 88 Откуда: Обнинск
|
Добавлено: Вт Янв 17 2006 01:24 Заголовок сообщения: |
|
|
Ребята... что вы тут спорите?? отладчиком кто учил работать? от хорошей жизни результаты выводятся плохие?
дык... что не получается не по твоей вине... нада смотреть настройки компилятора... может там стоит tiny-сегментирование... или стеку присвоено 256 байт...
и второй НЮ... если ты используешь printf(), почему ты не пользуешься scanf()? |
|
Вернуться к началу |
|
|
Kefir
Зарегистрирован: 16.04.2005 Сообщения: 443 Откуда: Пермь
|
Добавлено: Вт Янв 17 2006 09:09 Заголовок сообщения: |
|
|
scanf считывает строку до 1го пробела или символа табуляции или еще чего нибудь... Он правильно использует gets... |
|
Вернуться к началу |
|
|
|