#include <xxalloc.h>
cc
[flags] files
-lxxalloc [-lxxerror]
[libraries]
Base Routines
void xx_error(s)
char *s;
char *xx_alloc(n)
unsigned n;
void xx_free(p, n)
char *p;
unsigned n;
long xx_amount()
Prefixes and Arguments
{type} - char - short - long - int - float - double
{*} - * - ** - *** for 1 - 2 - 3 dimensions
{t} - c - s - l - i - f - d
{d} - 1 - 2 - 3
{args} - ib,ie - ib,ie,jb,je - ib,ie,jb,je,kb,ke
Functions for Simple Types
{type} {*}{t}{d}_alloc({args})
int {args};
void {t}{d}_init(m, {args}, ini)
{type} {*}m;
int {args};
{type} ini;
void {t}{d}_prnt(fp, fmt, m, {args})
FILE *fp;
char *fmt;
{type} {*}m;
int {args};
{type} {*}{t}{d}_renum(m, {args}, {args})
{type} {*}m;
int {args}, {args};
void {t}{d}_free(m, {args})
{type} {*}m;
int {args};
Functions for Structures
char {*}n{d}_alloc({args}, n)
int {args}, n;
void n{d}_init(m, {args}, n, nini)
char {*}m;
int {args}, n;
void (*nini)();
void n{d}_prnt(fp, nprn, m, {args}, n)
FILE *fp;
void (*nprn)();
char {*}m;
int {args}, n;
char {*}n{d}_renum(m, {args}, {args}, n)
char {*}m;
int {args}, {args}, n;
void n{d}_free(m, {args}, n)
char {*}m;
int {args}, n;
xxalloc is a family of routines for dynamic array manipulation in one, two and three dimensions. Routines are included for allocation, initialization, printing, renumbering, and freeing both arrays of structures and arrays of simple types. Since the "edge-vector" approach is used for two and three dimensional arrays, this set of routines allows for the development of reusable subroutine libraries without regard to some "maximum" dimension. Both positive and negative indices are allowed. In this document "array of" is often used where "pointer to" would be more correct.
Base Routines
The default routine is simply
#include <stdio.h>
void xx_error(s)
char *s;
{
fprintf(stderr, s);
exit(2);
return;
}
The suffix on the function name indicates its function. The five function types are
The prefix on the function name indicates its type. They are
Arguments common to both functions that operate on simple types and structures.
Arguments to functions that operate on simple types.
Arguments to functions that operate on structures.
void initialize_some_structure(some_struct)
struct *some_struct;
void print_some_structure(fp, some_struct)
FILE *fp;
struct *some_struct;
Example1 - Operations on a two dimensional array of doubles
/* example1.c */
#include <stdio.h>
#include <xxalloc.h>
void mtxtsp(a, ib, ie, jb, je, b)
double **a, **b;
int ib, ie, jb, je;
{
int i, j;
double tmp;
for (i = ib; i <= ie; i++)
for (j = i; j <= je; j++)
{
tmp = a[i][j];
b[i][j] = a[j][i];
b[j][i] = tmp;
}
return;
}
main()
{
double **a;
int i, j;
/* allocate a two dimensional array of doubles */
a = d2_alloc(0, 9, 0, 9);
/* initialize the array to 1.0 and print */
d2_init(a, 0, 9, 0, 9, 1.0);
printf("\ninitialized to 1\n");
d2_prnt(stdout, "%5.0f ", a, 0, 9, 0, 9);
/* set the array equal to the 2*i + j and print */
for (i = 0; i < 10; i++)
for (j = 0; j < 10; j++)
a[i][j] = (double) (2*i + j);
printf("\n2*i + j\n");
d2_prnt(stdout, "%5.0f ", a, 0, 9, 0, 9);
/* take the transpose and print*/
mtxtsp(a, 0, 9, 0, 9, a);
printf("\ntransposed\n");
d2_prnt(stdout, "%5.0f ", a, 0, 9, 0, 9);
/* renumber the indices a la FORTRAN and print */
/* the new indices must be used from now on */
a = d2_renum(a, 0, 9, 0, 9, 1, 10, 1, 10);
printf("\nrenumbered\n");
d2_prnt(stdout, "%5.0f ", a, 1, 10, 1, 10);
/* renumber the indices a la C and print */
/* the new indices must be used from now on */
a = d2_renum(a, 1, 10, 1, 10, 0, 9, 0, 9);
printf("\nrenumbered again\n");
d2_prnt(stdout, "%5.0f ", a, 0, 9, 0, 9);
/* free the allocated memory */
d2_free(a, 0, 9, 0, 9);
exit(0);
}
Example 2 - Operations on an array of structures
/* example2.c */
#include <stdio.h>
#include <xxalloc.h>
typedef struct
{
double dnum;
int inum;
} NUM;
/* structure initialization function */
/* passed as an argument to {d}n_init() */
void num_init(num)
NUM *num;
{
num->dnum = 1.0;
num->inum = 1;
return;
}
/* structure printing function */
/* passed as an argument to {d}n_prnt() */
void num_prnt(fp, num)
FILE *fp;
NUM *num;
{
fprintf(fp, "%5.1f %3d ", num->dnum, num->inum);
return;
}
main()
{
int i;
NUM *num;
/* allocate a one dimensional array of NUM */
num = (NUM *) n1_alloc(0, 4, sizeof(NUM));
/* initialize the array to 1.0 and print */
n1_init(num, 0, 4, sizeof(NUM), num_init);
printf("\ninitialized to 1\n");
n1_prnt(stdout, num_prnt, num, 0, 4, sizeof(NUM));
/* set the array equal to the i and print */
for (i = 0; i <= 4; i++)
{
num[i].dnum = (double) i;
num[i].inum = i;
}
printf("\nset to i\n");
n1_prnt(stdout, num_prnt, num, 0, 4, sizeof(NUM));
/* renumber the indices a la FORTRAN and print */
/* the new indices must be used from now on */
num = (NUM *) n1_renum(num, 0, 4, 1, 5, sizeof(NUM));
printf("\nindices renumbered\n");
n1_prnt(stdout, num_prnt, num, 1, 5, sizeof(NUM));
printf("\n");
/* free the allocated memory */
n1_free(num, 1, 5, sizeof(NUM));
exit(0);
}
There is only minimal error checking and no error checking at all between function calls.
Harold G. Walters