LINUX.ORG.RU

Подскажите как писать код на C

 , ,


2

4

У меня есть несколько проблем, из-за которых я не знаю как можно создать свой проект.

  • Как мне использовать key-value структуру данных? В других языках используется библиотека (Java) или встроенная реализация (Go). А что используют в проектах, написанных на C?
  • Как в проектах на C узнают длину массива, переданного как аргумент? Я знаю, что массивы передаются как указатели, а указать длину данных за указателем - невозможно. Нужно всегда передавать длину как аргумент? Я также понимаю, что можно создавать свои структуры, состоящие из указателя и длины, но как это грамотно сделать, чтобы потом не запутаться в типах и бойлерплейте? Возможно, есть нормальная практика, которой все следуют?
  • Единственный способ иметь в структуре несколько массивов - использовать указатели. Значит, память нужно выделять и очищать вручную. Значит, для работы с такими структурами нужно иметь функции-обёртки. Так все делают для создания нескольких массивов в структуре?


Последнее исправление: elonmusk (всего исправлений: 3)

Как мне использовать key-value структуру данных?

Структурой с двумя строками.

Как в проектах на C узнают длину массива, переданного как аргумент?

Передавай вместе с массивом и длину, либо структурой содержащей значение длины (см. как устроены структуры image).

Так все делают для создания нескольких массивов в структуре?

Да (см. как устроены структуры image).

Deleted
()

Как мне использовать key-value структуру данных?

Написать контейнер, реализующий такую структуру.


Как в проектах на C узнают длину массива, переданного как аргумент?

Никак. Поэтому передаётся два аргумента: указатель на начало и размер. Либо, в нуль-терминированный строках — ищут ноль.


Единственный способ иметь в структуре несколько массивов - использовать указатели

struct
  {
	int a[5];
	int b[3];
  }
XMs ★★★★★
()

Kv-структур дохрена видов, выбери подходящий и найди/напиши (uthash..sqlite(:memory:)). 2. Длину хранят рядом с массивом, передают вторым аргументом. 3. Ты можешь в структуре иметь сколько угодно массивов, но динамические - только через указатели, даже один. В целом да.

anonymous
()

узнают длину массива

key-value структуру данных

Библиотеки или велосипеды. Зависит от нефункциональных требований и бюджета.

функции-обёртки

Как будто в других языках по-другому. Ну да, там языковыми средствами оно генерируется.


Итого:

Прежде, чем браться за разработку на C надо чётко и честно ответить себе на вопросы - зачем это? по карману ли это? как поживает твой диабет?

pon4ik ★★★★★
()
Последнее исправление: pon4ik (всего исправлений: 1)

На C можно писать как на Java/C++

То есть использовать библиотеки с нормальными контейнерами.

Массив:

// gcc list.c `pkg-config --libs --cflags glib-2.0 gee-0.8`
#include <glib.h>
#include <glib-object.h>
#include <gee.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
    GeeArrayList* list = gee_array_list_new (G_TYPE_INT, NULL, NULL, NULL, NULL, NULL);
    gee_abstract_collection_add ((GeeAbstractCollection*)list, (gpointer) ((gintptr) 1));
    gee_abstract_collection_add ((GeeAbstractCollection*)list, (gpointer) ((gintptr) 2));
    gee_abstract_collection_add ((GeeAbstractCollection*)list, (gpointer) ((gintptr) 3));
    gee_abstract_collection_add ((GeeAbstractCollection*)list, (gpointer) ((gintptr) 4));
    gee_abstract_list_remove_at ((GeeAbstractList*) list, 3);
    gee_abstract_list_set ((GeeAbstractList*)list, 2, (gpointer) ((gintptr) 10));


    gint list_size = gee_abstract_collection_get_size ((GeeAbstractCollection*) list);
    for (gint i = 0; i < list_size; ++i)
    {
        gpointer data = gee_abstract_list_get ((GeeAbstractList*) list, i);
        gint real_data = (gint)data;
        fprintf (stdout, "%d\n", real_data);
    }
    g_object_unref (list);
}

Map

// gcc map.c `pkg-config --libs --cflags glib-2.0 gee-0.8`
#include <glib.h>
#include <glib-object.h>
#include <gee.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    GeeHashMap* map = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, G_TYPE_INT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    gee_abstract_map_set ((GeeAbstractMap*) map, "one", (gpointer) ((gintptr) 1));
    gee_abstract_map_set ((GeeAbstractMap*) map, "two", (gpointer) ((gintptr) 2));
    gee_abstract_map_set ((GeeAbstractMap*) map, "three", (gpointer) ((gintptr) 3));
    gee_abstract_map_set ((GeeAbstractMap*) map, "four", (gpointer) ((gintptr) 4));
    gee_abstract_map_set ((GeeAbstractMap*) map, "five", (gpointer) ((gintptr) 5));

    gpointer data = gee_abstract_map_get ((GeeAbstractMap*) map, "four");
    gint a = (gint) ((gintptr) data);

    data = gee_abstract_map_get ((GeeAbstractMap*) map, "four");
    gint b = (gint) ((gintptr) data);

    assert (a == b);

    fprintf (stdout, "Iterating over entries\n");
    {
        GeeSet* entries = gee_abstract_map_get_entries ((GeeAbstractMap*) map);
        GeeIterator* entry_it = gee_iterable_iterator ((GeeIterable*) entries);;
        while (gee_iterator_next (entry_it))
        {
            GeeMapEntry* entry = (GeeMapEntry*)gee_iterator_get (entry_it);
            gconstpointer key = gee_map_entry_get_key (entry);
            gconstpointer value = gee_map_entry_get_value (entry);
            fprintf (stdout, "%s => %d\n", (const gchar*) key, (gint) ((gintptr) value));
	    g_object_unref (entry);
        }
        g_object_unref (entry_it);
        g_object_unref (entries);
    }

    g_object_unref (map);
}

Отличия от Java минимальны...

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)

Как мне использовать key-value структуру данных?

Напиши парсер, делов-то! Самый оптимальный вариант - использование некоей хеширующей функции. В этом случае просто делаем switch по хешу, а уж дальше strcmp вызываем. Сильно экономит ресурсы.

Как в проектах на C узнают длину массива, переданного как аргумент?

Как аргумент, вестимо. Но лучше не делай так, а создай структуру, где помимо массива будет длина храниться. Это удобней.

Так все делают для создания нескольких массивов в структуре?

Да, ясное дело! Тебе нужны функции-конструкторы и функции-деструкторы. В недоЯПах вроде цепепе деструкторы неявно вызываются при выходе из области видимости, для простых случаев предусмотрены примитивные деструкторы a la free().

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

Любителям глиба надо яйца отрывать!

А мне нравится glib.

Научился писать на C++, и внезапно умеешь писать на C, C#, Java, Typescript. Лишь названия классов и методов чуток изменяются , но не сама суть. Тот же Rust гораздо дальше от С++, чем С + glib

fsb4000 ★★★★★
()

Как мне использовать key-value структуру данных?

Написать её или взять библиотеку. Например glib.

Как в проектах на C узнают длину массива, переданного как аргумент?

Её узнают если передают рядом.

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

Нет, массив может быть фиксированной длинны, выше даже пример дали.

Значит, память нужно выделять и очищать вручную.

Если память выделяется на куче, то да. А вообще вопросы выдают нехватку знаний. Я бы рекомендовал осилить хотя бы одну книгу по С. Тем кто хочет писать на С в питон-стиле (после прочтение туториала на сайте), надо приготовиться к серьёзным разочарованиям. К примеру у Прата есть целая глава посвящённая абстрактным типам данных.

andalevor ★★
()

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

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

Например glib

Еще один любитель гадостей...

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

Если же решите сами писать контейнеры

То сразу вдоль. ТС даже нормальный вектор не осилит, что говорить о чём-то сложнее.

RazrFalcon ★★★★★
()

С - это про закат Солнца вручную. Библиотека там минимальная, так что всё, что выходит за её рамки, делай сам.

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

Если речь про начало - начни с контрибьюта в то, где уже построен фреймворк. Ибо C про то, что бы сделать себе песочницу со своим блэкджеком и распутными девами.

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

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

выглядит ужасно, особенно вот это:

gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, G_TYPE_INT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);

anonymous
()
  • библиотеку
  • всегда передавать длину
  • да, иметь функции-обёртки

Каждый пункт тебе прямо кричит о неприменимости C для реальных задач - брось же эту дрянь.

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

неприменимости C для реальных задач

У тебя, похоже, мозг не применим для реальных задач. А на С можно делать все, что угодно!

anonymous
()

Как мне использовать key-value структуру данных? В других языках используется библиотека (Java) или встроенная реализация (Go). А что используют в проектах, написанных на C?

Тут надо определиться какой тип контейнера будет быстрее всего, после этого можно выбрать библиотеку и всунуть туда данные.

Как в проектах на C узнают длину массива, переданного как аргумент?

Передают размер массива.

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

Нужно взять готовый контейнер.

Значит, для работы с такими структурами нужно иметь функции-обёртки. Так все делают для создания нескольких массивов в структуре?

Да.

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

Ну так сделай что угодно. Ты же одну банальщину пишешь.

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

Наконец-то адекватное мнение в комментариях. А если их нет? Вырывать матку или... Нет, а вдруг кастрат? Ваш способ не универсален, всё-таки.

anonymous
()

Написать интерпретатор лиспа и не париться!

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

И даже на не полном можно почти все угодно. Часто тюринг-полноту поминают не по делу.

Тюринг-полноту можно изобразить даже в неполном языке через взаимодействие с системой. Например убрать из си циклы и рекурсию, он станет неполным, но программа все равно сможет запускать себя же с другими аргументами через system("./путь-к-бинарнику") а из этого можно получить рекурсию и полноту, хотя в языке ее нет.

vlad9486
()
Последнее исправление: vlad9486 (всего исправлений: 1)
Ответ на: комментарий от vlad9486

libcello лучше брать когда у тебя нет вопросов которые задаёт ТС. Но за упоминание этой либы лайк и подписка

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от slovazap

Я не вижу проблемы в использовании разных языков в разных условиях. Я обсираю C++/Rust/Python часто, но обсираю лишь инопланетный синтаксис и просто визуальное уродство, но это всё не отменяет того что во многих задачах эти языки лучшее решение, так и С является лучшим решением в своих задачах и применимость его выше чем любого другого языка, так что говорить что он не ни на что не годен это такое себе, вот сказал бы ты что на нём не комельфо что то быстро сделать, а что то вообще неудобно настолько что при условии нетребовательности к перфомансу будет лучше взять любую скриптоту то я кивну и соглашусь, если хейтишь то либо обосновано, либо просто «Этот язык мне не нра паташушта он пахой и всё» тогда и спору нет на вкус и цвет фломастер разный

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

Python

инопланетный синтаксис

если за что и обсирать, то явно не за это. Упоминание питона в этом разрезе выдаёт быдлокодера. Вы случайно не пишете на жс?

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

C не является лучшим решением нигде, как минимум потому что есть его более безопасное, современное и эффективное надмножество. Его непригодность доказывается уже существованием данного топика, а про откровенную вредность было недавно на zdnet.

инопланетный синтаксис

Чисто ради поржать, а что у тебя не инопланетный?

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

про откровенную вредность было недавно на zdnet

А есть ссылка?

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

За упоминание libcello - сразу разжалование в школоту, которой си нужен только на поиграть.

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

Научился писать на C++, и внезапно умеешь писать на C, C#, Java, Typescript.

Нет, не умеешь. Программист_на_фортране.cpp

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

го непригодность доказывается уже существованием данного топика,

Скажи это Торвальдсу, и сообществу *bsd ))

Его непригодность доказывается уже существованием данного топика, а про откровенную вредность было недавно на zdnet.

Авторитетно!

Чисто ради поржать, а что у тебя не инопланетный?

Для тебя видимо да, как для меня те языки про которые я говорил. Это просто вкусовщина. Если тебе не нравится С чисто из за его вида и как выглядят/читаются программы, ну чё пожалуйста, у меня такое же мнение по поводу многих других языков и тут можно просто помолчать или посраться о вкусовщине.

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

Никто не заставляет использовать, но там реализовано много чего, ТС может легко посмотреть как реализовать ту или иную штуку

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

Скажи это Торвальдсу, и сообществу *bsd ))

Ещё раз, если намёк не был понят - использовать как аргумент за язык существование тонны говённого легаси на этом языке - это расписываться даже не в профнепригодности, а просто в отсутствии логического мышления.

Это просто вкусовщина

Именно, и я, в отличие от тебя, её не затрагиваю ни коим образом. Убогость и небезопасность C - это объективный факт, и именно поэтому там нет ни key-value, одну сущность нельзя передать одним аргументом, и для работы с мало-мальски сложной структурой нужно написать тонну обёрток, где нужно не забыть всё в правильном порядке выделить, инициализировать и потом освободить.

И всё-таки, чисто для себя, я жду списка языков которые ты не считаешь инопланетными.

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

Скажи это Торвальдсу

А он уже начал писать на чистом С, который умеют собирать компиляторы отличные от gcc?

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

Лучше Python взять, будет проще, удобнее, быстрее.

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

Каждый пункт тебе прямо кричит о неприменимости C для реальных задач

Лол, приятного переписывания кучи существующих библиотек. Русский и английский тоже не идеальные, но ими пользуются! Вот и С пользуются, библиотеки есть, скорость есть, все прекрасно.

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