【问题标题】:int var = 1; void main() { int i = i; }整数变量 = 1; void main() { int i = i; }
【发布时间】:2010-07-04 01:57:52
【问题描述】:

这是我遇到的一个面试问题:

int var = 1;
void main()
{
    int i = i;
}

赋值后i的值是多少?它真的依赖于编译器还是只是未定义?我在 cygwin 上的 g++ 似乎一直给我 0。

谢谢

【问题讨论】:

  • 似乎是一个糟糕的面试问题。我认为了解晦涩难懂的语言是一项经常受到考验的技能(从长远来看并不是很重要)。我宁愿有人会去询问或查找,也不愿有人知道诸如此类的一切。
  • 它甚至不会编译,你至少需要int main()
  • 为什么顶部有int var = 1;
  • 未定义。这就是这个词的用途。就像,科莫多巨蜥可能会爬出来吃掉你的液晶屏。面试官实际上可能希望与您讨论编译器技术(或外行程序员)如何实现捕获此类错误等的技术。
  • @Brian 我想它的意思是说int i = 1;

标签: c++


【解决方案1】:

i 有一个不确定的值,因为它没有被初始化。因此,它不仅依赖于编译器,而且依赖于该内存位置中发生的任何事情。局部范围内的变量未在 C++ 中初始化。

我假设您的意思不是顶部的int var = 1;,而是int i = 1;

仍将使用局部作用域i,因为变量的声明点位于其声明符之后和初始化器之前。

更具体地说,C++03 标准的第 3.3.1-1 节:

名称的声明点是 完成后立即 声明符(第 8 条)及其之前 初始化程序(如果有),除非另有说明 以下。 [示例:

int x = 12;
{ int x = x; }

这里第二个 x 用它自己的(不确定的)值初始化。 ]


顺便说一句,我认为这不是一个很好的面试问题,因为它与了解一些关于语言的晦涩事实有关,而这并不能说明你的编码经验。

【讨论】:

  • 虽然我同意这是一个糟糕的面试问题,但它可能会说明您的编码经验一些。例如,如果您曾经尝试编写一个尝试声明自己的变量的宏(然后得出结论改为使用内联函数),那么您需要考虑这一点。
  • @jamesdlin:也许可以,但我不会推断出这一点,因为你无法区分他们是否恰好知道这个事实。
  • 他们正在检查您的分析能力......伙计们,并非所有问题都是一个简单易懂的问题。他们希望看到您解决问题并提出解决方案,他们希望看到您的知识有多深。您可能会回答“这取决于编译器”之类的问题,或者引导他们完成堆栈操作并解释值的来源,或者您可以说它是在范围之外定义的,因此被分配给一个未初始化的值......您甚至可以说“哦,这将是随机内存数据”,只是表明您可以思考问题。
  • @user257493:除了知道 C++03 规范中的密钥外,没有太多工作要做,即名称的声明点直接位于其声明符之后和其初始化程序之前。如果你有一个编译器可以使用,你也可以很容易地弄清楚,但我怀疑 OP 是。
  • 在最新的 C++1y 草案中,这变成了undefined behavior for the int case
【解决方案2】:

如果你的意思是你所说的代码,它是未定义的,因为int i = i;int i; 相同,这使它未初始化。但是,您的意思可能是:

int i = 1;
void main() {
    int i = i;
}

i 在本地范围内仍未定义,尽管这个问题至少稍微有趣一些。本地i 定义后立即遮蔽全局,因此在分配发生时本地定义已经存在,右侧i 指的是main 中定义的i,而不是全球的。如果它没有删除全局 int i = 1; 将导致编译错误,因为 int i = i; 将引用一个尚不存在的 i

【讨论】:

    【解决方案3】:

    这会导致未定义的行为,因为您在其生命周期开始之前从 i 读取。

    首先:

    [basic.life]/1.2

    ...对象的生命周期...开始于:

    ——它的初始化(如果有的话)已经完成

    i读取时i的初始化没有完成,因为你需要知道值才能完成初始化。

    下一步:

    [basic.life]/7.1

    ...在对象的生命周期开始之前但在分配对象将占用的存储空间之后...任何引用原始对象的glvalue都可以使用,但只能以有限的方式使用。 ...如果出现以下情况,则程序具有未定义的行为:

    ——glvalue 用于访问对象

    i 读取确实“访问对象”,因此是 UB。

    【讨论】:

      【解决方案4】:

      为什么我应该在这里有任何价值,即使是未定义的?分配什么都不做,可以完全优化。

      【讨论】:

      • 这是一个初始化,不是赋值。
      • 但是我没有使用,并且该功能不会有副作用。因此它可以被完全删除。
      • 我认为出于面试目的你会忽略这类事情
      【解决方案5】:

      我有同样的面试问题,我可以确认它确实是 int var = 1;

      这意味着这确实会有所作为。我会运行代码,但我现在不在我的电脑上。

      我同意这样的问题对于面试来说是愚蠢的。以此类推,就像某人正在面试厨师的工作,而问题是“如果你给某人喂了一勺大肠杆菌,淋上了伤寒,他们会生病吗?”。 你不太可能在工作中需要这些知识。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-01
        • 2022-07-13
        • 1970-01-01
        • 1970-01-01
        • 2016-07-20
        • 1970-01-01
        • 2012-01-13
        相关资源
        最近更新 更多