0

我看过这个问题,我注意到当我在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));
}
4

1 回答 1

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++ 没有这种隐式转换,但你可能不应该malloc()在 C++ 中使用。)

而不是这样:

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

你可以这样写:

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

去掉不必要的演员表可以避免某些错误;例如,对于某些编译器,如果您忘记了 required ,则强制转换可以掩盖必要的错误消息#include <stdlib.h>。并且应用or ,sizeof而不是显式命名大小,意味着如果指针的类型发生变化,您将不必更改调用。如果你写,例如:*z*intArr

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

那么你分配了错误的大小,但编译器不会警告你。

此外,如果您使用 分配单个intmalloc(),就像您使用iandz指针所做的那样,您正在做不必要的工作。除非您的目的是练习使用malloc(),否则您最好只使用 makeiz int变量,然后放弃malloc()调用。您只需将他们的地址传递给scanf. 换句话说,你可以改变这个:

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

对此:

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

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

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

可能已经足够好了。

于 2012-09-30T22:16:39.657 回答