From 32e562cb104ccc6c8030dedd524cd6b1f26628c9 Mon Sep 17 00:00:00 2001 From: dzruyk Date: Fri, 14 Apr 2023 17:18:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B,=20=D0=BE=D0=B1=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D1=80=D0=B8=D0=B4=D0=BC=D0=B8=D1=85=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.txt => README.md | 31 ++++++++------- macro.h | 1 - util.c | 1 - util.h | 2 +- vector.h | 22 +++++++++-- vector_test.c | 87 ++++++++++++++++++++++++++++++++++------- 6 files changed, 107 insertions(+), 37 deletions(-) rename README.txt => README.md (51%) diff --git a/README.txt b/README.md similarity index 51% rename from README.txt rename to README.md index d724526..d74889c 100644 --- a/README.txt +++ b/README.md @@ -1,25 +1,24 @@ -Базовые структуры данных. Вектор --------------------------------- +# Базовые структуры данных. Вектор -* Склонировать репозиторий https://timp.pw/121/lab4_ivec.git +* Склонировать репозиторий `https://timp.pw/121/lab4_ivec.git` (если репозиторий уже склонирован -- пропустить этот шаг ^_^) В этом задании мы должны реализовать вектор для типа int. Вектор -- это динамический массив данных, который может менять свой размер в процессе работы. - Описание структуры данных ivector в файле vector.h + Описание структуры данных ivector в файле `vector.h` - Вам необходимо реализовать некоторые функции в файле ./vector.c - и пройти тесты (описанные в ./vector_test.c). + Вам необходимо реализовать некоторые функции в файле `./vector.c` + и пройти тесты (описанные в `./vector_test.c`). - Команда для сборки проекта -- make - Команда для запуска тестов -- make test + Команда для сборки проекта -- **make** + Команда для запуска тестов -- **make test** * Необходимо реализовать следующие функции(короткое описание функций можно - подсмотреть в vector.h): - + подсмотреть в `vector.h`): +``` vector_len vector_data vector_resize @@ -30,15 +29,17 @@ vector_push vector_pop - (Опционально, но очень желательно) vector_insert vector_del +``` + +Для функций `vector_insert`, `vector_del` написать тесты в `vector_test.c` Для работы вам могут понадобится следующие библиотечные функции: -* malloc(size_t size) -- функция, динамически выделяющая size байт и возвращающая +* `malloc(size_t size)` -- функция, динамически выделяющая **size** байт и возвращающая указатель на выделенный кусок -* realloc(void *ptr, size_t size) -- функция изменяющая размер выделенного куска памяти +* `realloc(void *ptr, size_t size)` -- функция, изменяющая размер выделенного куска памяти на вход принимает указатель на предыдущий выделенный кусок. - возвращает укзаатель на заново выделенную память. - Все предыдущие данные в ptr остаются без изменений + Функция возвращает указатель на заново выделенную память. + Все предыдущие данные в `ptr` остаются без изменений diff --git a/macro.h b/macro.h index fae0ee1..77fe232 100644 --- a/macro.h +++ b/macro.h @@ -12,4 +12,3 @@ #define ARR_FOREACH(arr, item) \ for (item = arr; item != arr + ARRSZ(arr) * sizeof(*item); item++) - diff --git a/util.c b/util.c index 1514964..b9545c7 100644 --- a/util.c +++ b/util.c @@ -45,4 +45,3 @@ xerror(int rc, char *fmt, ...) exit(rc); } - diff --git a/util.h b/util.h index aa141f4..33a16bc 100644 --- a/util.h +++ b/util.h @@ -6,4 +6,4 @@ void* xrealloc(void *ptr, size_t size); void xfree(void *ptr); -void xerror(int rc, char *fmt, ...); +void xerror(int rc, char *fmt, ...); \ No newline at end of file diff --git a/vector.h b/vector.h index 589328a..32ac668 100644 --- a/vector.h +++ b/vector.h @@ -37,14 +37,28 @@ void vector_push(ivector *v, int val); /* Удалить последний элемент из вектора */ void vector_pop(ivector *v); -/* Вставить новое значение *val* по индексу *idx* - * idx может быть в диапазоне [0; v->n] +/* Добавить новое значение *val* по индексу *idx*. + * idx может быть в диапазоне [0; v->n]. + * + * Элемент по индексу *idx* и все последующие двигаются "вправо", например + * Вектор, содержащий элементы {0, 1, 2, 3, 4} + * после выполнения + * vector_insert(&vec, 2, 42) + * Будет выглядить так {0, 1, 42, 2, 3, 4} */ void vector_insert(ivector *v, size_t idx, int val); -/* Удалить элемент под индексом idx из вектора */ + +/* Удалить элемент под индексом idx из вектора + * idx может быть в диапазоне [0; v->n - 1] + * + * Все последующие после *idx* элементы двигаются "влево", например + * Вектор, содержащий элементы {0, 1, 42, 2, 3, 4} + * после выполнения + * vector_del(&vec, 2) + * Будет выглядить так {0, 1, 2, 3, 4} + */ void vector_del(ivector *v, size_t idx); /* очистить все элементы из вектора */ void vector_clear(ivector *v); - diff --git a/vector_test.c b/vector_test.c index 2b8857a..a804b91 100644 --- a/vector_test.c +++ b/vector_test.c @@ -6,25 +6,62 @@ #include "munit/munit.h" static MunitResult -test_vector_getters(const MunitParameter params[], void * data) +test_vector_len(const MunitParameter params[], void * data) { - // (Really stupid) tests for vector_len and vector_data ivector v; vector_init(&v); munit_assert_size(vector_len(&v), ==, 0); - munit_assert_not_null(vector_data(&v)); // Lame method, that checks vector_len getter v.n = 1337; munit_assert_size(vector_len(&v), ==, 1337); + + vector_free(&v); + munit_assert_size(vector_len(&v), ==, 0); + + return MUNIT_OK; +} + +static MunitResult +test_vector_data(const MunitParameter params[], void * data) +{ + // (Really stupid) test for vector_data + ivector v; + vector_init(&v); + + munit_assert_not_null(vector_data(&v)); + vector_free(&v); + munit_assert_null(vector_data(&v)); + + return MUNIT_OK; +} + +static MunitResult +test_vector_initdata(const MunitParameter params[], void * data) +{ + int *p; + int i; + ivector v; + int arr[] = { + 1, 2, 3, 4, 5 + }; + + vector_initdata(&v, arr, ARRSZ(arr)); + p = vector_data(&v); + munit_assert_not_null(p); + munit_assert_size(vector_len(&v), ==, ARRSZ(arr)); + + for (i = 0; i < ARRSZ(arr); i++) { + munit_assert_int(arr[i], ==, p[i]); + } vector_free(&v); return MUNIT_OK; } static MunitResult -test_vector_init_reserve(const MunitParameter params[], void * data) +test_vector_resize(const MunitParameter params[], void * data) { int i; int arr[] = { @@ -35,14 +72,6 @@ test_vector_init_reserve(const MunitParameter params[], void * data) ivector v; vector_initdata(&v, arr, ARRSZ(arr)); - p = vector_data(&v); - munit_assert_not_null(p); - munit_assert_size(vector_len(&v), ==, ARRSZ(arr)); - - for (i = 0; i < ARRSZ(arr); i++) { - munit_assert_int(arr[i], ==, p[i]); - } - vector_resize(&v, 16); munit_assert_size(vector_len(&v), ==, 16); @@ -56,7 +85,33 @@ test_vector_init_reserve(const MunitParameter params[], void * data) } vector_free(&v); + return MUNIT_OK; +} +static MunitResult +test_vector_set_get(const MunitParameter params[], void * data) +{ + int arr[] = { + 1, 2, 3, 4, 5 + }; + ivector v; + int *p; + int i; + + vector_initdata(&v, arr, ARRSZ(arr)); + for (i = 0; i < vector_len(&v); i++) { + vector_set(&v, i, i); + } + + p = vector_data(&v); + for (i = 0; i < vector_len(&v); i++) { + int item = vector_get(&v, i); + munit_assert_int(item, ==, i); + //double check with raw pointer + munit_assert_int(p[i], ==, i); + } + + vector_free(&v); return MUNIT_OK; } @@ -110,9 +165,12 @@ test_vector_push_pop(const MunitParameter params[], void * data) #define TEST_ITEM(func) {#func, func, NULL, NULL, MUNIT_TEST_OPTION_NONE } static MunitTest test_suite_tests[] = { - TEST_ITEM(test_vector_getters), + TEST_ITEM(test_vector_len), + TEST_ITEM(test_vector_data), + TEST_ITEM(test_vector_initdata), - TEST_ITEM(test_vector_init_reserve), + TEST_ITEM(test_vector_resize), + TEST_ITEM(test_vector_set_get), TEST_ITEM(test_vector_push_pop), //TEST_ITEM(test_pvector_init), @@ -134,4 +192,3 @@ main(int argc, const char *argv[]) munit_suite_main(&test_suite, (void *) "vector_test", argc, (char * const*) argv); return 0; } -