在类中使用typedef作为自己的struct数据

时间:2013-07-28 21:41:54

标签: c++ class struct typedef

我正在创建一个新课程。该类声明了一个结构变量cs,该变量用于该类的所有函数。类中函数的某些返回变量的类型为cs *。在下面,是CSparse.h

的内容
#ifndef _CSPARSE_H
#define _CSPARSE_H

#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stddef.h>
#ifdef MATLAB_MEX_FILE
#include "mex.h"
#endif
#define CS_VER 3                    /* CSparse Version */
#define CS_SUBVER 1
#define CS_SUBSUB 2
#define CS_DATE "April 16, 2013"    /* CSparse release date */
#define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006-2013"

#ifdef MATLAB_MEX_FILE
#undef csi
#define csi mwSignedIndex
#endif
#ifndef csi
#define csi ptrdiff_t
#endif

class CSparse
{
public:
    CSparse(void);
    virtual ~CSparse(void);

    /* --- primary CSparse routines and data structures ------------------------- */
    typedef struct csparse     /* matrix in compressed-column or triplet form */
    {
        csi nzmax ;     /* maximum number of entries */
        csi m ;         /* number of rows */
        csi n ;         /* number of columns */
        csi *p ;        /* column pointers (size n+1) or col indices (size nzmax) */
        csi *i ;        /* row indices, size nzmax */
        double *x ;     /* numerical values, size nzmax */
        csi nz ;        /* # of entries in triplet matrix, -1 for compressed-col */
    } cs;

    cs    *cs_add (const cs *A, const cs *B, double alpha, double beta) ;
    csi    cs_cholsol (csi order, const cs *A, double *b) ;
    cs    *cs_compress (const cs *T) ;
    csi    cs_dupl (cs *A) ;
    csi    cs_entry (cs *T, csi i, csi j, double x) ;
    csi    cs_gaxpy (const cs *A, const double *x, double *y) ;
    cs    *cs_load (FILE *f) ;
    csi    cs_lusol (csi order, const cs *A, double *b, double tol) ;
    cs    *cs_multiply (const cs *A, const cs *B) ;
    double cs_norm (const cs *A) ;
    csi    cs_print (const cs *A, csi brief) ;
    csi    cs_qrsol (csi order, const cs *A, double *b) ;
    cs    *cs_transpose (const cs *A, csi values) ;

    /* utilities */
    void  *cs_calloc (csi n, size_t size) ;
    void  *cs_free (void *p) ;
    void  *cs_realloc (void *p, csi n, size_t size, csi *ok) ;
    cs    *cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet) ;
    cs    *cs_spfree (cs *A) ;
    csi    cs_sprealloc (cs *A, csi nzmax) ;
    void  *cs_malloc (csi n, size_t size) ;

private:
    /* --- secondary CSparse routines and data structures ----------------------- */
    typedef struct cs_symbolic  /* symbolic Cholesky, LU, or QR analysis */
    {
        csi *pinv ;     /* inverse row perm. for QR, fill red. perm for Chol */
        csi *q ;        /* fill-reducing column permutation for LU and QR */
        csi *parent ;   /* elimination tree for Cholesky and QR */
        csi *cp ;       /* column pointers for Cholesky, row counts for QR */
        csi *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */
        csi m2 ;        /* # of rows for QR, after adding fictitious rows */
        double lnz ;    /* # entries in L for LU or Cholesky; in V for QR */
        double unz ;    /* # entries in U for LU; in R for QR */
    } css;

    typedef struct cs_numeric   /* numeric Cholesky, LU, or QR factorization */
    {
        cs *L ;         /* L for LU and Cholesky, V for QR */
        cs *U ;         /* U for LU, R for QR, not used for Cholesky */
        csi *pinv ;     /* partial pivoting for LU */
        double *B ;     /* beta [0..n-1] for QR */
    } csn;

    typedef struct cs_dmperm     /* cs_dmperm or cs_scc output */
    {
        csi *p ;        /* size m, row permutation */
        csi *q ;        /* size n, column permutation */
        csi *r ;        /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */
        csi *s ;        /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */
        csi nb ;        /* # of blocks in fine dmperm decomposition */
        csi rr [5] ;    /* coarse row decomposition */
        csi cc [5] ;    /* coarse column decomposition */
    } csd;

    csi *cs_amd (csi order, const cs *A) ;
    csn *cs_chol (const cs *A, const css *S) ;
    csd *cs_dmperm (const cs *A, csi seed) ;
    csi  cs_droptol (cs *A, double tol) ;
    csi  cs_dropzeros (cs *A) ;
    csi  cs_happly (const cs *V, csi i, double beta, double *x) ;
    csi  cs_ipvec (const csi *p, const double *b, double *x, csi n) ;
    csi  cs_lsolve (const cs *L, double *x) ;
    csi  cs_ltsolve (const cs *L, double *x) ;
    csn *cs_lu (const cs *A, const css *S, double tol) ;
    cs  *cs_permute (const cs *A, const csi *pinv, const csi *q, csi values) ;
    csi *cs_pinv (const csi *p, csi n) ;
    csi  cs_pvec (const csi *p, const double *b, double *x, csi n) ;
    csn *cs_qr (const cs *A, const css *S) ;
    css *cs_schol (csi order, const cs *A) ;
    css *cs_sqr (csi order, const cs *A, csi qr) ;
    cs  *cs_symperm (const cs *A, const csi *pinv, csi values) ;
    csi  cs_updown (cs *L, csi sigma, const cs *C, const csi *parent) ;
    csi  cs_usolve (const cs *U, double *x) ;
    csi  cs_utsolve (const cs *U, double *x) ;
    /* utilities */
    css *cs_sfree (css *S) ;
    csn *cs_nfree (csn *N) ;
    csd *cs_dfree (csd *D) ;

    /* --- tertiary CSparse routines -------------------------------------------- */
    csi   *cs_counts (const cs *A, const csi *parent, const csi *post, csi ata) ;
    double cs_cumsum (csi *p, csi *c, csi n) ;
    csi    cs_dfs (csi j, cs *G, csi top, csi *xi, csi *pstack, const csi *pinv) ;
    csi    cs_ereach (const cs *A, csi k, const csi *parent, csi *s, csi *w) ;
    csi   *cs_etree (const cs *A, csi ata) ;
    csi    cs_fkeep (cs *A, csi (*fkeep) (csi, csi, double, void *), void *other) ;
    double cs_house (double *x, double *beta, csi n) ;
    csi    cs_leaf (csi i, csi j, const csi *first, csi *maxfirst, csi *prevleaf,
                    csi *ancestor, csi *jleaf) ;
    csi   *cs_maxtrans (const cs *A, csi seed) ;
    csi   *cs_post (const csi *parent, csi n) ;
    csi   *cs_randperm (csi n, csi seed) ;
    csi    cs_reach (cs *G, const cs *B, csi k, csi *xi, const csi *pinv) ;
    csi    cs_scatter (const cs *A, csi j, double beta, csi *w, double *x, csi mark,
                       cs *C, csi nz) ;
    csd   *cs_scc (cs *A) ;
    csi    cs_spsolve (cs *G, const cs *B, csi k, csi *xi, double *x,
        const csi *pinv, csi lo) ;
    csi    cs_tdfs (csi j, csi k, csi *head, const csi *next, csi *post,
                    csi *stack) ;
    /* utilities */
    csd   *cs_dalloc (csi m, csi n) ;
    csd   *cs_ddone (csd *D, cs *C, void *w, csi ok) ;
    cs    *cs_done (cs *C, void *w, void *x, csi ok) ;
    csi   *cs_idone (csi *p, cs *C, void *w, csi ok) ;
    csn   *cs_ndone (csn *N, cs *C, void *w, void *x, csi ok) ;

    #define CS_MAX(a,b) (((a) > (b)) ? (a) : (b))
    #define CS_MIN(a,b) (((a) < (b)) ? (a) : (b))
    #define CS_FLIP(i) (-(i)-2)
    #define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i))
    #define CS_MARKED(w,j) (w [j] < 0)
    #define CS_MARK(w,j) { w [j] = CS_FLIP (w [j]) ; }
    #define CS_CSC(A) (A && (A->nz == -1))
    #define CS_TRIPLET(A) (A && (A->nz >= 0))
};
#endif

以下是CSparse.cpp

的内容
#include "CSparse.h"

CSparse::CSparse(void)
{
}

CSparse::~CSparse(void)
{
}

/* remove duplicate entries from A */
csi CSparse::cs_dupl (cs *A)
{
    csi i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ;
    double *Ax ;
    if (!CS_CSC (A)) return (0) ;               /* check inputs */
    m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ;
    w = (csi* ) cs_malloc (m, sizeof (csi)) ;           /* get workspace */
    if (!w) return (0) ;                        /* out of memory */
    for (i = 0 ; i < m ; i++) w [i] = -1 ;      /* row i not yet seen */
    for (j = 0 ; j < n ; j++)
    {
        q = nz ;                                /* column j will start at q */
        for (p = Ap [j] ; p < Ap [j+1] ; p++)
        {
            i = Ai [p] ;                        /* A(i,j) is nonzero */
            if (w [i] >= q)
            {
                Ax [w [i]] += Ax [p] ;          /* A(i,j) is a duplicate */
            }
            else
            {
                w [i] = nz ;                    /* record where row i occurs */
                Ai [nz] = i ;                   /* keep A(i,j) */
                Ax [nz++] = Ax [p] ;
            }
        }
        Ap [j] = q ;                            /* record start of column j */
    }
    Ap [n] = nz ;                               /* finalize A */
    cs_free (w) ;                               /* free workspace */
    return (cs_sprealloc (A, 0)) ;              /* remove extra space from A */
}

/* C = A' */
cs* CSparse::cs_transpose (const cs *A, csi values) // THIS IS THE LINE WHERE THE FIRST ERROR APPREARS.
{
    csi p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ;
    double *Cx, *Ax ;
    cs *C ;
    if (!CS_CSC (A)) return (NULL) ;    /* check inputs */
    m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ;
    C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ;       /* allocate result */
    w = (csi *) cs_calloc (m, sizeof (csi)) ;                      /* get workspace */
    if (!C || !w) return (cs_done (C, w, NULL, 0)) ;       /* out of memory */
    Cp = C->p ; Ci = C->i ; Cx = C->x ;
    for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ;          /* row counts */
    cs_cumsum (Cp, w, m) ;                                 /* row pointers */
    for (j = 0 ; j < n ; j++)
    {
        for (p = Ap [j] ; p < Ap [j+1] ; p++)
        {
            Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */
            if (Cx) Cx [q] = Ax [p] ;
        }
    }
    return (cs_done (C, w, NULL, 1)) ;  /* success; free w and return C */
}

/* C = compressed-column form of a triplet matrix T */
cs *CSparse::cs_compress (const cs *T)
{
    csi m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ;
    double *Cx, *Tx ;
    cs *C ;
    if (!CS_TRIPLET (T)) return (NULL) ;                /* check inputs */
    m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ;
    C = cs_spalloc (m, n, nz, Tx != NULL, 0) ;          /* allocate result */
    w = (csi *) cs_calloc (n, sizeof (csi)) ;                   /* get workspace */
    if (!C || !w) return (cs_done (C, w, NULL, 0)) ;    /* out of memory */
    Cp = C->p ; Ci = C->i ; Cx = C->x ;
    for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ;           /* column counts */
    cs_cumsum (Cp, w, n) ;                              /* column pointers */
    for (k = 0 ; k < nz ; k++)
    {
        Ci [p = w [Tj [k]]++] = Ti [k] ;    /* A(i,j) is the pth entry in C */
        if (Cx) Cx [p] = Tx [k] ;
    }
    return (cs_done (C, w, NULL, 1)) ;      /* success; free w and return C */
}


/* allocate a sparse matrix (triplet form or compressed-column form) */
cs *CSparse::cs_spalloc (csi m, csi n, csi nzmax, csi values, csi triplet)
{
    cs *A = (cs *) cs_calloc (1, sizeof (cs)) ;    /* allocate the cs struct */
    if (!A) return (NULL) ;                 /* out of memory */
    A->m = m ;                              /* define dimensions and nzmax */
    A->n = n ;
    A->nzmax = nzmax = CS_MAX (nzmax, 1) ;
    A->nz = triplet ? 0 : -1 ;              /* allocate triplet or comp.col */
    A->p = (csi *) cs_malloc (triplet ? nzmax : n+1, sizeof (csi)) ;
    A->i = (csi *) cs_malloc (nzmax, sizeof (csi)) ;
    A->x = values ? (double *) cs_malloc (nzmax, sizeof (double)) : NULL ;
    return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ;
}

/* change the max # of entries sparse matrix */
csi CSparse::cs_sprealloc (cs *A, csi nzmax)
{
    csi ok, oki, okj = 1, okx = 1 ;
    if (!A) return (0) ;
    if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ;
    A->i = (csi *) cs_realloc (A->i, nzmax, sizeof (csi), &oki) ;
    if (CS_TRIPLET (A)) A->p = (csi *) cs_realloc (A->p, nzmax, sizeof (csi), &okj) ;
    if (A->x) A->x = (double *) cs_realloc (A->x, nzmax, sizeof (double), &okx) ;
    ok = (oki && okj && okx) ;
    if (ok) A->nzmax = nzmax ;
    return (ok) ;
}

/* free a sparse matrix */
cs *CSparse::cs_spfree (cs *A)
{
    if (!A) return (NULL) ;     /* do nothing if A already NULL */
    cs_free (A->p) ;
    cs_free (A->i) ;
    cs_free (A->x) ;
    return ((cs *) cs_free (A)) ;   /* free the cs struct and return NULL */
}

/* free a numeric factorization */
csn *CSparse::cs_nfree (csn *N)
{
    if (!N) return (NULL) ;     /* do nothing if N already NULL */
    cs_spfree (N->L) ;
    cs_spfree (N->U) ;
    cs_free (N->pinv) ;
    cs_free (N->B) ;
    return ((csn *) cs_free (N)) ;  /* free the csn struct and return NULL */
}

/* free a symbolic factorization */
css *CSparse::cs_sfree (css *S)
{
    if (!S) return (NULL) ;     /* do nothing if S already NULL */
    cs_free (S->pinv) ;
    cs_free (S->q) ;
    cs_free (S->parent) ;
    cs_free (S->cp) ;
    cs_free (S->leftmost) ;
    return ((css *) cs_free (S)) ;  /* free the css struct and return NULL */
}

/* allocate a cs_dmperm or cs_scc result */
csd *CSparse::cs_dalloc (csi m, csi n)
{
    csd *D ;
    D = (csd *) cs_calloc (1, sizeof (csd)) ;
    if (!D) return (NULL) ;
    D->p = (csi *) cs_malloc (m, sizeof (csi)) ;
    D->r = (csi *) cs_malloc (m+6, sizeof (csi)) ;
    D->q = (csi *) cs_malloc (n, sizeof (csi)) ;
    D->s = (csi *) cs_malloc (n+6, sizeof (csi)) ;
    return ((!D->p || !D->r || !D->q || !D->s) ? cs_dfree (D) : D) ;
}

/* free a cs_dmperm or cs_scc result */
csd *CSparse::cs_dfree (csd *D)
{
    if (!D) return (NULL) ;     /* do nothing if D already NULL */
    cs_free (D->p) ;
    cs_free (D->q) ;
    cs_free (D->r) ;
    cs_free (D->s) ;
    return ((csd *) cs_free (D)) ;  /* free the csd struct and return NULL */
}

/* free workspace and return a sparse matrix result */
cs *CSparse::cs_done (cs *C, void *w, void *x, csi ok)
{
    cs_free (w) ;                       /* free workspace */
    cs_free (x) ;
    return (ok ? C : cs_spfree (C)) ;   /* return result if OK, else free it */
}

/* free workspace and return csi array result */
csi *CSparse::cs_idone (csi *p, cs *C, void *w, csi ok)
{
    cs_spfree (C) ;                     /* free temporary matrix */
    cs_free (w) ;                       /* free workspace */
    return (ok ? p : (csi *) cs_free (p)) ; /* return result, or free it */
}

/* free workspace and return a numeric factorization (Cholesky, LU, or QR) */
csn *CSparse::cs_ndone (csn *N, cs *C, void *w, void *x, csi ok)
{
    cs_spfree (C) ;                     /* free temporary matrix */
    cs_free (w) ;                       /* free workspace */
    cs_free (x) ;
    return (ok ? N : cs_nfree (N)) ;    /* return result if OK, else free it */
}

/* free workspace and return a csd result */
csd *CSparse::cs_ddone (csd *D, cs *C, void *w, csi ok)
{
    cs_spfree (C) ;                     /* free temporary matrix */
    cs_free (w) ;                       /* free workspace */
    return (ok ? D : cs_dfree (D)) ;    /* return result if OK, else free it */
}

/* wrapper for malloc */
void *CSparse::cs_malloc (csi n, size_t size)
{
    return (malloc (CS_MAX (n,1) * size)) ;
}

/* wrapper for calloc */
void *CSparse::cs_calloc (csi n, size_t size)
{
    return (calloc (CS_MAX (n,1), size)) ;
}

/* wrapper for free */
void *CSparse::cs_free (void *p)
{
    if (p) free (p) ;       /* free p if it is not already NULL */
    return (NULL) ;         /* return NULL to simplify the use of cs_free */
}

/* wrapper for realloc */
void *CSparse::cs_realloc (void *p, csi n, size_t size, csi *ok)
{
    void *pnew ;
    pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */
    *ok = (pnew != NULL) ;                  /* realloc fails if pnew is NULL */
    return ((*ok) ? pnew : p) ;             /* return original p if failure */
}

/* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */
double CSparse::cs_cumsum (csi *p, csi *c, csi n)
{
    csi i, nz = 0 ;
    double nz2 = 0 ;
    if (!p || !c) return (-1) ;     /* check inputs */
    for (i = 0 ; i < n ; i++)
    {
        p [i] = nz ;
        nz += c [i] ;
        nz2 += c [i] ;              /* also in double to avoid csi overflow */
        c [i] = p [i] ;             /* also copy p[0..n-1] back into c[0..n-1]*/
    }
    p [n] = nz ;
    return (nz2) ;                  /* return sum (c [0..n-1]) */
}

/* C = alpha*A + beta*B */
cs *CSparse::cs_add (const cs *A, const cs *B, double alpha, double beta)
{
    csi p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ;
    double *x, *Bx, *Cx ;
    cs *C ;
    if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ;         /* check inputs */
    if (A->m != B->m || A->n != B->n) return (NULL) ;
    m = A->m ; anz = A->p [A->n] ;
    n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ;
    w = (csi *) cs_calloc (m, sizeof (csi)) ;                       /* get workspace */
    values = (A->x != NULL) && (Bx != NULL) ;
    x = values ? (double *) cs_malloc (m, sizeof (double)) : NULL ;    /* get workspace */
    C = cs_spalloc (m, n, anz + bnz, values, 0) ;           /* allocate result*/
    if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ;
    Cp = C->p ; Ci = C->i ; Cx = C->x ;
    for (j = 0 ; j < n ; j++)
    {
        Cp [j] = nz ;                   /* column j of C starts here */
        nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ;   /* alpha*A(:,j)*/
        nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ;    /* beta*B(:,j) */
        if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ;
    }
    Cp [n] = nz ;                       /* finalize the last column of C */
    cs_sprealloc (C, 0) ;               /* remove extra space from C */
    return (cs_done (C, w, x, 1)) ;     /* success; free workspace, return C */
}

我得到的第一个错误如下。

1>.\CSparse.cpp(46) : error C2143: syntax error : missing ';' before '*'

我在上面的源代码中标记了错误位置。它发生在cs* CSparse::cs_transpose (const cs *A, csi values)的定义中。

在线搜索后,我发现这是typedef范围的问题。因此,我必须在CSparse.cpp中调整返回的函数类型。例如,我改变了

cs* CSparse::cs_transpose (const cs *A, csi values)

CSparse::cs* CSparse::cs_transpose (const cs *A, csi values)

它工作正常。有没有更好的方法呢?为什么这个问题是函数和函数参数的返回变量不会导致任何问题。例如,在函数cs_transpose中,A以及函数返回变量的类型为cs,但只有函数返回才会导致编译器抱怨。另外,由于某些原因,我无法使用using namespace

有人可以帮我找到解决这个问题的正确方法吗?

1 个答案:

答案 0 :(得分:1)

在我看来,你刚刚在班级myClass的末尾忘记了;

除此之外,你不需要输入你的结构,它可能是:

struct ms {
    double d;
    double* pd;
};

ms *myfunction(void);