Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions 05_hw/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,34 @@
cmake_minimum_required(VERSION 3.10)
project(stack)

# Включаем clang-tidy, если он найден
find_program(CLANG_TIDY clang-tidy)
if(CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY};-checks=-*,clang-analyzer-*")
message(STATUS "clang-tidy found: ${CLANG_TIDY}")
else()
message(STATUS "clang-tidy not found, skipping.")
endif()

# Включаем санитайзеры для Clang
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,memory")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address,memory")
message(STATUS "Sanitizers enabled")
endif()

# Добавляем библиотеку stack
add_library(stack stack.c)

# Добавляем исполнимые файлы
add_executable(Test test.c benchmark.c)
target_link_libraries(Test stack)

add_executable(main main.c)
target_link_libraries(main stack)

# Добавляем возможность установки бинарников
install(TARGETS main Test stack
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
43 changes: 43 additions & 0 deletions 05_hw/benchmark.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "stack.h"

#define BENCHMARK_SIZE 1000000

void benchmark_push() {
Stack stack;
initStack(&stack);
clock_t start, end;
double cpu_time_used;

start = clock();
for (int i = 0; i < BENCHMARK_SIZE; i++) {
push(&stack, i);
}
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;

printf("Benchmark push: %f seconds\n", cpu_time_used);
destroyStack(&stack);
}

void benchmark_pop() {
Stack stack;
initStack(&stack);
for(int i = 0; i < BENCHMARK_SIZE; i++) {
push(&stack, i);
}
clock_t start, end;
double cpu_time_used;

start = clock();
for (int i = 0; i < BENCHMARK_SIZE; i++) {
pop(&stack);
}
end = clock();
cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;

printf("Benchmark pop: %f seconds\n", cpu_time_used);
destroyStack(&stack);
}
12 changes: 12 additions & 0 deletions 05_hw/benchmark.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

void benchmark_push();
void benchmark_pop();

#ifdef __cplusplus
}
#endif
5 changes: 2 additions & 3 deletions 05_hw/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ int main() {
printf("Top element: %d\n", topElement->data);
}

destroyStack(&stack);
return 0;
}


}
23 changes: 19 additions & 4 deletions 05_hw/stack.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "stack.h"

Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if(newNode == NULL){
perror("Failed to allocate memory for node");
exit(EXIT_FAILURE);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
Expand All @@ -21,6 +26,7 @@ void destroyStack(Stack* stack) {
current = current->next;
free(tmp);
}
stack->top = NULL;
}

void push(Stack* stack, int data) {
Expand All @@ -30,22 +36,33 @@ void push(Stack* stack, int data) {
}

void pop(Stack* stack) {
if(stack->top == NULL){
return; // Если стек пустой, ничего не делаем.
}
Node* temp = stack->top;
stack->top = stack->top->next;
free(temp);
}

Node* searchByValue(Stack* stack, int value) {
Node* current = stack->top;
if (current == NULL){
return NULL;
}
while (current != NULL) {
if (current->data == value) {
return current;
}
current = current->next;
}
return NULL;
}

Node* searchByIndex(Stack* stack, int index) {
Node* current = stack->top;
if (current == NULL){
return NULL;
}
int count = 0;
while (current != NULL) {
if (count == index) {
Expand All @@ -62,7 +79,7 @@ Node* getTop(Stack* stack) {
}

void traverseStack(Stack* stack) {
Node* current = stack->top;
Node* current = stack->top;
printf("Stack elements: ");
while (current != NULL) {
printf("%d ", current->data);
Expand All @@ -72,7 +89,5 @@ void traverseStack(Stack* stack) {
}

bool isEmpty(Stack* stack) {
free(stack->top);
return stack->top == NULL;
}

}
2 changes: 1 addition & 1 deletion 05_hw/stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ bool isEmpty(Stack* stack);

#ifdef __cplusplus
}
#endif
#endif
164 changes: 164 additions & 0 deletions 05_hw/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "stack.h"
#include "benchmark.h"


void print_error(const char* test_name, const char* message) {
fprintf(stderr, "Test %s failed: %s\n", test_name, message);
}


void test_init_stack() {
Stack stack;
initStack(&stack);
assert(stack.top == NULL); // Убедиться, что стек пуст
printf("Test init_stack passed\n");
}

void test_push() {
Stack stack;
initStack(&stack);
push(&stack, 10);
assert(stack.top != NULL); // Вершина не должна быть NULL после push
assert(stack.top->data == 10); // Данные на вершине соответствуют добавленному элементу
push(&stack, 20);
assert(stack.top->data == 20); // Вершина обновляется с каждым новым элементом
printf("Test push passed\n");
destroyStack(&stack);
}


void test_pop() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
pop(&stack);
assert(stack.top != NULL && stack.top->data == 10); // Удален верхний элемент
pop(&stack);
assert(stack.top == NULL); // Стек пуст
pop(&stack); // Попытка удалить из пустого стека
assert(stack.top == NULL); // Никаких изменений для пустого стека
printf("Test pop passed\n");
destroyStack(&stack);
}


void test_search_by_value() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);

Node* result = searchByValue(&stack, 20);
assert(result != NULL && result->data == 20);

result = searchByValue(&stack, 15);
assert(result == NULL);

// Проверка на пустом стеке
Stack emptyStack;
initStack(&emptyStack);
result = searchByValue(&emptyStack, 10);
assert(result == NULL);

printf("Test search_by_value passed\n");
destroyStack(&stack);
}


void test_search_by_index() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);

Node* result = searchByIndex(&stack, 1);
assert(result != NULL && result->data == 20); // Элемент по индексу 1 найден

result = searchByIndex(&stack, 0);
assert(result != NULL && result->data == 30); // Элемент по индексу 0 найден

result = searchByIndex(&stack, 5);
assert(result == NULL); // Индекс вне пределов

// Проверка на пустом стеке
Stack emptyStack;
initStack(&emptyStack);
result = searchByIndex(&emptyStack, 0);
assert(result == NULL);
printf("Test search_by_index passed\n");
destroyStack(&stack);
}


void test_get_top() {
Stack stack;
initStack(&stack);
assert(getTop(&stack) == NULL); // Пустой стек
push(&stack, 10);
assert(getTop(&stack) != NULL && getTop(&stack)->data == 10); // Вершина корректна
push(&stack, 20);
assert(getTop(&stack)->data == 20);
printf("Test get_top passed\n");
destroyStack(&stack);
}


void test_is_empty() {
Stack stack;
initStack(&stack);
assert(isEmpty(&stack) == true);
push(&stack, 10);
assert(isEmpty(&stack) == false);
pop(&stack);
assert(isEmpty(&stack) == true);
printf("Test is_empty passed\n");
destroyStack(&stack);
}


void test_traverse_stack() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);

printf("Test traverse_stack (output check manually):\n");
traverseStack(&stack); // Вручную проверить вывод
destroyStack(&stack);
}


void test_destroy_stack() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
destroyStack(&stack);
assert(stack.top == NULL); // После уничтожения вершина должна быть NULL
printf("Test destroy_stack passed\n");
}

int main() {
// Запуск всех тестов
test_init_stack();
test_push();
test_pop();
test_search_by_value();
test_search_by_index();
test_get_top();
test_is_empty();
test_traverse_stack();
test_destroy_stack();

// Вызов функций для проведения бенчмарков
benchmark_push();
benchmark_pop();

return 0;
}