根据用户输入更改#define值

时间:2019-03-08 17:52:06

标签: c

我有一组看起来像这样的代码:

#define BLOCKS 20
#define SEG 5

int memory[BLOCKS][SEG];

int main() {

    FILE* stream = fopen("file.csv", "r");

    printf("Please enter a number:");
    int input = scanf("%d", &input);

如果我尝试将SEG从#DEFINE变为int SEG = 0;,而不是int input = scanf("%d", &input);并尝试让SEG变成SEG,Visual Studio会告诉我我的{{ 1}}现在是

的未声明标识符和表达式
int memory[BLOCKS][SEG];

必须具有恒定值。

我的问题是,如何通过用户输入确定此SEG值?例如。如果用户输入10,我的变量SEG将变成10,程序将继续运行。

我尝试了以下链接,但对我而言无效。 Array definition - Expression must have a constant value

我将不胜感激。谢谢!

4 个答案:

答案 0 :(得分:0)

#define是预处理程序指令。您不能基于一个程序中的用户输入来更改它。您可以尝试使用malloc制作数组!

尝试

int input, i;

printf("Please enter a number:");
scanf("%d", &input);

int** memory = malloc(sizeof(int*) * BLOCKS);
for(i = 0; i < BLOCKS; i++)
    memory[i] = malloc(sizeof(int) * input);

像访问原始2D阵列一样访问它。 memory[row][col];

答案 1 :(得分:0)

df.resample('6H').ffill(limit=3) # feastday #date #2018-01-01 00:00:00 Neujahrestag #2018-01-01 06:00:00 Neujahrestag #2018-01-01 12:00:00 Neujahrestag #2018-01-01 18:00:00 Neujahrestag #2018-01-02 00:00:00 NaN #2018-01-02 06:00:00 NaN #2018-01-02 12:00:00 NaN #... 预处理程序指令的值必须在编译时已知,并且不能等待运行时。同样,声明数组通常是在编译时就知道的。

您需要做的是分配一些内存。 (请记住在完成操作后将其释放。)然后将内存作为二维数组进行寻址。

df = df.resample('6H').asfreq()
df.groupby(df.index.date).transform('first')

您可以将地址2的段3寻址为

c = 'T'

select a, b, c from tablename where c <> 'T'
union all
select a, b, c from (
  select a, b, c from tablename where c = 'T'
) where rownum <= 1 

或者,如果您想使用二维数组表示法,并且对维度的顺序不感到困惑,则可以声明指向数组的指针,

#define

引用者:

int *memory = (int *)malloc(BLOCKS * input * sizeof(int))

答案 2 :(得分:0)

对于C89和更早版本,数组声明中的数组维必须为常量表达式,这意味着它们必须在编译时可计算(数字常量,sizeof表达式,涉及数字常量的表达式)和/或sizeof表达式,或扩展为以上任何一个的宏)。

C99引入了“可变长度数组”,其中数组大小是使用运行时表达式确定的(这对使用VLA的位置施加了一些限制):

int blocks = some_value();
int seg = some_other_value();

int memory[blocks][segs];

不幸的是,Microsoft的Visual Studio实现不支持可变长度数组(或C89以外的其他很多格式)。

因此,您可以选择-您可以使用支持C99或更高版本的其他编译器(例如MinGW),也可以使用动态内存分配。如果您想保持BLOCKS不变但SEG可变,则需要执行以下操作:

int *memory[BLOCKS];
int seg;
...
scanf( "%d", &seg );
...
for ( int i = 0; i < BLOCKS; i++ )
{
  memory[i] = malloc( sizeof *memory[i] * seg );
  if ( !memory[i] )
    // handle memory allocation failure
}

完成后,您需要free该内存:

for ( int i = 0; i < BLOCKS; i++ )
  free( memory[i] );

此方法的主要缺点是数组的行在内存中将不连续-memory[i][seg-1]memory[i+1][0]之间将存在间隙。如果那很重要,您可能必须将内存分配为一个块,然后进行伪造的2D索引:

int *memory = malloc( sizeof *memory * BLOCKS * seg );
if ( !memory )
  // handle memory allocation failure
...
memory[i * BLOCKS + j] = some_value();

编辑

这是一个基于问题片段的示例(未经测试!)-您正在尝试读取具有固定行数(BLOCKS)和可变列数({{ 1}}):

SEG

答案 3 :(得分:0)

C语言中的数组非常基础。多维数组只是数组的数组;所以当你说:

int A[10][11];
...
A[3][4] = 17;

您可能还写得很好:

int A[110];
...
A[37] = 17;

为什么37? 3 * 11 + 4 = 37。

编译器如何知道乘以11?您在A的定义中告诉了它!

对const和volatile的灾难不满意,标准[sic]正文在数组的特殊情况下增加了动态数组的大小,这很愚蠢:

void f(int n, int m) {
    int A[n][m];
    int i,j;
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            A[i][j] = i*m+j;
        }
    }
    int *a = A;
    for (i = 0; i < n*m; i++) {
        printf("%d\n", a[i]);
    }
}

仅在受限的上下文中有效,特别是在您尝试的上下文中无效。因此,您可以编写一堆奇怪的访问器函数(没人会为此感谢您),或者自己实现存储映射:

int memory[A Very Big Number];
int *getmem(int blk, int segsize) {
     int off = blk * segsize;
     if (off >= 0 && off < A Very Big Number) {
         return memory + off;
     } else {
         return NULL;
     }
}