LINUX.ORG.RU

Сообщения XZentus

 

vpnhack

Форум — Security

Давеча наткнулся на сервис невиданной щедрости «Free Premium Tunneling Accounts/Best Tunneling Accounts Provider».

Собственно вопрос: где подвох, если там регистрацию не требуют, своё ПО устанавливать не предлагают и денежку не просят? Есть подозрение, что бесплатный сыр, как говорится, …

Адрес: https://vpnhack.com/

 , ,

XZentus
()

Си: Стэк

Форум — Development

Задача (придумал сам): реализовать слегка навороченный стэк и стандартные арифметические операции (+ / * -) Так как писал исключительно для себя, не стал делать файл .h и документацию. На, если надо, могу расписать, что к чему.

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

P.S. компилируется : gcc -Wall -g stack.c -lm

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <float.h>
#include <math.h>
#include <ctype.h>

#define STACK_INIT  1024
#define STACK_ADD   1024

#define BUFFER_INIT 4096
#define BUFFER_ADD  4096

enum type_expression {type_char, type_string, type_double};

struct stack_atom
{
    int type_data;
    int buffer_offset;
};

typedef struct stack_atom s_atom;

s_atom *stack;
char *data_buffer;

ptrdiff_t stack_size, top_element, buffer_size, buffer_top;

void stack_init(void)
{
    stack_size = STACK_INIT;
    buffer_size = BUFFER_INIT;
    if(!(stack = (s_atom*)malloc(stack_size * sizeof(s_atom))))
    {
        fputs("ERR : Cannot initialize stack\n", stdout);
        exit(1);
    }
    if(!(data_buffer = (char*)malloc(buffer_size * sizeof(char))))
    {
        fputs("ERR : Cannot initialize buffer\n", stdout);
        exit(2);
    }

    top_element = 0;
    buffer_top = 0;
}

void check_push(int add)
{
    if(top_element == stack_size)
    {
        stack_size += STACK_ADD;
        if(!(stack = (s_atom*)realloc(stack, sizeof(s_atom) * stack_size)))
        {
            fputs("ERR : Cannot reallocate stack\n", stdout);
            exit (3);
        }
    }
    if(buffer_top + add >= buffer_size)
    {
        buffer_size += BUFFER_ADD + add;
        if(!(data_buffer = (char*)realloc(data_buffer, sizeof(char) * buffer_size)))
        {
            fputs("ERR : Cannot reallocate data buffer\n", stdout);
            exit(4);
        }
    }
}

void push_char(char c)
{
    check_push(sizeof(char));

    stack[top_element].type_data = type_char;
    stack[top_element].buffer_offset = buffer_top;

    *(data_buffer + buffer_top) = c;

    ++buffer_top;
    ++top_element;
}

void push_double(double n)
{
    check_push(sizeof(double));

    stack[top_element].type_data = type_double;
    stack[top_element].buffer_offset = buffer_top;

    *((double *)(data_buffer + buffer_top)) = n;

    buffer_top += sizeof(double);
    ++top_element;
}

void push_string(char* str)
{
    int length = strlen(str);
    check_push(length + 1);

    stack[top_element].type_data = type_string;
    stack[top_element].buffer_offset = buffer_top;

    strncpy ((data_buffer + buffer_top), str, length);
    data_buffer[buffer_top + length + 1] = 0;

    buffer_top += length + 1;
    ++top_element;
}

void push(char *data)
{
    double dbl;
    if(data[1] == '\0') //special case;
    {
        if(isdigit(data[0]))
        {
            push_double((double)(data[0] - '0'));
            return;
        }
        push_char(data[0]);
        return;
    }
    else if((dbl = atof(data)) != 0.0)
    {
        push_double(dbl);
        return;
    }
    else
        push_string(data);
}

void print_object(int element)
{
    switch(stack[element].type_data)
    {
        case type_char:
            printf("%c ", (char)(*(data_buffer + stack[element].buffer_offset)));
            break;
        case type_double:
            printf("%e ", *((double *)(data_buffer + stack[element].buffer_offset)));
            break;
        case type_string:
            printf("%s ", (data_buffer + stack[element].buffer_offset));
    }
}

void binary_operation(char operation)
{
    double op1, op2;
    if((stack[top_element - 1].type_data == type_string) ||
            (stack[top_element - 2].type_data == type_string))
    {
        puts("WARN: Operations + - * / not work with strings");
        return;
    }
    if(stack[top_element - 1].type_data == type_char)
        op1 = (double)((char)(*(data_buffer + stack[top_element - 1].buffer_offset)));
    else
        op1 = (double)(*((double *)(data_buffer + stack[top_element - 1].buffer_offset)));

    if(stack[top_element - 2].type_data == type_char)
        op2 = (double)((char)(*(data_buffer + stack[top_element - 2].buffer_offset)));
    else
        op2 = (double)(*((double *)(data_buffer + stack[top_element - 2].buffer_offset)));
    switch(operation)
    {
        case '+':
            op1 += op2;
            break;
        case '-':
            op1 -= op2;
            break;
        case '*':
            op1 *= op2;
            break;
        case '/':
            if(fabs(op2) <= DBL_EPSILON*fmax(fabs(op2), 0))
            {
                puts("WARN: Division by zero");
                return;
            }
            op1 /= op2;
    }
    top_element -= 2;
    buffer_top = stack[top_element].buffer_offset;
    push_double(op1);
}

void main_loop(void)
{
    char command[256];
    size_t temp;
    while(1)
    {
        scanf("%255s", command);
        if(!command[1])
        {
            switch(command[0])
            {
                case '+':
                case '-':
                case '*':
                case '/':
                    if(top_element < 2)
                    {
                        puts("WARN: Not enough elements");
                        continue;
                    }
                    binary_operation(command[0]);
                    continue;
                case '.':
                    if(!top_element)
                    {
                        puts("WARN: Stack empty");
                        continue;
                    }
                    --top_element;
                    buffer_top = stack[top_element].buffer_offset;
                    print_object(top_element);
                    continue;
                case '^':
                    temp = top_element;
                    while(temp)
                        print_object(--temp);
                    continue;
                case '$':
                    temp = 0;
                    while(temp < top_element)
                        print_object(temp++);
                    continue;
                default:
                    push(command);
                    continue;
            }
        }
        else if(!strncmp(command, "exit", 255))
            exit(0);
        else if(!strncmp(command, "obj", 255))
        {
            printf("%td ", top_element);
            continue;
        }
        else if(!strncmp(command, "max_obj", 255))
        {
            printf("%td ", stack_size);
            continue;
        }
        else if(!strncmp(command, "data", 255))
        {
            printf("%td ", buffer_top);
            continue;
        }
        else if(!strncmp(command, "max_data", 255))
        {
            printf("%td ", buffer_size);
            continue;
        }
        else
            push(command);
    }
}

int main(int argc, char *argv[])
{
    stack_init();
    main_loop();
    return 0;
}

 ,

XZentus
()

RSS подписка на новые темы