Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: [решено] СРОЧНО... простые вопросы о языке СИ  (Прочитано 2992 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн $oft

  • Автор темы
  • Активист
  • *
  • Сообщений: 273
    • Просмотр профиля
Предистория:

Из другого ВУЗа меня попросили сделать их работу. Задание им задали три простых задачи написать на языке Си. Так как кроме меня никто не соображает в программировании. они попросили меня написать эти програмки... Я сам вообще пхп программист но совсем чутьчуть знаком с си/си++, питоном и еще парочкой совсем соовсем мало, ну думаю разберусь с гуглом и мануалами.... но увы уже сроки, а разобрался только с 1 задачей из 3х.

И так часть задачи:
нужно ввести числа Х1 Х2 ... Хn и каждое число чтобы стало элементом динамического массива.

вроде бы не трудно, для человека, знающего си.... но у меня проблема возникла:
я не знаю как элементы одной вводимой строки записать в разные индексы массива....  :'(

while((vvod = getchar()) != '\n')
{
   while (vvod != ' ')
   {
   nakop = vvod, nakop; \*это не работает, надо чтобы к символу vvod пристековался символ nakop ("1" + "6" = "16") *\
   ++i;
   }
... другие условия и запись в следующий свободный элемент массива1 или массива2 в соответствии с условиями.
}

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

Вот что должно получиться:
вводим числа через пробел (условно):
1 2 3 -4,1 1,1 0,9 0 0,5 8987980

arr1:
arr1[0] = 1;
arr1[1] = -4
arr1[2] = 0,9
arr1[3] = 0
arr1[4] = 0,5

arr2:
arr2[0] = 2;
arr2[1] = 3;
arr2[2] = 1,1;
arr2[3] = 8987980

если не трудно помогите... иначе завал(((((((((

ЗЫ.
компиляция под Windows, но думаю тут не важно особо. Так для информации... 1 программу скомпилировал в винде через программу dev-c++, собственно в ней и пишу.

все другие впросы по си из этих 3х предоставленных мне задач сюда буду спрашивать...

ЗАРАНЕЕ ВСЕМ СПАСИБО ЗА ПОМОЩЬ.
« Последнее редактирование: 03 Марта 2010, 23:20:39 от $oft »
Yii2/Laravel + JS/vue fullstack web developer
@evetrov telegram

Оффлайн Conso

  • Новичок
  • *
  • Сообщений: 29
    • Просмотр профиля
Re: СРОЧНО... простые вопросы о языке СИ
« Ответ #1 : 01 Марта 2010, 03:43:24 »
Цитировать
может подскажите как сделать присоединение одного символа к другому, что бы получилось число а не цифра
о.О
Пардон, а можно весь код посмотреть, может тогда понятней будет...
Beer. Teets. Metal.

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: СРОЧНО... простые вопросы о языке СИ
« Ответ #2 : 01 Марта 2010, 09:14:14 »
Думаю просто человеку надо бросить фигнёй срадать и уже осилить пару web-страницек посвященных программированию на Си/С++

Вот работающий примерчик. На самом деле тут много лишнего. Зато работает как сказано.
Под Linux компилируется g++ под Windows - vc
/*
 * File:   main.cpp
 * Author: yurik
 *
 * Created on 1 Март 2010 г., 12:31
 */

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <locale>

#ifdef linux
#include <locale.h>
#define LOCALE ""
#else
#define LOCALE "Russian_Russia.866"
#endif

int main() {
    #ifdef linux
    setlocale(LC_ALL, LOCALE);
    #endif
    std::wcout.imbue(std::locale(LOCALE));
    std::wcout << L"Введите числа через пробел в одну строку: " << std::endl;

std::wstring line;
    std::getline(std::wcin, line);
    if (line == L"")
        return 1;

    std::wstringstream iss(line);
    iss.imbue(std::locale(LOCALE));

    std::vector<double> array;
    while (!iss.eof()) {
        double n = 0;
        iss >> n;
        array.push_back(n);
    }

    std::wcout << L"Всего введено чисел: " << array.size() << std::endl;
    for (size_t i = 0; i < array.size(); ++i)
        std::wcout << array[i] << std::endl;
    return 0;
}

P.S. Dev-C++ использует компилятор MinGW (виндовая версия GCC) так что можно не пытаться компилить ею исходник.
« Последнее редактирование: 01 Марта 2010, 09:26:21 от Yurror »

Оффлайн $oft

  • Автор темы
  • Активист
  • *
  • Сообщений: 273
    • Просмотр профиля
Re: СРОЧНО... простые вопросы о языке СИ
« Ответ #3 : 01 Марта 2010, 10:05:18 »
Уважаемый Yurror, компилить придется в дев-с++ ибо нет времени с никсами разбираться в части Компиляции :(

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

Пользователь решил продолжить мысль 01 Марта 2010, 21:53:53:
Собственно вот программа, но она недописана:

#include <stdio.h>

using namespase std;
main()
{
float *arr1, *arr2, Z, vvod, nakop; /*vvod - вводимый символ getchar(), nakop - окончательно собранное число из всех getchar() */
int i1, i2, ind; /*i - номер элемента массива (индекс), ind - типа index (там по коду я пытался применить)*/

arr1 = (float*)malloc(100*sizeof(float));
arr2 = (float*)malloc(100*sizeof(float));
i1 = 0;
i2 = 0;

while ((vvod = getchar()) != '\n')
 {

 while (vvod != ' ')
  {
 [color=red] nakop = nakop, vvod; /* здесь хочу что бы следующий символ пристековывался к предыдущему: 1, 8 = 18*/[/color]
  }

 if (nakop <= 1)
  {
  arr1[i1] = nakop;
  ++i1
  }
 else
  {
  arr2[i2] = nakop;
  ++i2
  }
 }

/* ну тут для теста я выведу первые два-три индекса обоих массивов */
}

ну пока вот такой кусочек... нерешаемый.
как видно в один массив попадают значения больше единицы, в другой меньше или равные единице. Но это при условии что заработает код, формирующий каждое ЧИСЛО в отдельности (выделен красным)

что скажете?
« Последнее редактирование: 01 Марта 2010, 21:53:54 от $oft »
Yii2/Laravel + JS/vue fullstack web developer
@evetrov telegram

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Re: СРОЧНО... простые вопросы о языке СИ
« Ответ #4 : 02 Марта 2010, 06:42:46 »
Уважаемый Yurror, компилить придется в дев-с++ ибо нет времени с никсами разбираться в части Компиляции :(
...
что скажете?
Скажу, что вы ошиблись форумом =) Слегка. Здесь в основном компилят под Линукс. Ну с кем не бывает.
Скажу, что не стоило вам браться за работу которую не осилите.
Не надо было отбивать хлеб у толковыхх студентов кторые могут
такие задачки нерадивым двоешникам за сходную цену качественно и быстро сделать.

Скажу что проблемы у вас начиная со строчки using namespase std;
Скажу что main() это тоже не правильно
Скажу что float vvod вообще нифига не символьный тип чтобы в нем хранить результат getch()
Скажу что дальше еще смешнее =) просто бред.

Языки Си и С++ гораздо строже относятся к типизации чем php.
Хотя они и строже, но содержат автоматическое преобразование типов,
которое в данной программе играет с вами злейшую шутку =)

А еще вы не в состоянии корректно сформулировать ТЗ на разработку.

Собственно программа более чем недописана. Я бы даже сказал что это не программа, а случайный набор символов.
Дубль два: вы бы почитали что-нибудь по Си/С++ (только не в перемешку).

Выше лирика. К практике.

#include <stdio.h>
// OK, пусть будет язык Си
using namespase std; // это из языка С++, выкидываем.
//Странно что ошибку не выдало. наверное спасла организация заголовочников которые пишутся универсальными для Си/С++

// дальше надо написать
int main()
{
    return 0;
}
// и подумать как должна строиться программа.

Вопервых, надо со стандартного ввода считать числа с плавающей точкой и запомнить в динамическом массиве (как я понял из ТЗ).
для чтения чисел с плавающей точкой из стандартного ввода используется функция scanf("%f", &value), где "%f" это формат ввода, value - это переменная типа float и &value передаё адрес этой переменной в функцию scanf. Как читаются числа со стандартного ввода вроде бы разобрались.
(Если по ТЗ scanf использовать запрещено, то это отдельная тема и вы точно не успели сделать работу =) )

Во вторых, надо хранить числа в динамической памяти. Есть два решения.
а) сначала спрашивать сколько чисел пользователь хочет ввести и заранее выделять нужное количество памяти
б) не спрашивать а читать до конца ввода (конца файла) и выделять память по мере надобности.
Подпункт б несколько сложнее и вариантов реализации очень много. так что рассмотрим пункт (а) как стандарт для студенческих поделок.
Для управления выделением памяти используются функции malloc/free (есть еще куча ф-ций, но эти самые популярные, опять же для студенческих поделок). Память перед использованием выделяется и инициализируется (второе не обязательно, но студентам я рекомендую). После использования освобождается.

Итак действия программы во время работы
1) спросить пользователя сколько чисел хотим обрабатывать
2) прочитать нужное количество чисел
3) вывести нужное количество чисел

пример
/* для подключения функций malloc()/free() и макроопределений EXIT_SUCCESS/EXIT_FAILURE */
#include <stdlib.h>
/* для подключения функций scanf()/printf() */
#include <stdio.h>

int main()
{
    /* переменная "беззнаковое целое n" будет содержать количество обрабатываемых чисел */
    unsigned int n;
    /* переменная "беззнаковое целое i" будет счетчиком итераций (повторений цикла) */
    unsigned int i;
    /* переменная "указатель на дробное число" будет указывать на начало динамичкски выделеной памяти для n дробных чисел */
    float *array;

    /* обнулим n перед началом работы */
    n = 0;
    /* выводим на консоль приглашение пользователя к вводу */
    printf("Введите количество обрабатываемых чисел: ");
    /* считываем число с консоли */
    scanf("%d", &n);

    /* проверяем не обдурил ли нас пользователь */
    if (n == 0) {
        /* сообщаем что "ждедаи не пройдут" */
        printf("Ошибка: Пользователь, видимо не желает вводить числа
");
        /* выходим из программы с кодом завершения EXIT_FAILURE */
        return EXIT_FAILURE;
    }

    /* Иначе работа продолжается и мы просим ОС выделить нам кусочек памяти */
    /* Функция malloc() хочет чтобы ей передали размер требуемого блока в байтах */
    /* так как float занимает больше байта и его размер зависит от приходи копилятора */
    /* нам придётся расчитать нужное в данный момент количество байтов по формуле */
    /*  n*sizeof(float), где n - это количество чисел, а sizeof(float) - размер одного числа */
    /* Функция malloc() возвращает указатель на void а нам нужен указатель на float */
    /* поэтому между знаком = (присвоить) и именем функции мы даём копилятору подсказку */
    /* о том как надо обращаться с выделенным кусочком памяти */
    array = (float*)malloc(n*sizeof(float));
    /* Проверяем что нам действительно выделили запрашиваемый кусочек */
    if (array == NULL) {
        /* Если не выделили, тогда сообщаем об ошибке выделения памяти */
        printf("Ошибка: Программе не удалось выделить память для работы
");
        /* и выходим из программы с кодом завершения EXIT_FAILURE */
        return EXIT_FAILURE;
    }

    /* Иначе работы продолжается и мы в цикле вызываем функцию чтения */
    /* числа с плавающей точкой, передаевая ей каждый раз новую ячейку памяти */
    /* для сохранения в неё считанного числа */
    for (i = 0; i < n; ++i)
        scanf("%f", &array[i]);

    /* Для контроля корректности ввода распечатаем числа полученые от пользователя */
    /* Сначала выведем текстовое описание того что же выводит программа */
    printf("Введены числа: ");
    /* затем в цикле выведем числа обратно на консоль */
    /* для этого вызывается фунция печати и ей каждый раз передается новое число из памяти */
    for (i = 0; i < n; ++i)
        printf("%f ", array[i]);
    /* в конце строки печается переход на новую строку */
    printf("
");

    /* и освобождаем выделенную память */
    free(array);
    /* выходим из программы с кодом завержения EXIT_SUCCESS */
    return EXIT_SUCCESS;
}


Пользователь решил продолжить мысль 02 Марта 2010, 07:17:44:
Решение задачи без коментариев
#include <stdlib.h>
#include <stdio.h>

void push_back(float **array, unsigned int *index, float value) {
    unsigned int idx = *index;
    *index += 1;
    *array = (float *)realloc(*array, *index * sizeof(float));
    (*array)[idx] = value;
}

void print_array(float *array, unsigned int index) {
    unsigned int i;
    for (i = 0; i < index; ++i)
        printf("%f ", array[i]);
    printf("\n");
}

int main()
{
    unsigned int i1, i2;
    float *a1, *a2;

    i1 = 0;
    i2 = 0;
    a1 = NULL;
    a2 = NULL;

    while (!feof(stdin)) {
        float value;
        scanf("%f", &value);

        if (value <= 1)
            push_back(&a1, &i1, value);
        else
            push_back(&a2, &i2, value);
    }

    printf("A1: ");
    print_array(a1, i1);
    printf("A2: ");
    print_array(a2, i2);

    free(a1);
    free(a2);

    return EXIT_SUCCESS;
}

« Последнее редактирование: 02 Марта 2010, 07:17:44 от Yurror »

Оффлайн $oft

  • Автор темы
  • Активист
  • *
  • Сообщений: 273
    • Просмотр профиля
Re: СРОЧНО... простые вопросы о языке СИ
« Ответ #5 : 02 Марта 2010, 17:05:00 »
Цитировать
    while (!feof(stdin)) {
        float value;
        scanf("%f", &value);

спасибо огромное... вот этот кусок я искал... правда я что-то подобное сразу придумал, но почему то програмка висела около 10 секунд, а потом получался только 1 ввод, а не несколько... в общем я подумал, что что-то не то написал... теперь вижу что то, но каряво...

Еще раз СПАСИБО!.. не стоило так подробно комментировать, я и так почти всё сознательно воспринимаю, но зато хоть пояснения професионала увижу...

Вечером когда сяду за компилятор, попробую этот код..

ЗЫ
Работу у отличников я не отнимаю... ибо, как пояснили, я единственный человек среди знакомых шарящий в программировании... вобщем кроме меня некому.

Пользователь решил продолжить мысль 03 Марта 2010, 23:24:17:
так вобщем вчера (во вторник) на основании "кода помощи" со своими модификациями написал всё... хз прально или нет, но выполняет именно то что нужно и без сбоев, следовательно всё правильно написано...

особенное спасибо за функцию:

void push_back(float **array, unsigned int *index, float value) {
    unsigned int idx = *index;
    *index += 1;
    *array = (float *)realloc(*array, *index * sizeof(float));
    (*array)[idx] = value;
}

иначе я бы хз сколько искал как добавить именно динамически элемент...
« Последнее редактирование: 03 Марта 2010, 23:24:17 от $oft »
Yii2/Laravel + JS/vue fullstack web developer
@evetrov telegram

 

Страница сгенерирована за 0.064 секунд. Запросов: 25.