LINUX.ORG.RU

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

 , ,


2

4

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

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

Как мне использовать 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

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

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

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

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

slovazap ★★★★★ ()

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

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

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

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

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

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

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

Да.

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

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

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

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

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

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

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

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

Python

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Deleted ()