【问题标题】:c: Style: altering variables in placec:风格:就地改变变量
【发布时间】:2012-08-17 06:04:49
【问题描述】:

假设我们有类似的东西

int f(int n);

....

do{
    int a = b;
    int b = f(a);
}

这样说有风险吗

do{
    int b = f(b);
}

相反,假设 a 没有在其他地方使用?做前者在风格上会更可取吗?

【问题讨论】:

  • 我个人不喜欢这两种方法,因为它会从更高的范围隐藏变量,这会使代码更难以理解/遵循,尽管这只是我的意见.. . 除了你的 gtg。
  • 我不确定我理解为什么会出现变量阴影。
  • do {} 块中的 b 与块外的 b 不同。事实上,你并没有像你的问题所假设的那样“改变”任何东西。
  • 你不能真正在同一个块中定义相同的变量,你会得到previous definition of 我也不认为第二个有效,因为编译器会尝试使用变量只是定义了哪个可能包含垃圾,无论哪种方式都不要隐藏,但如果你必须使用第一个,第二个就不会按预期工作。
  • 我认为这个问题被误解了。我将其解读为块可以如何实现的两个独立且相互排斥的变体,问题是后一种形式是否存在任何固有风险和/或风格问题。

标签: c variables coding-style in-place


【解决方案1】:

重要的是要理解,您在这里不是“更改”任何变量,只是更改名称的含义。

重要的概念称为point of declaration

让我们看看你的例子:

int b = 42;
{ 
   int a = b; 
   int b = 23 * a;
   printf("%d\n", b);
}
printf("%d\n", b); 

int b = 42;
{ 
   int b = 23 * b;
   printf("%d\n", b);
}
printf("%d\n", b); 

名称 b 引用了两个对象,具体取决于您在代码中的位置,我们称它们为 b1 和 b2。这在案例 1 中不足为奇:

int b1 = 42;
{ 
   int a = b1; 
   int b2 = 23 * a;
   printf("%d\n", b2);
} 
printf("%d\n", b1); 

由于在 C 中声明点在初始化器之前,因此第二个示例的解析方式不同:

int b1 = 42;
{ 
   int b2 = 23 * b2; 
   printf("%d\n", b2);
} 
printf("%d\n", b1); 

请注意,这里 b1 和 b2 之间没有链接,您正在使用其自己的(未定义的)值初始化 b2。勤奋的编译器会对此发出警告,例如

x.c:7:13: warning: 'b' is used uninitialized in this function [-Wuninitialized]

【讨论】:

    【解决方案2】:

    当编译器解析 C 代码时,它会填充一个符号表,该表包含有关所有不同符号的信息,符号是指标识符,例如您为变量、函数等命名的名称...

    大多数 C 程序都是由嵌套作用域构成的,全局 -> 函数 -> 组件语句等,每个作用域通常都有自己的符号表,因此编译器使用一堆符号表来跟踪所有内容,当一个变量被查找但未在当前符号表中定义它通过向上堆栈开始搜索,直到它到达全局或通常最后一个表......但是一旦在当前范围内定义了一个条目,就会将条目设为“阴影” ' 上一个。

    这里有一个简单的程序来说明。

    #include <stdio.h> 
    /* global accessable by most things ... */
    int a = 5;
    int main()
    { /* function scope */
        int a = 4; /* shadowing global */
        { /* nested scope within function scope */
            int b = a;
            int a = b; /* shadowing function  */
            printf("%i\n", a);
        }
        return 0;
     }
    

    如果你运行它,你会得到4,这是意料之中的,但任何关注你的代码的人都必须牢记a与来自全局函数的所有其他a不同main ...如果维护代码的程序员不知道这些事情,或者您自己忘记了,那么您可能会遇到难以调试的细微运行时错误...

    还要注意,如果你运行这个:

    #include <stdio.h> 
    /* global accessable by most things ... */
    int a = 5;
    int main()
    { /* function scope */
        int a = 4; /* shadowing global */
        { /* nested scope within function scope */            
            int a = a; /* shadowing function, but not actually accessing outer scope */
            printf("%i\n", a);
        }
        return 0;
     }
    

    你不会得到 4,但在我的机器上是一些大的随机 int,它是 1606422610,因为变量被分配给自己,只是影子,而 c 不会初始化变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-28
      • 2012-08-11
      • 2019-05-08
      • 2015-06-23
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多