C 结构指针参数

C 结构指针参数,c,structure,C,Structure,我很难在不重写的情况下移动结构 typedef struct listaC { int coluna; float valor; struct listaC *prox; } *Colunas; typedef struct listaL { int linha; Colunas lcol; struct listaL *prox; } *Mat; 在我的函数中,我试图添加2个矩阵 void addTo (Mat *m1, Mat m2){ if(m2==NULL)

我很难在不重写的情况下移动结构

typedef struct listaC {
int coluna;
float valor;
struct listaC *prox;
} *Colunas;

typedef struct listaL {
    int linha;
    Colunas lcol;
struct listaL *prox;
} *Mat;
在我的函数中,我试图添加2个矩阵

void addTo (Mat *m1, Mat m2){
    if(m2==NULL) return;
    if(m1==NULL) m1 = &m2;
    while(*m1!=NULL)
    {
        while((*m1)->lcol!=NULL)
        (*m1)->lcol->valor += m2->lcol->valor;
        m2->lcol=m2->lcol->prox;
    //here  m1->lcol = &((*m1)->lcol->prox);
    }
    m2 =m2->prox;
    m1 = &((*m1)->prox);
    *m1 = *m1->prox;
}
但是我在

m1->lcol = &((*m1)->lcol->prox);
错误:请求非结构或联合中的成员“lcol” m1->lcol=&(*m1)->lcol->prox)

我应该如何修复此问题?

m1->lcol = &((*m1)->lcol->prox);
对于左侧,m1是指向指针的指针。要使用->命令,您需要是一个指针

(*m1)->lcol
另外,在右边,&使其成为指向prox的指针的地址,而您只需要指针本身

(*m1)->lcol = ((*m1)->lcol->prox);

在其他点上,while(*m1!=NULL)实际上是一个无止境的循环,因为m1从不检查进入循环的循环,m1是指向Mat的指针,所以是指向struct的指针。赋值的右侧正确,但左侧缺少解引用:

(*m1)->lcol = (*m1)->lcol->prox;

我还删除了从右边获取地址的
&
,因为prox已经是一个指针。

语法的复杂性使您忘记了在赋值的左侧取消引用变量m1

(*m1)->lcol
m1->lcol = &((*m1)->lcol->prox);      // causes the error m1 is a ListaL**
(*m1)->lcol = &((*m1)->lcol->prox);   // this should compile.
另外,我想我在这行代码中发现了一个bug。既然m1是一个链表,add不会改变行和列的顺序,而只改变它们的内容,那么对链接指针进行任何更改都不会导致错误吗

// this would make add look something like this:

// void add(Mat *m1, Mat m2)  why the added * complexity.
void add(Mat m1, Mat m2)
{
  struct listaL* proxL1;
  struct listaL* proxL2;
  struct listaC* proxC1;
  struct listaC* proxC2;

  if(m2==NULL) return;
  //if(m1==NULL) m1 = &m2; // Appropriate here?  Is this the right 
                           // place to do this?  Not part of add
                           // definition.. no return, so effect is 
                           // *m1 = m2 = 2.m2 
                           // you should consider simply passing a Mat
                           // and checking for NULL
  if (m1 == NULL) return; 

  for (proxL1 = m1, proxL2 = m2; 
       proxL1 != 0 && proxL2 != 0; 
       proxL1 = proxL1->prox, proxL2 = proxL2->prox)
  {
    for (proxC1 = proxL1->lcol, proxC2 = proxL2->lcol;
         proxC1 != 0  && proxC2 != 0; 
         proxC1 = proxC1->prox, proxC2 = proxC2->prox)
    {
      proxC1->valor += proxC2->valor;
    }
  }
  // values have been added.... done!  
}
我认为你应该在早上睡个好觉,喝杯浓咖啡后再做乘法运算:)

提示:对于矩阵来说,也许链表不是最好的方法,而一个简单的双浮点malloc’ed数组就可以做到这一点

像这样的事情要简单得多,不是吗

typedef struct Mat 
{
  int rows;
  int cols;
  float data[1];
};
// useful for random access
#define MAT_AT(m, r, c) ((m)->data + ((r) * (m)->cols) + (c))
// useful for malloc, copy
#define MAT_SIZEOF(r, c) (sizeof(struct Mat) + (sizeof(float) * (((r) * (c)) - 1)))

// makes for an api that is much faster and efficient

struct Mat* matalloc(int r, int c)
{
  struct Mat* m = (struct Mat*)malloc(MAT_SIZEOF(r, c));
  if (m == 0) return 0;
  m->rows = r;
  m->cols = c;
  memset(m->data, 0, sizeof(float) * r * c); 
  return m
}

void matfree(struct Mat* m)
{
  free(m);
}

struct Mat* matadd(struct Mat* r, struct Mat* a, struct Mat* b)
{
  int i, j;
  assert(a && b && r 
         && a->rows == b->rows && a->cols == b->cols 
         && a->rows == r->rows && a->cols == r->cols);
  for (i = 0; i < a->rows; ++i)
    for (j = 0; j < a->cols; ++j)
      *MAT_AT(r, i, j) = *MAT_AT(a, i, j) + *MAT_AT(b, i, j);
  return r;
}

struct Mat* mataddto(struct Mat* r, struct Mat* a)
{
  return matadd(r, r, a);
}
typedef结构材料
{
int行;
int cols;
浮动数据[1];
};
//用于随机访问
#在(m,r,c)((m)->data+((r)*(m)->cols)+(c))定义MAT_
//对malloc有用,复制
#定义MAT_SIZEOF(r,c)(SIZEOF(struct MAT)+(SIZEOF(float)*((r)*(c))-1)))
//使api更快、更高效
结构材料*材料(内部r,内部c)
{
struct Mat*m=(struct Mat*)malloc(Mat_SIZEOF(r,c));
如果(m==0)返回0;
m->rows=r;
m->cols=c;
memset(m->data,0,sizeof(float)*r*c);
返回m
}
无空隙材料(结构材料*m)
{
自由(m);
}
结构材料*matadd(结构材料*r、结构材料*a、结构材料*b)
{
int i,j;
断言(a&&b&&r)
&&a->rows==b->rows&&a->cols==b->cols
&&a->rows==r->rows&&a->cols==r->cols);
对于(i=0;irows;++i)
对于(j=0;jcols;++j)
*(r,i,j)=(a,i,j)+(b,i,j)的MAT_;
返回r;
}
结构材料*mataddto(结构材料*r,结构材料*a)
{
返回matadd(r,r,a);
}

永远不要在typedef后面隐藏指针。这很可能是你所有问题的根源。不要因为把不同的东西命名得太相似而混淆你自己。m1是指向Map的指针,它本身就是指向struct的指针的typedef。所以m1是指向结构的指针…它会像这样重写指针指向的内容吗?因为我需要保留matrix@RyzonPT:函数实际上尝试将第二个矩阵添加到第一个矩阵。这个答案只修复了语法错误。是的,但是我想更改指针的地址,这样我就可以在不破坏结构的情况下在结构中“移动”,我通常会执行m=&((*m)->prox);这是可行的,但当我尝试m->lcol=&(*m)->lcol->prox时;它确实发出了。。这是我的问题…@RyzonPT:你是对的,算法有缺陷。您需要临时变量来避免更改
(*m1)->col
m2->col
-对于
m2
也会出现同样的问题,您能给我举个例子吗?