在C char foo [foo]中是不允许的,但是为什么呢?以及如何使用输入作为此[foo]的声明

问题描述

我是C语言的新手,我习惯使用zx basic和z80 asm。我想使用输入的值来创建字符数组,但是

int   amount_of_dice_sides ;
printf("Give number of sides of dice:\n") ;
scanf("%d",&amount_of_dice_sides) ;
char  all[amount_of_dice_sides] ;

目前还不允许

int   amount_of_dice_sides=6 ;
char  all[6] ;

效果很好....我怎么得到的 char all [amount_of_dice_sides]; 加工? 这是一个非常基础的问题,非常“基本”,但我似乎找不到一个并非以“ const char * foo之间的区别”开头的答案 这与将char设置为整数无关,而只是将其设置为实数值而不是变量。 我发现了这些可能的“ char foo”,但我无法实现 https://medium.com/@bartobri/untangling-complex-c-declarations-9b6a0cf88c96

编辑 我使用另一个编译器,然后使用gcc

#include <stdio.h>
void main ()
    {
int   amount_of_dice_sides ;
printf("Give number of sides of dice:\n") ;
scanf("%d",&amount_of_dice_sides) ;
char  all[amount_of_dice_sides] ;
return ;
    }

可以正常工作,但不能与zcc一起使用。 所以我不得不去另一个地方,我真的还在学习。 见ya,并感谢您减轻繁琐的回答。克里斯

解决方法

它不起作用的原因是您使用的是侏罗纪时期的编译器和MCU。可变长度数组(VLA)于1999年以C语言引入。Z80可能是学习一种汇编语言的不错的平台,但它却是学习C的可怕平台。

但是无论如何,您永远不要在低端微控制器上使用VLA分配或堆分配,因为它们的内存通常非常有限,尤其是堆栈内存。 (并且堆分配只是doesn't make sense。)

出于相同的原因,您也不应该使用stdio.h,它将杀死大量的所有可用内存。相反,您应该使用原始UART驱动程序或自己编写一个-假设stdio.h函数进入PC的终端。首先找到链接程序映射文件,对其进行研究,然后查看这些库实际上占用了多少内存,然后您将亲自了解为什么它们不合适。

,

C在某些情况下仅允许使用可变长度的堆栈数组。具体来说,当您具有函数时,可以使用基于参数的计算来为堆栈分配数组。

void func(int param){
    int array[param] // call it here
    // do some work with array as a scratch space
}   // when the final curly bracket is called,the array is destroyed

但是,这种技术很容易使您陷入麻烦。如果您未指定数组的长度,并且用户输入了一个很大的数字,那么您将得到 Stack Overflow 。在早期的C编译器和平台(如Intel-8051)上,这很痛苦,而且调用了太多的嵌套函数。

解决方案是在堆上分配可变长度数组。有些平台也允许分配堆栈,但并非全部。

// In sumfunc we roll a number of dice,print,and return the sum
// Malloc allocates to the heap
int sumFunc_malloc(int num_dice){
    int * dice = (int*)malloc(sizeof(int) * num_dice); // our allocation
    int sum = 0;
    for (int i = 0; i < num_dice; i++){
        dice[i] = (rand() % 6) + 1;
        printf("Dice %d rolled a %d",i,dice[i];
        sum += dice[i];
    }
    free(dice); // REQUIRED or memory will leak,and eventually program will fail
    return sum;
}

// In sumfunc we roll a number of dice,and return the sum
// Alloca is not supported by all platforms,but is on the stack
int sumFunc_alloca(int num_dice){
    int * dice = (int*)alloca(sizeof(int) * num_dice); // our allocation on the stack
    int sum = 0;
    for (int i = 0; i < num_dice; i++){
        dice[i] = (rand() % 6) + 1;
        printf("Dice %d rolled a %d",dice[i];
        sum += dice[i];
    }
    return sum;
}

一种最后的选择(尤其是在8051等设备上)是拥有一个便签本,您可以在其中做大量工作,然后重复使用它。

static char scratch[100];

int func(int param){
    // use scratch to hold lots of temporary values
}
,

最好的评论是解释WHY部分:编译将把内存设置在一个永久的位置,如果以后更改大小,C会遇到分配变量的麻烦。

与此同时,我确实在名为z88dk的dinosar上学习了C。我花了一些时间才能够使用它。 z88dk正在缓慢地从“经典”重写为SDCC以及其他版本。

此代码在zcc中有效,但在构建z88dk本身时(BUILD_SCC = 1)(!!!),并对zx频谱使用特殊的库:

hommes = {}
femmes = {}

Bryan=Candidat("homme",4,5,3,2)
Adrien=Candidat("homme",2,3)
Marin=Candidat("homme",3)
Alcaraz=Candidat("homme",1)
Allan=Candidat("homme",1)
SebyDaddy=Candidat("homme",1)

hommes[‘Bryan’] = Bryan
hommes[‘Adrien’] = Adrien
hommes[‘Marin’] = Marin
hommes[‘Alcaraz’] = Alcaraz
hommes[‘Allan’] = Allan
hommes[‘SebyDaddy’] = SebyDaddy

#--------------------------------#

Anissa=Candidat("femme",0)
Melanie=Candidat("femme",3)
Dita=Candidat("femme",2)
LeaMary=Candidat("femme",1)
Maissane=Candidat("femme",1)
Kellyn=Candidat("femme",1)

femmes[‘Anissa’] = Anissa
femmes[‘Melanie’] = Melanie
femmes[‘Dita’] = Dita
femmes[‘LeaMary’] = LeaMary
femmes[‘Maissane’] = Maissane
femmes[‘Kellyn’] = Kellyn

homme = input("Homme : ")  #input Man
femme = input("Femme : ")  #input Woman
compare(hommes[homme],femmes[femme]) #comparing


**Update:** I had skipped putting the rest of the people into their dicts. Fixed now. 

那我为什么要被困在这里? 好吧,这是我真正拥有的唯一来源!

,

在此声明中,

int   amount_of_dice_sides ;
printf("Give number of sides of dice:\n") ;
scanf("%d",&amount_of_dice_sides) ;
char  all[amount_of_dice_sides] ;

all [amount_of_dice_sides]是一个静态数组,编译器在构建代码之前需要知道其大小。

在您的情况下,发生的事情是在编译后将数组的大小作为用户的输入读取

为了避免以后在代码中出现内存问题,总是建议明确提及数组的大小