I've seen this question and I noticed that I get errors when I declare variables in the middle of the main()
function, but I thought that creating variables dynamically wouldn't cause an error, because it can be done anywhere and anytime during run-time (as far as I know).
我已经看到了这个问题,并且注意到在main()函数的中间声明变量时出现了错误,但是我认为动态创建变量不会导致错误,因为在运行时(据我所知)可以在任何地方和任何时间执行它。
However, I still get:
然而,我仍然得到:
error C2065: 'i' : undeclared identifier
error C2065: 'z' : undeclared identifier
error C2065: 'intArr' : undeclared identifier
My code:
我的代码:
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 个解决方案
#1
1
(I'm not sure why @Blood deleted his answer; it was essentially correct.)
(我不知道为什么@Blood删除了他的答案;它本质上是正确的。)
When I compile your program using gcc, it compiles with no errors. I had to add
当我使用gcc编译您的程序时,它没有任何错误。我已经添加
#include <stdio.h>
#include <stdlib.h>
to the top, and delete the three .....
lines.
最上面,删除三个……行。
When I compile the same program using Microsoft's Visual C++ 2010 Express, I get a number of errors. Several of them complain about undeclared identifiers, but that's a common side effect of syntax errors; if the compiler can't parse your source file, it's likely to become "confused" as it tries to recover. The most relevant error is:
当我使用微软的Visual c++ 2010 Express编译相同的程序时,我得到了许多错误。其中一些抱怨未声明的标识符,但这是语法错误的常见副作用;如果编译器不能解析您的源文件,它可能会在试图恢复时变得“混乱”。最相关的错误是:
syntax error : missing ';' before 'type'
on line 10:
10号线:
printf("Type the array size:\t"); // line 9
int *z = (int *)malloc(sizeof(int)); // line 10
The problem is that the 1989/1990 version of the C standard doesn't permit mixing declarations and statements within a block; it requires all declarations to appear first, followed by all statements. The 1999 C standard changed that, but Microsoft's C compiler has very limited support for any C standard past the 1990 one (and they've said they have no intention of changing that). (I expect they might permit mixed declarations and statements in a future version, since that's a C++ feature as well.)
问题是,1989/1990年版的C标准不允许在一个块中混合声明和语句;它需要首先出现所有声明,然后是所有语句。1999年的C标准改变了这一点,但是微软的C编译器在1990年以后对任何C标准的支持都非常有限(他们说他们无意改变)。(我希望在将来的版本中,它们可能允许混合声明和语句,因为这也是一个c++特性。)
(I'm assuming from the form of the error messages that you're using a Microsoft compiler.)
(我从错误消息的形式假设您正在使用Microsoft编译器。)
You can rearrange your code to satisfy the Microsoft compiler's restrictions. In some cases, you might need to change something like
您可以重新排列代码以满足Microsoft编译器的限制。在某些情况下,您可能需要更改如下内容
int *var = initial_value;
to
来
int *var;
// ...
var = initial_value;
Another suggestion, not related to your question:
另一个与你的问题无关的建议:
In C, you shouldn't cast the result of malloc()
. The malloc()
function returns a value of type void*
, which can be implicitly converted to any pointer-to-object type. (C++ doesn't have this implicit conversion, but you probably shouldn't be using malloc()
in C++ anyway.)
在C语言中,不能使用malloc()的结果。函数的作用是:返回void*类型的值,可以隐式地转换为任何指针到对象的类型。(c++没有这种隐式转换,但您可能不应该在c++中使用malloc())。)
Rather than this:
而不是:
int *z = (int *)malloc(sizeof(int));
...
int *intArr = (int *)malloc((*z) * sizeof(int));
you can write this:
你可以这样写:
int *z = malloc(sizeof *z);
...
int *intArr = malloc(*z * sizeof *intArr);
Dropping the unnecessary cast can avoid certain errors; for example, with some compilers a cast can mask a necessary error message if you've forgotten the required #include <stdlib.h>
. And applying sizeof
to *z
or *intArr
, rather than naming the size explicitly, means that you won't have to change the call if the type of the pointer changes. If you write, for example:
删除不必要的cast可以避免某些错误;例如,如果您忘记了必需的#include
double *p = malloc(sizeof (int)); // incorrect
then you're allocating the wrong size, but the compiler won't warn you about it.
然后您分配了错误的大小,但是编译器不会警告您。
Also, if you're allocating a single int
value using malloc()
, as you're doing with your i
and z
pointers, you're doing unnecessary work. Unless your purpose is to practice using malloc()
, you might as well just make i
and z
int
variables, and drop the malloc()
calls. You'll just have to pass their addresses to scanf
. In other words, you can change this:
另外,如果使用malloc()分配一个int值,就像使用i和z指针一样,那么您就在做不必要的工作。除非您的目的是使用malloc()进行实践,否则您最好只创建i和z int变量,并删除malloc()调用。你只需要把他们的地址传递给scanf。换句话说,你可以改变这一点:
int *z = (int *)malloc(sizeof(int));
...
scanf("%d", z);
to this:
:
int z;
...
scanf("%d", &z);
One more point: your program has no error checking. malloc()
can fail if there isn't enough memory to allocate; it returns a null pointer (NULL
) when this happens. scanf()
can fail if there's an input error, or if you type hello
when it's expecting to read an int
. scanf()
returns the number of items it successfully scanned; you should verify that it did so (in this case, it returns 1 on success). For a simple program like this, aborting the program with an error message:
还有一点:你的程序没有错误检查。如果没有足够的内存来分配,malloc()可能会失败;当发生这种情况时,它返回一个空指针(null)。如果有输入错误,或者当您输入hello时,它希望读取int. scanf(),那么scanf()可能会失败;您应该验证它这样做了(在本例中,它在成功时返回1)。对于这样的简单程序,使用错误消息中止程序:
fprintf(stderr, "Call to ... failed\n");
exit(EXIT_FAILURE);
is probably good enough.
可能是不够好。
#1
1
(I'm not sure why @Blood deleted his answer; it was essentially correct.)
(我不知道为什么@Blood删除了他的答案;它本质上是正确的。)
When I compile your program using gcc, it compiles with no errors. I had to add
当我使用gcc编译您的程序时,它没有任何错误。我已经添加
#include <stdio.h>
#include <stdlib.h>
to the top, and delete the three .....
lines.
最上面,删除三个……行。
When I compile the same program using Microsoft's Visual C++ 2010 Express, I get a number of errors. Several of them complain about undeclared identifiers, but that's a common side effect of syntax errors; if the compiler can't parse your source file, it's likely to become "confused" as it tries to recover. The most relevant error is:
当我使用微软的Visual c++ 2010 Express编译相同的程序时,我得到了许多错误。其中一些抱怨未声明的标识符,但这是语法错误的常见副作用;如果编译器不能解析您的源文件,它可能会在试图恢复时变得“混乱”。最相关的错误是:
syntax error : missing ';' before 'type'
on line 10:
10号线:
printf("Type the array size:\t"); // line 9
int *z = (int *)malloc(sizeof(int)); // line 10
The problem is that the 1989/1990 version of the C standard doesn't permit mixing declarations and statements within a block; it requires all declarations to appear first, followed by all statements. The 1999 C standard changed that, but Microsoft's C compiler has very limited support for any C standard past the 1990 one (and they've said they have no intention of changing that). (I expect they might permit mixed declarations and statements in a future version, since that's a C++ feature as well.)
问题是,1989/1990年版的C标准不允许在一个块中混合声明和语句;它需要首先出现所有声明,然后是所有语句。1999年的C标准改变了这一点,但是微软的C编译器在1990年以后对任何C标准的支持都非常有限(他们说他们无意改变)。(我希望在将来的版本中,它们可能允许混合声明和语句,因为这也是一个c++特性。)
(I'm assuming from the form of the error messages that you're using a Microsoft compiler.)
(我从错误消息的形式假设您正在使用Microsoft编译器。)
You can rearrange your code to satisfy the Microsoft compiler's restrictions. In some cases, you might need to change something like
您可以重新排列代码以满足Microsoft编译器的限制。在某些情况下,您可能需要更改如下内容
int *var = initial_value;
to
来
int *var;
// ...
var = initial_value;
Another suggestion, not related to your question:
另一个与你的问题无关的建议:
In C, you shouldn't cast the result of malloc()
. The malloc()
function returns a value of type void*
, which can be implicitly converted to any pointer-to-object type. (C++ doesn't have this implicit conversion, but you probably shouldn't be using malloc()
in C++ anyway.)
在C语言中,不能使用malloc()的结果。函数的作用是:返回void*类型的值,可以隐式地转换为任何指针到对象的类型。(c++没有这种隐式转换,但您可能不应该在c++中使用malloc())。)
Rather than this:
而不是:
int *z = (int *)malloc(sizeof(int));
...
int *intArr = (int *)malloc((*z) * sizeof(int));
you can write this:
你可以这样写:
int *z = malloc(sizeof *z);
...
int *intArr = malloc(*z * sizeof *intArr);
Dropping the unnecessary cast can avoid certain errors; for example, with some compilers a cast can mask a necessary error message if you've forgotten the required #include <stdlib.h>
. And applying sizeof
to *z
or *intArr
, rather than naming the size explicitly, means that you won't have to change the call if the type of the pointer changes. If you write, for example:
删除不必要的cast可以避免某些错误;例如,如果您忘记了必需的#include
double *p = malloc(sizeof (int)); // incorrect
then you're allocating the wrong size, but the compiler won't warn you about it.
然后您分配了错误的大小,但是编译器不会警告您。
Also, if you're allocating a single int
value using malloc()
, as you're doing with your i
and z
pointers, you're doing unnecessary work. Unless your purpose is to practice using malloc()
, you might as well just make i
and z
int
variables, and drop the malloc()
calls. You'll just have to pass their addresses to scanf
. In other words, you can change this:
另外,如果使用malloc()分配一个int值,就像使用i和z指针一样,那么您就在做不必要的工作。除非您的目的是使用malloc()进行实践,否则您最好只创建i和z int变量,并删除malloc()调用。你只需要把他们的地址传递给scanf。换句话说,你可以改变这一点:
int *z = (int *)malloc(sizeof(int));
...
scanf("%d", z);
to this:
:
int z;
...
scanf("%d", &z);
One more point: your program has no error checking. malloc()
can fail if there isn't enough memory to allocate; it returns a null pointer (NULL
) when this happens. scanf()
can fail if there's an input error, or if you type hello
when it's expecting to read an int
. scanf()
returns the number of items it successfully scanned; you should verify that it did so (in this case, it returns 1 on success). For a simple program like this, aborting the program with an error message:
还有一点:你的程序没有错误检查。如果没有足够的内存来分配,malloc()可能会失败;当发生这种情况时,它返回一个空指针(null)。如果有输入错误,或者当您输入hello时,它希望读取int. scanf(),那么scanf()可能会失败;您应该验证它这样做了(在本例中,它在成功时返回1)。对于这样的简单程序,使用错误消息中止程序:
fprintf(stderr, "Call to ... failed\n");
exit(EXIT_FAILURE);
is probably good enough.
可能是不够好。