为什么在动态创建变量时会出现未声明的标识符错误?

时间:2012-09-30 19:16:01

标签: c compiler-errors

我见过this question,我发现当我在main()函数的中间声明变量时出现错误,但我认为动态创建变量不会导致错误,因为它可以在运行期间的任何时间和任何时间完成(据我所知)。

然而,我仍然得到:

error C2065: 'i' : undeclared identifier
error C2065: 'z' : undeclared identifier
error C2065: 'intArr' : undeclared identifier

我的代码:

int main()
{
  ..... 
  .....
  ..... 

  printf("Type the array size:\t");
  int *z = (int *)malloc(sizeof(int));
  scanf("%d", z);
  int *intArr = (int *)malloc((*z) * sizeof(int));

  int *i = (int *)malloc(sizeof(int));

  for (*i = 0; *i < *z; ((*i)++))
  {
      printf("Type a number\t");
      scanf("%d", (intArr+(*i)));
  }

  printArr(intArr);
}

void printArr(int *arr)
{
    int i; 
    for (i = 0; i < (sizeof(arr) / sizeof(*arr)); ++i)
        printf("%d ", *(arr+i));
}

1 个答案:

答案 0 :(得分:1)

(我不确定为什么@Blood删除了他的答案;它基本上是正确的。)

当我使用gcc编译程序时,它编译时没有错误。我不得不添加

 #include <stdio.h>
 #include <stdlib.h>

到顶部,然后删除三条.....行。

当我使用Microsoft的Visual C ++ 2010 Express编译相同的程序时,我收到了许多错误。他们中的一些人抱怨未声明的标识符,但这是语法错误的常见副作用;如果编译器无法解析您的源文件,它可能会在尝试恢复时变得“混乱”。最相关的错误是:

syntax error : missing ';' before 'type'

第10行:

printf("Type the array size:\t");     // line 9
int *z = (int *)malloc(sizeof(int));  // line 10

问题是1989/1990版的C标准不允许在一个区块内混合声明和陈述;它要求所有声明首先出现,然后是所有声明。 1999 C标准改变了这一点,但微软的C编译器对1990年以后的任何C标准的支持非常有限(他们说他们无意改变它)。 (我希望他们可能允许在将来的版本中使用混合声明和语句,因为这也是一个C ++特性。)

(我假设您使用的是Microsoft编译器的错误消息。)

您可以重新排列代码以满足Microsoft编译器的限制。在某些情况下,您可能需要更改

之类的内容
int *var = initial_value;

int *var;
// ...
var = initial_value;

另一个与您的问题无关的建议:

在C中,您不应该投射malloc()的结果。 malloc()函数返回类型void*的值,可以隐式转换为任何指向对象的类型。 (C ++没有这种隐式转换,但你可能不应该在C ++中使用malloc()。)

而不是:

int *z = (int *)malloc(sizeof(int));
...
int *intArr = (int *)malloc((*z) * sizeof(int));

你可以这样写:

int *z = malloc(sizeof *z);
...
int *intArr = malloc(*z * sizeof *intArr);

删除不必要的演员阵容可以避免某些错误;例如,对于某些编译器,如果您忘记了所需的#include <stdlib.h>,则演员可以屏蔽必要的错误消息。将sizeof应用于*z*intArr,而不是明确命名大小,意味着如果指针的类型发生更改,则不必更改调用。如果你写,例如:

double *p = malloc(sizeof (int)); // incorrect

然后你分配的是错误的大小,但编译器不会警告你。

此外,如果您使用int分配一个malloc()值,就像您使用iz指针一样,那么您就没有必要了工作。除非您的目的是使用malloc()进行练习,否则您最好只制作iz int个变量,然后删除malloc()次来电。您只需将地址传递给scanf即可。换句话说,你可以改变这个:

int *z = (int *)malloc(sizeof(int));
...
scanf("%d", z);

到此:

int z;
...
scanf("%d", &z);

还有一点:您的程序没有错误检查。如果没有足够的内存来分配,malloc()可能会失败;当发生这种情况时,它返回一个空指针(NULL)。如果输入错误,或者在期望阅读scanf()时键入helloint可能会失败。 scanf()返回成功扫描的项目数;你应该验证它是这样做的(在这种情况下,它会在成功时返回1)。对于这样的简单程序,使用错误消息中止程序:

fprintf(stderr, "Call to ... failed\n");
exit(EXIT_FAILURE);

可能还不错。