我正在编写一个c程序,并且我注意到每当我用const变量声明我的数组长度(const size_t MAX_LEN = 某个数字)时,它就会向我发送错误。 另一方面,当我使用(#define MAX_LEN = 某个数字)作为我的数组长度声明时,它可以正常工作。
我得到的确切错误:LinSeperator.c:45:2:错误:使用可变长度数组'arr'[-Werror = vla] double theAns,arr [MAX_LEN]; ^
任何人都可以帮我弄清楚它为什么会发生吗?
编辑:这是我的代码: 这是我的LinSeperatorHelperFunc.h:
#pragma once
#include <stdio.h>
const size_t MAX_LEN = 199;
typedef struct Orange
{
double arr[MAX_LEN];
int tag;
}orange;
void learnProg(orange *o, double w[], int d);
void filePrinter(const char *output, FILE **fileIn, int d, double w[]);
这是我的.c文件:
#include "LinSeperator.h"
#include "LinSeperatorHelperFunctions.h"
#define NEG_ONE (-1)
#define NegToPos (2)
void LinSeperator(const char *In, const char *Out){
FILE * input;
orange o;
int d , pos, neg ,i , j;
//initializing the hypothesis vector as requested in step 1
double w[MAX_LEN];
for(i = 0 ; i<MAX_LEN ; i++){
w[i] = 0;
}
input = fopen(In,"r");
if(input == NULL){
printf("file doesnt exists");
return;
}
fscanf(input, "%d %d %d", &d , &pos, &neg);
for(i = 0; i<pos+neg ; i++){
o.tag = i<pos ? 1: -1;
for(j = 0 ; j<d ; j++){
fscanf(input, "%lf", &o.arr[j]);
//removing ',' from being scanned
if(j!= d-1){
fgetc(input);
}
}
learnProg(&o,w,d);
}
filePrinter(Out, &input, d, w);
fclose(input);
}
void filePrinter(const char* out, FILE **in, int d, double w[]){
int i;
double theAns, arr[MAX_LEN];
FILE *output = fopen(out, "w");
if (output == NULL){
printf("couldnt write to the current file");
return;
}
while(!feof(*in)){
for (i=0; i<d; i++) {
fscanf((*in), "%lf", &arr[i]);
if(feof(*in))//if we finished the checked vectors we should finish the file and the function
{
fclose(output);
return;
}
//preventing from reading the "," between each col
if(i!=d-1){
fgetc(*in);
}
}
theAns=0;
for (i=0; i<d; i++){
theAns+=arr[i]*w[i];
}
//if ans >=0 print 1 to file else -1
fprintf(output, "%d\n", NEG_ONE+NegToPos*(theAns>=0));
}
fclose(output);
}
//the learning progress algo
void learnProg(orange *o, double w[], int d){
int i, negOrPos = (*o).tag;
double theAns = 0;
for(i = 0; i<d ; i++){
theAns += ((*o).arr[i] * w[i]); //2.1
}
//has the same sign
if( (negOrPos * theAns) > 0 ){ //2.2
return ;
}
else{
for(i = 0; i<d ; i++){
w[i] += (negOrPos * (*o).arr[i]);
}
}
}
答案 0 :(得分:4)
在C中,const
不创建编译时常量。它只是创建一个只读变量。区别很重要。
使用时:
#define MAX_LEN 701
这是指令预处理器替换所有的指令
MAX_LEN
701
的出现次数gcc
。当编译器得到
你的代码,它只能看到数值常数。
C 90标准允许仅使用数字常量长度声明数组。 但是,如果您使用C 99,则可以使用可变长度数组。
使用--std=c99
,您可以使用--std=c90
或g0
来设置标准
编译你的代码。
答案 1 :(得分:1)
这只是语言的限制。您不能在数组声明中使用const size_t。例如:
const size_t dimensions = 3;
size_t reality[dimensions]={3,8,12};
它不会编译,但
#define dimensions 3
size_t reality[dimensions]={3,8,12};
作品。
静态有界数组的大小需要是常量表达式,不幸的是在C中,它只是像文字常量或sizeof表达式那样,但不是常量变量。您可以尝试使用dynamic allocation of array of pointers,但使用它会更复杂。
正如Lundin所说,从技术上讲,标准C99表示你无法向VLA提供初始化列表。参考here。
答案 2 :(得分:1)
这取决于声明数组的位置。
如果在文件范围(任何函数外部)声明它,则数组大小必须是常量表达式,如#define
原始数字。不幸的是,C不将const
变量视为常量表达式。
如果数组是在本地范围内声明的,那么问题就在于您使用的是太旧的编译器,或者您使用了错误配置的GCC。如果是GCC,请告诉它根据C标准语言编译代码:gcc -std=c11 -pedantic-errors -Wall -Wextra
。