crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

4 страниц V   1 2 3 > »   
Ответить в данную темуНачать новую тему
> Начал изучать Си. Первые трудности.
micro-chipset
  опции профиля:
сообщение 29.1.2011, 10:54
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 27.1.2011
Пользователь №: 2371

Спасибо сказали: 0 раз(а)




Репутация:   0  


Возникла проблема со следующей задачей. Задача из из книги Б. Керниган, Д. Ритчи "Язык программирования Си" Глава 1.6 упражнение 1.13 Книгу онлайн можно найти тут

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


набросок программы

#include <stdio.h>

/*Программа вывода гистограммы длин слов во входном потоке*/

main ()
{
    int i, c, j;
    int length[15];
    
    j = 0;
    
    for (i = 0; i < 15; i++)
        length[i] = 0;
    while ((c = getchar()) != EOF)
        if (c != ' ' || c != '\t' || c != '\n'){
            ++j;
            ++length[c-j];
        }
    printf("Длинна слов =");
    for (i = 0; i < 15; i++)
        printf(" %d", length[i]);
}

Программа компилируется, но выдает не верные результаты. Наверное не верно заполняю массив, как поправить. Зарание спасибо за помощь.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 29.1.2011, 12:51
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2931
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


а почему именно C, а не C++ ? Или тебе для микроконтроллеров ?

Для начала - учимся основам:
1) форматирование кода (тут я лично мой варинт покажу, но он не самый плохой. Я даже уверен, что он хороший :) )
2) инициализация

с учётом вышесказанного, программа в стиле C будет выглядеть уже так
Раскрывающийся текст
#include <stdio.h>

/*Программа вывода гистограммы длин слов во входном потоке*/

main()
{
    //не лепи все объявления в одну строчку!
    //И не забывай про инициализацию
    int i=0;
    int c=0;
    int j=0;
    
    //константы надо именовать
    enum
    {
        arrlen=15,
    };
    
    int length[arrlen];
    //массив тоже полезно инитить
    memset(length,0,arrlen*sizeof(*length));
    
    j=0;
    
    while((c=getchar()) != EOF)
    {
        if(c!=' ' || c!='\t' || c!='\n')
        {
            j++;
            
            //полезно проверять выход за край, если это неочевидно
            if(c-j<arrlen)
            {
                length[c-j]++;
            }
        }
    }
    
    printf("Длина слов =");
    
    for(i=0; i<arrlen; i++)
    {
        printf(" %d", length[i]);
    }
}


Сообщение отредактировал Алексей1153 - 29.1.2011, 12:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
micro-chipset
  опции профиля:
сообщение 29.1.2011, 14:43
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 27.1.2011
Пользователь №: 2371

Спасибо сказали: 0 раз(а)




Репутация:   0  


1) С форматированием согласен еще не вошло в привычку придерживаться нормального стиля.

На данный код компилятор ругается:
Ошибки компилятора

gcc power.c -o power
power.c: В функции ‘main’:
power.c:21: предупреждение: несовместимая неявная декларация внутренней функции ‘memset’


enum
    {
        arrlen=15,
    };
    
    int length[arrlen];
    //массив тоже полезно инитить
    memset(length,0,arrlen*sizeof(*length));


Этот кусочек не совсем ясен. Особенно что такое enum и зачем так делается. И зачем инитить массив что это дает. У Керниган и Ритчи пока такого не встречал если можно поясните пожалуста. Хотелось бы понять.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 29.1.2011, 16:17
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2931
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(micro-chipset @ 29.1.2011, 16:43) *
На данный код компилятор ругается:


надо заголовочник добавить
<memory.h>

enum - это объявление константы типа int (причём, эта константа будет иметь область видимости, что очень хорошо)

arrlen*sizeof(*length)
- это выражение даст длину массива в байтах ( arrlen * длину_одного_элемента_массива)

(*length) - это разыменование указателя, так что sizeof этого выражения вернёт размер указуемого элемента

для статического массива можно было бы и просто sizeof(length) написать, но я не стал тебя путать и показал универсальный вариант для статических и для динамических массивов


Цитата(micro-chipset @ 29.1.2011, 16:43) *
И зачем инитить массив что это дает

инициализировать нужно абсолютно всё, иначе сюрпризы будут появляться в программах постоянно

Сообщение отредактировал Алексей1153 - 29.1.2011, 16:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 29.1.2011, 20:16
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Алексей1153 @ 29.1.2011, 18:17) *
причём, эта константа будет иметь область видимости
фразу-то не закончил. Какую область видимости будет иметь константа?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 29.1.2011, 20:22
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Алексей1153 @ 29.1.2011, 16:17) *
Цитата(micro-chipset @ 29.1.2011, 16:43) *
На данный код компилятор ругается:


надо заголовочник добавить
<memory.h>

enum - это объявление константы типа int (причём, эта константа будет иметь область видимости, что очень хорошо)

arrlen*sizeof(*length)
- это выражение даст длину массива в байтах ( arrlen * длину_одного_элемента_массива)

не понятно чему ты учишь, но в C нету memory.h, функция memset определёна в string.h/cstring.
по поводу arrlen*sizeof(*length), проще так:
memset(arr, 0, sizeof(arr));


Сообщение отредактировал DEADHUNT - 29.1.2011, 20:23
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rocky
  опции профиля:
сообщение 29.1.2011, 21:01
Сообщение #7


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


Кстати, а в ANSI C есть операторы "++" и "--" постфиксной и префиксной форм? (имеющие тот же смысл что и в С++)

Я просто помню помню фразу преподователя со 2-го курса института "Знаменитый оператор ++ языка С++....." которая предполагала, что все это было введено уже в С++.... А т.к. компилятора ANSI C у меня никогда не было =), я так и остался в неведении...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 29.1.2011, 21:09
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Rocky @ 29.1.2011, 21:01) *
Кстати, а в ANSI C есть операторы "++" и "--" постфиксной и префиксной форм? (имеющие тот же смысл что и в С++)

Есть.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rocky
  опции профиля:
сообщение 29.1.2011, 22:10
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


Буду знать, пасиб)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
micro-chipset
  опции профиля:
сообщение 30.1.2011, 10:55
Сообщение #10


Новичок


Группа: Новичок
Сообщений: 7
Регистрация: 27.1.2011
Пользователь №: 2371

Спасибо сказали: 0 раз(а)




Репутация:   0  


Программа компилируется и работает. Но выдает не верный результат. Проверяю так:
./1.13 < 1

то есть должна посчитать длинны слов в файле 1 в файле один содержится:
при привет в

А программа выдает:
Длина слов = 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0

А должно быть:
Длина слов = 0 1 0 1 0 0 1 0 0 0 0 0 1 0 0


Программа имеет вид:
Исходный код программы
#include <stdio.h>
#include <memory.h>

/*Программа вывода гистограммы длин слов во входном потоке*/

main()
{
    //не лепи все объявления в одну строчку!
    //И не забывай про инициализацию
    int i=0;
    int c=0;
    int j=0;
    
    //константы надо именовать
    enum
    {
        arrlen=15,
    };
    
    int length[arrlen];
    //массив тоже полезно инитить
    memset(length,0,arrlen*sizeof(*length));
    
    j=0;
    
    while((c=getchar()) != EOF)
    {
        if(c!=' ' || c!='\t' || c!='\n')
        {
            j++;
            
            //полезно проверять выход за край, если это неочевидно
            if(c-j<arrlen)
            {
                length[c-j]++;
            }
        }
    }
    
    printf("Длина слов =");
    
    for(i=0; i<arrlen; i++)
    {
        printf(" %d", length[i]);
    }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

4 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.6.2022, 17:20