C общего программирования

Массив - это объект-контейнер, который содержит фиксированное число значений одного типа.

blockquote>

См. http://docs.oracle.com/javase /tutorial/java/nutsandbolts/arrays.html

13
задан Andrei Ciobanu 2 October 2010 в 22:15
поделиться

7 ответов

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

(1) Реализовать стек для этой другой структуры. Да, это двойная работа, но на вашем этапе каждая работающая программа имеет значение. Собирает опыт.

(2) Сравните программы. Какие у них общие части? Чем отличаются эти части? Ваша цель - отделить общие части от частей, которые отличаются. Какие средства эти две группы используют для общения? Общие части идут в одну часть Вашей системы (stack.h/stack.c), другие части идут в собственные файлы (account.h/c, person.h/c и т.д.). А часть, где вы их объединяете, должна включать в себя stack.h и сущность параметризации.

(3) Попробуйте найти все возможные способы, которые предлагает язык для реализации функциональности абстрактной структуры. Сначала всегда кажется, что есть только один путь, но для каждой нетривиальной проблемы существует несколько подходов. В стековом случае, используя стандартный C, например, zou можно использовать указатели на пустоты, препроцессорные макросы, следует обратить внимание на вставку токенов, можно использовать указатели на функции плюс указатели на структуры и т.д.

(4) Реализуйте как можно больше из них. Опять же, это для обучения. В C столько ловушек, и чем раньше вы их встретите, тем лучше.

(5) После того, как вы перечислили и реализовали все эти различные подходы, вы должны их оценить: Какой из них легче всего использовать? Какой из них был самым простым в реализации? Какой из них самый быстрый? Какой из них проще всего отладить?

15
ответ дан 1 December 2019 в 17:59
поделиться

Хотя большая часть советов здесь звездная (я призываю вас попробовать множество различных методов, чтобы получить опыт), я рекомендую использовать C ++. Используйте шаблон стека, чтобы создать реализацию, затем используйте extern «C», чтобы создать набор функций C api для его использования.

вам понадобится

  o constructor to create the object
  o a destructor to destroy the object
  o a push function
  o a pop function
  o an "is_empty" function.

Последние 3 функции будут принимать указатель на объект в качестве их первого (void *) параметра. Внутри функции этот указатель будет приведен к типу объекта стека, а затем использован в обычная мода на C ++.

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

1
ответ дан 1 December 2019 в 17:59
поделиться

Для производственного кода я обычно предпочитаю Си++. Даже если вы не планируете использовать OO, дженерики и метапрограммирование, вы можете использовать Си++ как лучший Си (в данном случае, просто чтобы получить std::stack бесплатно).

Если вам нужно использовать Си, постарайтесь сделать его простым и сделайте прагматичный выбор, основываясь на ваших конкретных обстоятельствах. Например, если вы точно знаете, что ваш стек ограничен каким-то маленьким лимитом и данные, которые вы держите в руках, просты, то ваш код стека может быть таким же простым, как stack[tos++] = x; и return stack[--tos], без необходимости использования библиотеки многоразового использования. Ответы, предлагающие библиотеку, основанную на void*, также уместны при различных обстоятельствах. Стандартный std::stack практически решает эту проблему раз и навсегда; Си не дает такой роскоши.

.
2
ответ дан 1 December 2019 в 17:59
поделиться

Здесь я привел пример общего программирования на языке Си. Хотя это и не алгоритм структуры данных, но, что-то вроде того, он может дать некоторые подсказки на эту тему. Надеюсь, это вам поможет.

Ниже приведен алгоритм, представляющий собой общую реализацию алгоритма сортировки пузырьков. Я использую указатели на пустоты, и приводю данные для работы на уровне байтов. Также я использую внешнюю функцию сравнения, которая является единственным кодом, знающим тип сортируемых данных. Эта функция сравнения передается в качестве параметра алгоритму сортировки.

Еще один важный момент заключается в том, что основному алгоритму необходимо знать размер в байтах обрабатываемых данных, чтобы знать, сколько байт необходимо для перемещения этих данных на новое место в массиве. Он также создает буфер для хранения одного экземпляра этих данных (переменная k в функции bubleSort).

    static int compare(void *menor, void *maior)
    {
       int *pMenor = (int *)menor;
       int *pMaior = (int *)maior;

       return ( *pMenor > *pMaior );
    }

    void bubleSort(void *base, int bWidth, int len, int (*func)(void *key, void *data))
    {
       int i, j;
       char *k=0;
       char *bPtr = (char *)base;         //Points to the beginning of the array 
       char *pi, *pj;

       k = (char *)malloc(bWidth);        //Creates a new var with the size of the data type

       if(!k)
          return;

       for(i = 0; i < len; i++)
       {
          pi = (bPtr + (i*bWidth));

          for(j=i+1; j < len; j++)
          {
             pj = (bPtr+(j*bWidth));

             if( func((void *)pi, (void *)pj) )
             {
                memcpy(k, pi, bWidth);
                memcpy(pi,pj, bWidth);
                memcpy(pj, k, bWidth);
             }
          }
       }

       free(k);
    }

int main()
{
   int vet[5] = {4, 1, 3, 5, 2};
   bubleSort((void *)vet, sizeof(int), 5, compare);

   return 0;
}
2
ответ дан 1 December 2019 в 17:59
поделиться

Я считаю, что абстракция в основном находится в глазах программиста. Великий программист может видеть паттерн в простых выражениях, даже на таком низкоуровневом языке как C. Языки и их синтаксис, безусловно, могут помочь, но то, как в конце концов пишутся выражения и выражения, в некоторой степени отличает хороших программистов от плохих. Тем не менее, как это может помочь? Ну, я хочу сказать, что познакомиться с конструкциями на Си, чтобы Вы знали их, когда увидите, и void*, как упоминает Кевин Монтроуз, является обычным явлением. Стратегии, которые я считаю хорошими, это подумать о stdlib, как там все было решено и отразиться в отличном коде, когда вы видите некоторые из них. Т.е. общий шаблон паттерна в stdlib должен иметь ноль (0), чтобы представлять OK. Или подумайте о том, насколько хорошо файловый скриптор работает со всеми функциями read, write и т.д., независимо от их происхождения (сокет, файл, труба и т.д.). Этот SO вопрос (link) имеет несколько хороших ссылок на отличный код для чтения.

alt text
(source: skitch.com)

Изображение из Thinking Forth, великой старой книги по программированию, независимо от языка.

10
ответ дан 1 December 2019 в 17:59
поделиться

Я не делаю много взлома C, но я думаю, что путь к этому недействителен * .

Поэтому просто перепишите стек push/pop void * вместо some _ struct * . Это становится вашей проблемой, чтобы держать типы правильными, но это просто цена, которую вы платите за использование такого низкоуровневого * языка программирования.

* Не подразумевать, что это плохо.

13
ответ дан 1 December 2019 в 17:59
поделиться

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

Лучшее, что вы можете сделать, это написать свои структуры данных, чтобы всегда использовать void * и оставить каждое распределение / освобождение / литье для абонента. Это грязно и ошибка, хотя.

1
ответ дан 1 December 2019 в 17:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: