⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdlib.c

📁 一款标准c类库.Tima(TM-Tiny&Miny) Standard ANSI C based Library
💻 C
📖 第 1 页 / 共 2 页
字号:
        acc = ULONG_MAX;
        errno = ERANGE;
    } else if (neg)
        acc = -acc;
    if (endptr != 0)
        *endptr = (char *) (any ? s - 1 : nptr);

    return (acc);
}



/***************************************
 *
 *    Math function
 *
 ***************************************/

/**
 * abs - compute the absolute value of an integer
 */
int abs(int j){
    return j < 0 ? -j : j;
}

/**
 * labs - compute the absolute value of an integer
 */
long int labs(long int j){
    return j < 0 ? -j : j;
}

/**
 * llabs - compute the absolute value of an integer
 */
long long int llabs(long long int j){
    return j < 0 ? -j : j;
}



/***************************************
 *
 * Data Structure and Algorithm function
 *
 ***************************************/

/**
 * bsearch - binary search of a sorted array
 *
 * @desc The function searches an array of nmemb objects, the initial member of which is pointed to by base, for a member 
 *		 that matches the object pointed to by key.  The size of each member of the array is specified by size
 * @return The function returns a pointer to a matching member of the array, or NULL if no match is  found. If there are 
 *		   multiple elements that match the key, the element returned is unspecified.
 */
void *bsearch (const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){
    size_t l, u, idx;
    const void *p;
    int comparison;

    l = 0;
    u = nmemb;
    while (l < u){
        idx = (l + u) / 2;
        p = (void *) (((const char *) base) + (idx * size));
        comparison = (*compar) (key, p);
        if (comparison < 0)
            u = idx;
        else if (comparison > 0)
            l = idx + 1;
        else
            return (void *) p;
    }

    return NULL;
}


/**
 * swap - swap two variables (for qsort)
 */
static void swap(void *base, size_t i, size_t j, size_t size){
    void *tmp = malloc(size);

    memcpy(tmp, (char *)base + i * size, size);
    memmove((char *)base + i * size, (char *)base + j * size, size);
    memcpy((char *)base + j * size, tmp, size);
    free(tmp);
}

/**
 * qsort - sorts an array
 *
 * @desc The function sorts an array with nmemb elements of size size.  The base argument points to the start of
 *		 the array
 * @return The function returns no value
 */
void qsort(void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *)){
    int i, last;

    if (nmemb <= 1)
        return;

    swap(base, 0, nmemb / 2, size);

    last = 0;
    for (i = 1; i < nmemb; i++)
        if (compar((char *)base + (i * size), base) < 0)
            swap(base, i, ++last, size);

    swap(base, 0, last, size);

    qsort(base, last, size, compar);
    qsort((char *)base + (last + 1) * size, nmemb - last - 1, size, compar);
}


/**
 * srand - pseudo-random number generator
 *
 * @desc The function sets its argument as the seed for a new sequence of pseudo-random integers to be returned
 *       by rand().  These sequences are repeatable by calling srand() with the same seed value.
 *       If no seed value is provided, the rand() function is automatically seeded with a value of 1
 * @return The function returns no value
 */
void srand(unsigned int seed){
    __rand_next__ = seed;
}


/**
 * rand - pseudo-random number generator
 *
 * @desc The function returns a pseudo-random integer between 0 and RAND_MAX.
 * @return The functions return a value between 0 and  RAND_MAX.
 */
int rand(void){
    __rand_next__ = __rand_next__ * 1103515245 + 12345;
    return (unsigned int)(__rand_next__ / 65536) % 32768;
}


/**
 * rand - pseudo-random number generator
 *
 * @desc The function is supplied with a pointer to an unsigned int, to be used as state. This is a very small amount of
 *       state, so this function will be a weak pseudo-random generator.
 * @return The functions return a value between 0 and  RAND_MAX.
 */
int rand_r(unsigned int *seed){
    unsigned int next = *seed;
    int result;

    next *= 1103515245;
    next += 12345;
    result = (unsigned int) (next / 65536) % 2048;

    next *= 1103515245;
    next += 12345;
    result <<= 10;
    result ^= (unsigned int) (next / 65536) % 1024;

    next *= 1103515245;
    next += 12345;
    result <<= 10;
    result ^= (unsigned int) (next / 65536) % 1024;

    *seed = next;

    return result;
}



/***************************************
 *
 *   Memory control function
 *
 ***************************************/

/**
 * morecore - ask system for more memory (for malloc)
 *
 * @desc system implement (like UNIX os use sbrk() alloc data segment)
 */
static Header *morecore(size_t nu){
    char *cp, *sbrk(int);
    Header *up;
    if (nu < NALLOC)
        nu = NALLOC;
    cp = sbrk(nu * sizeof(Header));
    if (cp == (char *) -1) /* no space at all */
        return NULL;
    up = (Header *) cp;
    up->s.size = nu;
    free((void *)(up+1));
    return freep;
}

/**
 * malloc - Allocate dynamic memory
 *
 * @desc malloc() allocates  size  bytes and returns a pointer to the allocated memory.  The memory is not cleared. If
 *       size is 0, then malloc() returns either NULL, or a unique pointer value that can later be  successfully  passed
 *       to free().
 * @return malloc(), the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of 
 *		   variable, or NULL if the request fails.
 */
void *malloc(size_t size){
    size_t nbytes = size;
    Header *p, *prevp;
    size_t nunits;

    nunits = (nbytes+sizeof(Header)-1)/sizeof(header) + 1;
    if ((prevp = freep) == NULL) { /* no free list yet */
        base.s.ptr = freeptr = prevptr = &base;
        base.s.size = 0;
    }
    for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {
        if (p->s.size >= nunits) { /* big enough */
            if (p->s.size == nunits) /* exactly */
                prevp->s.ptr = p->s.ptr;
            else { /* allocate tail end */
                p->s.size -= nunits;
                p += p->s.size;
                p->s.size = nunits;
            }
            freep = prevp;
            return (void *)(p+1);
        }
        if (p == freep) /* wrapped around free list */
            if ((p = morecore(nunits)) == NULL)
                return NULL; /* none left */
    }
}

/**
 * free - Free dynamic memory
 *
 * @desc free()  frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(),
 *       calloc() or realloc().  Otherwise, or if free(ptr) has already been called before, undefined  behavior  occurs.
 *       If ptr is NULL, no operation is performed.
 * @return free() returns no value
 */
void free(void *ptr){
    Header *bp, *p;
    void *ap = ptr;

    bp = (Header *)ap - 1; /* point to block header */
    for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
        if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
            break; /* freed block at start or end of arena */
    if (bp + bp->size == p->s.ptr) { /* join to upper nbr */
        bp->s.size += p->s.ptr->s.size;
        bp->s.ptr = p->s.ptr->s.ptr;
    } else
        bp->s.ptr = p->s.ptr;
    if (p + p->size == bp) { /* join to lower nbr */
        p->s.size += bp->s.size;
        p->s.ptr = bp->s.ptr;
    } else
        p->s.ptr = bp;
    freep = p;
}

/**
 * calloc - Allocate dynamic memory
 *
 * @desc calloc()  allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allo-
 *       cated memory.  The memory is set to zero.  If nmemb or size is 0, then  calloc()  returns  either  NULL,  or  a
 *       unique pointer value that can later be successfully passed to free().
 * @return the value returned is a pointer to the allocated memory, which is suitably aligned for any kind of variable, 
 *		   or NULL if the request fails.
 */
void *calloc(size_t nmemb, size_t size){
    void *ptr;

    ptr = malloc(nmemb * size);
    if (ptr)
        memset(ptr, '\0', nmemb * size);
    return ptr;
}


/**
 * realloc - Allocate dynamic memory
 *
 * @desc realloc() changes the size of the memory block pointed to by ptr to size bytes.  The contents will be unchanged
 *       to the minimum of the old and new sizes; newly allocated memory will be uninitialized.  If  ptr  is  NULL,  the
 *       call  is equivalent to malloc(size); if size is equal to zero, the call is equivalent to free(ptr).  Unless ptr
 *       is NULL, it must have been returned by an earlier call to malloc(), calloc() or realloc().  If the area pointed
 *       to was moved, a free(ptr) is done.
 * @return realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind  of  variable
 *         and  may be different from ptr, or NULL if the request fails.  If size was equal to 0, either NULL or a pointer
 *         suitable to be passed to free() is returned.  If realloc() fails the original block is left  untouched;  it  is
 *         not freed or moved.
 */
void *realloc(void *ptr, size_t size){
    Header *bp;
    void *new_ptr;
    size_t old_size;

    if (ptr == NULL)
        return malloc(size);
    bp = (Header *)ptr - 1;     /* point to block header */
    old_size = sizeof(Header) * (bp->s.size - 1);
    new_ptr = malloc(size);
    if (new_ptr == NULL) {
        return NULL;
    }
    if (old_size <= size) {
        memcpy(new_ptr, ptr, old_size);
    } else {
        memcpy(new_ptr, ptr, size);
    }
    free(ptr);
    return new_ptr;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -