gpt4 book ai didi

c - 解决方法 : ISO C90 forbids variable length array

转载 作者:太空宇宙 更新时间:2023-11-04 03:40:18 31 4
gpt4 key购买 nike

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

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

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 是:

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]:

#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...

   /* 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];
}
}

接下来我打印结果

  /* 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;
}

辅助函数...

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;
}

辅助函数...

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;
}

辅助函数...

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 时,错误都消失了,除了:

readReg.c: In function ‘main’:
readReg.c:62: error: subscripted value is neither array nor pointer

下面是更新后的主函数:

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);
}

...
}

最佳答案

您首先声明 nRow 和 nCol 而不分配任何值:

int nCol;
int nRow;

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

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?有关如何使用动态多维数组的更多信息。

关于c - 解决方法 : ISO C90 forbids variable length array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29227724/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com