【问题标题】:C Array Error - Asks me to declare the same variable twiceC 数组错误 - 要求我两次声明相同的变量
【发布时间】:2017-01-05 18:51:41
【问题描述】:

我有一个用 c 编写的代码,基本上它接收一个数组并向后打印它。很基本的东西。代码如下:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>

int main(){
    int n; 
    scanf("%d",&n);
    int *arr = malloc(sizeof(int) * n);
    for(int arr_i = 0; arr_i < n; arr_i++)
    {
       scanf("%d",&arr[arr_i]);
    }
    for(arr_i=n-1; arr_i >= 0;arr_i--)
    {
      printf("%d ",arr[arr_i]);   
    }
    return 0;
}

第二个 for 循环出现以下错误:

solution.c:17:9: error: ‘arr_i’ undeclared (第一次在这个函数中使用)

  for(arr_i=n-1; arr_i >= 0;arr_i--)

当我在第二个for 循环中的arr_i 之前插入int 时,错误消失了。

所以,我怀疑为什么即使我已经在第一个 for 循环中声明了 arr_i,它要求我在第二个 for 循环中再次声明它?

【问题讨论】:

  • 如果在函数开始时将变量声明为单独的声明,它可以在任何需要的地方使用。

标签: c arrays dynamic scope


【解决方案1】:

arr_i 的范围仅限于第一个 for 循环。在第二个循环中,is 不存在。

引用C11,第 §6.2.1 章

[...] 如果声明符或类型说明符 声明标识符出现在块内或参数声明列表中 一个函数定义,标识符有块作用域,它终止于 关联块。 [...]

详细地说,for 循环的可用语法之一是

 for ( declaration expressionopt ; expressionopt ) statement

在您的情况下使用。由于arr_i 的声明出现在for 循环的clause-1 中,作用域仅限于循环scope,因此,此标识符为未声明在循环之外。

如果您希望在两个循环中使用相同的变量,请在整个函数的块范围内定义该变量,在本例中为 main() 函数。

也就是说,一般建议,在使用返回的指针之前始终检查malloc() 是否成功。

注意:正如你所说,

当我在第二个 for 循环中的“arr_i”之前插入 int 时,它消失了。

值得一提的是,在这种情况下,有两个不同的变量存在于两个不同的范围内。它们不是同一个变量。

【讨论】:

  • 在调用任何堆内存分配函数(malloc、calloc、realloc)时,始终检查 (!=NULL) 返回值以确保操作成功。
  • 在调用任何scanf() 系列函数时,始终检查返回值(而不是参数值)以确保操作成功。
  • 一般来说,当期望用户输入时,提示用户,告诉他们期望输入什么。
  • 重点是什么?非常简单。 OP似乎是一个初级程序员。许多正式的课堂教学未能涵盖检查错误的需要。并且也没有讨论为什么代码需要检查错误。 (在当前情况下,如果发生错误,则代码将写入地址 0 的小偏移量。这是未定义的行为,可能(通常会)导致段错误事件。因此代码应检查错误并如果发生错误,则通过调用将错误报告(到 stderr):perror() 然后exit( EXIT_FAILURE );
  • @user3629249 这是我对您的第一条评论的回复,并且已经在答案中提到。
【解决方案2】:

这实际上是 for 循环与 while 循环相比的一个不错的功能,该变量的生命周期与 For 块结构一样长,您可以在 for 块参数中声明它。因此,只需在结构之外(之前)声明它,您就会发现,了解有关范围和变量生命周期的更多信息。

int main(){
int n; 
scanf("%d",&n);
int *arr = malloc(sizeof(int) * n);
int arr_i = 0; 
for( ; arr_i < n; arr_i++)
{
   scanf("%d",&arr[arr_i]);
}
//
for(arr_i=n-1; arr_i >= 0;arr_i--)
{
  printf("%d ",arr[arr_i]);   
}
return 0;

}

另外查看你的代码 n 没有被赋予任何值,你可以解决它但它没有值(它实际上是一个未确定的值),malloc( sizeof(int) * n ) 将是 4bytes * (未确定)..因此,如果有的话,请将其设置为 0。我不确定这是否是一些伪代码,但其中包含错误,我会为您编写它,但既然您开始了,您应该自己做 :) 熟能生巧。如果您需要更多帮助,请说出该评论。

【讨论】:

  • 如果您要使用单个变量,我更愿意在循环控制中而不是在变量定义中看到初始化。通常,在定义时进行初始化是好的,但在 IMO 中,在循环控制行中包含 for 循环的所有控制信息甚至是莫里斯很重要。
【解决方案3】:

正如 Sourav Ghosh 已经指出的那样,当您在 for(本例)中声明一个变量时,该变量仅存在于该循环中。示例:

void test ()
{
    int normal_variable = 5;
    {
        int local_variable = 10;//only exists here
        printf("It compiles: %d and work.\n", local_variable);
        printf("It also works: %d",normal_variable);
    }
    printf("Doesn't compile because doesn't exists: %d.",local_variable);
    printf("It also works, because it already exists: %d",normal_variable);
}

括号是使这成为可能的括号。 如果您想了解更多信息,请查看:

Where you can and cannot declare new variables in C?

【讨论】:

  • 请不要发布仅链接的答案。
【解决方案4】:

变量的范围很重要。

第一个循环中的第一个声明具有该循环的范围

所以它在第二个循环中是不可见的。

【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2012-12-10
    • 1970-01-01
    相关资源
    最近更新 更多