【问题标题】:array length variable - c数组长度变量 - c
【发布时间】:2016-07-29 08:31:30
【问题描述】:

我正在编写一个 c 程序,我注意到每当我用 const 变量(const size_t MAX_LEN = some number)声明我的数组长度时,它都会向我发送错误。 另一方面,当我使用 (#define MAX_LEN = some number) 作为我的数组长度声明时,它工作得很好。

我得到的确切错误:LinSeperator.c:45:2: error: variable length array ‘arr’ is used [-Werror=vla] 加倍答案,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]);
  }
}
}

【问题讨论】:

  • 您能尝试创建一个Minimal, Complete, and Verifiable Example 并展示给我们看吗?并且还包括 complete 错误输出?
  • 尝试添加-std=c99 选项。
  • 您的编译器是否符合 c99 c 标准?因为可变长度数组 (VLA) 仅在 c99 中添加
  • 显示你的代码而不是描述它。
  • "#define MAX_LEN = some number" 很可能无法编译。你想删除=

标签: c arrays


【解决方案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 表达式之类的东西,而不是 const 类型的变量。您可以尝试使用dynamic allocation of array of pointers,但使用起来比较复杂。

正如 Lundin 所说,从技术上讲,标准 C99 规定您不能为 VLA 提供初始化列表。参考here

【讨论】:

  • 示例无法编译的原因是您无法为 VLA 提供初始化列表。总的来说,这个答案是不正确的。 1999 年有一个新的 C 标准。
【解决方案2】:

在 C 中,const 不创建编译时常量。它只是创建一个只读变量。区别很重要。

使用时:

#define MAX_LEN 701

这是一个给预处理器的指令来替换所有 MAX_LEN701 的出现次数。当编译器得到 你的代码,它所看到的只是数字常量。

C 90 标准只允许声明具有数字常数长度的数组。 但是,如果您要使用 C 99,则可以使用可变长度数组。

使用gcc,您可以使用--std=c99--std=c90 设置什么标准 编译你的代码。

【讨论】:

    【解决方案3】:

    这取决于数组的声明位置。

    如果它是在文件范围内(任何函数之外)声明的,那么数组大小必须是一个常量表达式,例如 #define 原始数字。不幸的是,C 不将const 变量视为常量表达式。

    如果数组是在本地范围内声明的,问题只是您使用的编译器太旧,或者您错误配置了 GCC。如果是 GCC,告诉它根据 C 标准语言编译你的代码:gcc -std=c11 -pedantic-errors -Wall -Wextra

    【讨论】:

      猜你喜欢
      • 2022-11-27
      • 1970-01-01
      • 2014-06-17
      • 2013-06-23
      • 2021-07-11
      • 1970-01-01
      • 2017-11-15
      • 2014-03-27
      • 2018-12-16
      相关资源
      最近更新 更多