首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >解决办法: ISO C90禁止可变长度数组

解决办法: ISO C90禁止可变长度数组
EN

Stack Overflow用户
提问于 2015-03-24 08:14:38
回答 1查看 2K关注 0票数 1

我正在读取一个名为reg.dat的文件,并将每列中的第一个变量设置为变量Y的索引,将每列中的其余变量设置为X的索引。然后,我希望将X和Y输入dgesv函数,以计算线性回归。

我的代码如下(块,因为我不能一次把它全部包含在这个网站上)。运行gcc -ansi -pedantic readReg.c -o readReg -llapack -lblas -lgfortran时遇到的错误如下所示:

代码语言:javascript
运行
复制
readReg.c: In function ‘main’:
readReg.c:18: warning: ISO C90 forbids variable length array ‘ipiv’
readReg.c:19: warning: ISO C90 forbids variable length array ‘X1’
readReg.c:19: warning: ISO C90 forbids variable length array ‘X1’
readReg.c:19: warning: ISO C90 forbids variable length array ‘XtX’
readReg.c:19: warning: ISO C90 forbids variable length array ‘XtY’
readReg.c:48: error: subscripted value is neither array nor pointer

例如,如果文件reg.dat是:

代码语言:javascript
运行
复制
5.1 3.5 1.4
4.9 3 1.4
4.7 3.2 1.3
4.6 3.1 1.5
5 3.6 1.4

然后X= 5.1、4.9、4.7、4.6、5和Y= 3.5、1.4、3、1.4、3.2、1.3、3.1、1.5、3.6、1.4

代码语言:javascript
运行
复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int getCol(char *myStr);
int getRow(char *fileName);
int assignY(int nCol, int nRow, double *Y, char *fileName);
int assignX(int nCol, int nRow, double *X, char *fileName);
void dgesv_(int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);

int main(){
   FILE *f;
   char myStr[1000];
   int strL;
   int nCol;
   int nRow;
   char *fileName = "reg.dat";
   int i, j, k, n1=nCol, n2=1, ipiv[nCol], info;
   double X1[nRow][nCol], XtX[(nCol) * (nCol)], XtY[nCol];

   double *X;
   double *Y;

   f = fopen(fileName, "r");
   if (f == NULL) perror ("Error opening file");
   else {
     if (fgets(myStr, 1000, f) != NULL ) 
       puts(myStr); 
     fclose(f);
   }     

   strL = strlen(myStr);
   nCol = getCol(myStr);
   nRow = getRow(fileName);
   printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);

   X = (double *) malloc(sizeof(double) * ((nCol-1) * nRow));
   Y = (double *) malloc(sizeof(double) * nRow);
   assignY(nCol, nRow, Y, fileName);
   assignX(nCol, nRow, X, fileName);

接下来我操纵X和Y..。

代码语言:javascript
运行
复制
   /* The following is for doing the dgesv function */

  /* design matrix */
  for (i=0; i<nRow; i++){
    X1[i][0] = 1;
    for (j=1; j<n1; j++)
      X1[i][j] = X[i][j-1];
  }

  /* t(X1) %*% X1 */
  for (i=0; i<n1; i++){
    for (j=0; j<n1; j++){
      XtX[i*n1+j] = 0;
      for (k=0; k<nRow; k++)
        XtX[i*n1+j] += X1[k][i] * X1[k][j];
    }
  }

  /* t(X1) %*% Y */
  for (i=0; i<n1; i++){
    XtY[i] = 0;
    for (j=0; j<nRow; j++){
      XtY[i] += X1[j][i] * Y[j];
    }
  }

接下来我打印结果

代码语言:javascript
运行
复制
  /* XtX is symmetric, no transpose needed before passing to Fortran subrountine */
  dgesv_(&n1, &n2, XtX, &n1, ipiv, XtY, &n1, &info);
  if (info!=0)  printf("failure with error %d\n", info);

  /* print beta */
  printf("The regression coefficients: ");
  for (i=0; i<n1; i++){
    printf("%f ", XtY[i]);
  }
  printf("\n");

   return 0;
}

助手函数..。

代码语言:javascript
运行
复制
int assignY(int nCol, int nRow, double *Y, char *fileName){
  int i=0;
  int j;
  char string[1000];
  char* data = NULL;
  FILE *f;
  f = fopen(fileName, "r");

  while(fgets(string, sizeof(string), f) != NULL){
    data = strtok(string, " ");
    for (j=0; NULL != data && j<nCol; j++){
        if (data[strlen(data) - 1] == '\n')
            data[strlen(data) - 1] = '\0';

        if (j==0){
          Y[i] = atof(data);
          i++;
        }
        data = strtok(NULL, " ");
    }
  }

  for (i=0;i<nRow;i++){
    printf("%f\n", Y[i]);
  }
  return 0;
}

助手函数..。

代码语言:javascript
运行
复制
int assignX(int nCol, int nRow, double *X, char *fileName){
  int i=0;
  int j;
  char string[1000];
  char* data = NULL;
  FILE *f;
  f = fopen(fileName, "r");

  while(fgets(string, sizeof(string), f) != NULL){
    data = strtok(string, " ");
    for (j=0; NULL != data && j<nCol; j++){
        if (data[strlen(data) - 1] == '\n')
            data[strlen(data) - 1] = '\0';

        if (j!=0){
          X[i] = atof(data);
          i++;
        }
        data = strtok(NULL, " ");
    }
  }

  for (i=0;i<(nRow*(nCol-1));i++){
    printf("%f\n", X[i]);
  }
  return 0;
}

助手函数..。

代码语言:javascript
运行
复制
int getCol(char *myStr){
    int length,i,count=0;
    char prev;
    length=strlen(myStr);
    if(length > 0){
      prev = myStr[0];
    }
    for(i=0; i<=length; i++){
      if(myStr[i]==' ' && prev != ' '){
        count++;
      }
      prev = myStr[i];
    }
    if(count > 0 && myStr[i] != ' '){
        count++;
    }
    return count;
}

int getRow(char *fileName){
  char ch;
  int count=0;
  FILE *f;
  f = fopen(fileName, "r");

  while(!feof(f)){
    ch = fgetc(f);
    if(ch == '\n')
    {
      count++;
    }
  }
fclose(f);
return count;
} 

编辑:

我现在更改为X1、XtY、XtX和ipiv的malloc()。我现在还为X1使用了多维动态数组。当我跑gcc的时候,所有的错误都消失了,除了:

代码语言:javascript
运行
复制
readReg.c: In function ‘main’:
readReg.c:62: error: subscripted value is neither array nor pointer

以下是最新的主要职能:

代码语言:javascript
运行
复制
int main(){
   FILE *f;
   char myStr[1000];
   int strL;
   int nCol;
   int nRow;
   char *fileName = "reg.dat";
   int i, j, k, n1=nCol, n2=1, info;

   double *X;
   double *Y;
   double **X1;
   double *XtX;
   double *XtY;
   int *ipiv;
   double *temp;

   f = fopen(fileName, "r");
   if (f == NULL) perror ("Error opening file");
   else {
     if (fgets(myStr, 1000, f) != NULL )
       puts(myStr);
     fclose(f);
   }

   strL = strlen(myStr);
   nCol = getCol(myStr);
   nRow = getRow(fileName);
   printf("Sample size and number of predictors are %d and %d respectively.\n", nRow, nCol-1);

   X = (double *) malloc(sizeof(double) * ((nCol-1) * nRow));
   Y = (double *) malloc(sizeof(double) * nRow);
   XtX = (double *) malloc(sizeof(double) * (nCol*nCol));
   XtY = (double *) malloc(sizeof(double) * nCol);
   ipiv = (int *) malloc(sizeof(int) * nCol);

   assignY(nCol, nRow, Y, fileName);
   assignX(nCol, nRow, X, fileName);

   X1 = malloc(nRow * sizeof(double*));
   temp = malloc(nRow * nCol * sizeof(double));
   for (i= 0; i < nRow; i++) {
      X1[i] = temp + (i * nCol);
   }

...
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-24 08:24:38

首先声明nRow和nCol,而不赋值:

代码语言:javascript
运行
复制
int nCol;
int nRow;

...and现在定义了四个使用nRow和nCol的可变长度数组:

代码语言:javascript
运行
复制
int i, j, k, n1=nCol, n2=1, ipiv[nCol], info;
double X1[nRow][nCol], XtX[(nCol) * (nCol)], XtY[nCol];

首先,在C90中禁止变长阵列.为此使用malloc()。您似乎知道如何基于代码使用malloc()

其次,在为nColnRow赋值之前,如何期望编译器在声明数组时知道数组的大小?

其中一个数组是多维的。有关如何使用动态多维数组的更多信息,请参见How do I work with dynamic multi-dimensional arrays in C?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29227724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档