Collections-C هي مكتبة لهياكل البيانات العامة للغة C.
الهياكل التي تخزن البيانات في شكل void*
.
حاوية | وصف |
---|---|
CC_Array | مصفوفة ديناميكية تتوسع تلقائيًا عند إضافة العناصر. |
CC_List | قائمة مرتبطة بشكل مضاعف. |
CC_SList | قائمة مرتبطة منفردة. |
CC_Deque | مصفوفة ديناميكية تدعم إدراج الوقت الثابت المطفأ وإزالته من كلا الطرفين والوصول إلى الوقت الثابت. |
CC_HashTable | خريطة قيمة المفتاح غير مرتبة. يدعم أفضل حالة مستهلكة لإدراج الوقت الثابت وإزالتها والبحث عن القيم. |
CC_TreeTable | خريطة قيمة المفتاح مرتبة. يدعم إدخال الوقت اللوغاريتمي وإزالته والبحث عن القيم. |
CC_HashSet | مجموعة غير مرتبة. يتم إجراء البحث والحذف والإدراج في وقت ثابت مطفأ وفي أسوأ الحالات في وقت خطي مطفأ. |
CC_TreeSet | مجموعة مرتبة. يتم إجراء البحث والحذف والإدراج في وقت لوغاريتمي. |
CC_Queue | هيكل FIFO (ما يدخل أولاً يخرج أولاً). يدعم الإدراج المستمر للوقت والإزالة والبحث. |
CC_Stack | هيكل LIFO (آخر ما يدخل أولاً يخرج أولاً). يدعم الإدراج المستمر للوقت والإزالة والبحث. |
CC_PQueue | قائمة انتظار الأولوية. |
CC_RingBuffer | عازلة حلقة. |
CC_TSTTable | جدول شجرة البحث الثلاثي. يدعم الإدراج والبحث والتكرار والحذف. |
int value = 20 ;
CC_Array * array ;
if ( cc_array_new ( & array ) != CC_OK ) { /*Create a new array.*/
// handle error
}
if ( cc_array_add ( & array , ( void * ) & value ) != CC_OK ) { /* Add the pointer to the value to the array */
// handle error
}
الهياكل التي تخزن البيانات ذات الطول التعسفي مباشرة.
حاوية | وصف |
---|---|
CC_ArraySized | مصفوفة ديناميكية تتوسع تلقائيًا عند إضافة العناصر. |
int value = 20 ;
CC_SizedArray * array ;
if ( cc_sized_array_new ( sizeof ( int ), & array ) != CC_OK ) { /* Create a new array that stores values the size of an int*/
// handle error
}
if ( cc_sized_array_add ( & array , & value ) != CC_OK ) { /* Copy the value into the array */
// handle error
}
تجمعات الذاكرة عبارة عن كتل مخصصة مسبقًا من الذاكرة المتجاورة
حاوية | وصف |
---|---|
CC_DynamicPool | على الكومة، تجمع الذاكرة يحتمل أن يكون قابلاً للتوسيع |
CC_StaticPool | بركة ثابتة |
/* CC_StaticPool can enable the use of the structures on the stack */
#include "memory/cc_static_pool.h"
#include "cc_list.h"
CC_StaticPool * pool ;
// Alloc wrappers
void * pool_malloc ( size_t size ) { cc_static_pool_malloc ( size , pool );}
void * pool_calloc ( size_t count , size_t size ) { cc_static_pool_calloc ( count , size , pool );}
void pool_free ( void * ptr ) { cc_static_pool_free ( ptr , pool );}
int main ( int argc , char * * argv ) {
uint8_t buffer [ 2000 ]; /* Large enough buffer. */
cc_static_pool_new ( sizeof ( buffer ), 0 , buffer , buffer , & pool ); /* allocate the pool structure inside the buffer */
CC_ListConf conf ; /* Create a new list config */
cc_list_conf_init ( & conf );
conf . mem_alloc = pool_malloc ; /* Set list memory allocators to pool allocators */
conf . mem_calloc = pool_calloc ;
conf . mem_free = pool_free ;
CC_List * list ;
cc_list_new_conf ( & conf , & list ); /* The newly created list will be allocated inside the "buffer" array*/
// Use the list
return 0 ;
}
يمكن عادةً تثبيت هذه الحزم من خلال مدير حزم التوزيعات لديك.
لبناء المشروع، نحتاج أولاً إلى إنشاء دليل بناء منفصل (إذا لم يكن موجودًا بالفعل):
mkdir build
من هذا الدليل يمكننا تشغيل الأمر cmake
وتكوين البنية:
cmake ..
أو cmake -DSHARED=True
لإنشاء Collections-C كمكتبة مشتركةcmake -DSHARED=False
لإنشاء مكتبة ثابتة بمجرد cmake
من إنشاء ملفات makefiles، يمكننا إنشاء المكتبة عن طريق تشغيل make
داخل دليل البناء الخاص بنا.
مثال على الاستنساخ وبناء مكتبة ثابتة:
git clone https://github.com/Collections-C.git
cd Collections-C
mkdir build
cd build
cmake -DSHARED=False
make
لتشغيل الاختبارات (من دليل build
):
make test
لإجراء اختبارات فردية، ما عليك سوى تشغيل الملف القابل للتنفيذ المناسب. على سبيل المثال:
build/test/array_test
لتثبيت تشغيل المكتبة:
sudo make install
افتراضيًا، سيتم تثبيت المكتبات والرؤوس في المجلدين /usr/local/lib/
و /usr/local/include
.
يجب عليك أن تجعل وقت تشغيل النظام على علم بموقع المكتبة الجديدة لتتمكن من تشغيل التطبيقات المرتبطة ديناميكيًا. قد يكون هذا الأمر بسيطًا مثل تشغيل الأمر التالي إذا كان /etc/ld.so.conf
يحتوي على دليل التثبيت.
ملاحظة: نظام التشغيل macOS لا يدعم ldconfig.
sudo ldconfig
إذا قمنا بالفعل ببناء المكتبة وتثبيتها، فيمكننا كتابة برنامج helloworld بسيط وحفظه في ملف اسمه hello.c
:
#include <stdio.h>
#include <collectc/cc_array.h>
int main ( int argc , char * * argv ) {
// Create a new array
CC_Array * ar ;
cc_array_new ( & ar );
// Add a string to the array
cc_array_add ( ar , "Hello World!n" );
// Retreive the string and print it
char * str ;
cc_array_get_at ( ar , 0 , ( void * ) & str );
printf ( "%s" , str );
return 0 ;
}
الآن نحن بحاجة إلى تجميع وربط برنامجنا. نظرًا لأن make
يبني كلاً من المكتبة الثابتة والديناميكية، فيمكننا اختيار المكتبة التي نرغب في ربطها ببرنامجنا.
إذا أردنا ربط المكتبة ببرنامجنا بشكل ثابت، فيمكننا تمرير العلامة -static
إلى المترجم
ملاحظة: في نظام التشغيل macOS، العلامة -static
ليست مألوفة للغاية (تتطلب أن تكون جميع المكتبات مرتبطة بشكل ثابت). لذا يمكننا استبدال -static -lcollectc
بالمسار الكامل للمكتبة الثابتة. وهو /usr/local/lib/libcollectc.a
افتراضيًا.
gcc hello.c -static -lcollectc -o hello
أو بالمثل عند التجميع باستخدام clang:
clang hello.c -static -lcollectc -o hello
سيؤدي هذا إلى ربط المكتبة عن طريق نسخها إلى الملف القابل للتنفيذ. يمكننا استخدام هذا الخيار إذا لم نرغب في أن يكون Collections-C تابعًا لوقت التشغيل ، ولكن هذا يأتي على حساب إنشاء ملف تنفيذي أكبر.
يمكننا أيضًا اختيار الارتباط بالمكتبة ديناميكيًا في وقت التشغيل. هذا هو السلوك الافتراضي إذا قمت بحذف علامة المترجم -static
:
gcc hello.c -lcollectc -o hello
أو مع رنة:
clang hello.c -lcollectc -o hello
يؤدي الارتباط ديناميكيًا إلى إنتاج ملف تنفيذي أصغر، ولكنه يتطلب وجود libcollectc.so
في كل نظام سيتم تنفيذ البرنامج عليه.
في بعض الأحيان قد يواجه المترجم مشكلة في العثور على المكتبة أو الرؤوس. يحدث هذا عادةً لأنه يبحث عنها في الدليل الخاطئ، وهو ما قد يحدث إذا تم تثبيت المكتبة أو الرؤوس أو كليهما في دليل غير قياسي أو لم يتم تثبيته على الإطلاق.
إذا كان الأمر كذلك، يمكننا أن نخبر المترجم بوضوح أين يبحث عنها عن طريق تمرير الخيارين -I[path to headers]
و -L[path to libraries]
:
gcc hello.c `pkg-config --cflags --libs collectionc` -o hello
إذا سار كل شيء على ما يرام مع التجميع يمكننا تشغيل الملف القابل للتنفيذ:
./hello
وينبغي أن تطبع Hello, World!
إلى وحدة التحكم.
المساهمات هي موضع ترحيب.
إذا كان لديك طلب ميزة، أو وجدت خطأ، فلا تتردد في فتح قضية جديدة. إذا كنت ترغب في المساهمة بالكود، راجع CONTRIBUTING.md لمزيد من التفاصيل.