GVKun编程网logo

while(true); 循环在无效时抛出无法访问的代码(while循环无法实现遍历循环)

4

如果您对while感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于while的详细内容,我们还将为您解答true;循环在无效时抛出无法访问的代码的相关问题,并且为您提供关于.

如果您对while感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于while的详细内容,我们还将为您解答true; 循环在无效时抛出无法访问的代码的相关问题,并且为您提供关于.setVisible(true)立即重绘、c – 构造函数的右括号中无法访问的代码、c#类,结构或接口成员声明中的’while’标记无效(while循环不起作用)、C++ while(do-while)循环详解的有价值信息。

本文目录一览:

while(true); 循环在无效时抛出无法访问的代码(while循环无法实现遍历循环)

while(true); 循环在无效时抛出无法访问的代码(while循环无法实现遍历循环)

我在用Java做一些小程序。我知道,如果我编写 while(true); 程序,程序将在此循环中冻结。如果代码是这样的:

测试1:

public class While {    public static void main(String[] args) {        System.out.println("start");        while (true);        System.out.println("end");    }}

编译器抛出错误:

Exception in thread "main" java.lang.Error: Unresolved compilation problem:     Unreachable code    at While.main(While.java:6)

我不知道这个错误存在。但是我知道为什么会抛出它。当然, 第6行无法访问 ,从而导致编译问题。然后,我对此进行了测试:

测试2:

public class While {    public static void main(String[] args) {        System.out.println("start");        a();        b();    }    static void a() {        while(true);    }    static void b() {        System.out.println("end");    }}

由于某种原因 ,程序正常运行 (控制台先打印“开始”,然后冻结)。编译器无法检查内部, void a() 并无法访问。确保我尝试过:

测试3:

public class While {    public static void main(String[] args) {        System.out.println("start");        a();        System.out.println("end");    }    static void a() {        while(true);    }}

与测试2相同的结果。

经过一番研究,我发现了这个 。 因此,如果括号内的代码是变量,则编译器不会抛出异常 。这是有道理的,但我认为不适用于 voids

问: 那么,如果无法到达 void b() (测试2)和 System.out.println("end");
(测试3),为什么编译器会在测试1处抛出错误?

编辑: 我尝试在C ++中的测试1:

#include <iostream>using namespace std;int main(){    cout << "start" << endl;    while(true);    cout << "end" << endl;    return 0;}

编译器没有抛出任何错误 ,然后我得到了与Test 2和Test 3相同的结果。所以我想这是Java吗?

答案1

小编典典

该语言规范有一个确切的定义是什么,编译器应该当作可达代码,也见:
编译器的行为在Java语言规范的14.21节中有明确规定。无法到达的陈述。

这是一个关键语录,它直接解决了您的问题:

本节专门对“可达”一词进行精确的解释。这个想法是,从包含该语句的构造函数,方法,实例初始值设定项或静态初始值设定项的开始,必须有一些可能的执行路径。该分析考虑了语句的结构。除了对while,do和条件表达式的常数值为true的语句的特殊处理外,流分析中不考虑表达式的值。

特别是,它并不关心某个方法是否完成,也不会在其他方法内部查找。

它不会做得更多。

但是,您可以使用诸如FindBugs之类的静态代码分析工具来进行“更深入的”分析(尽管不确定它们是否能够检测到您描述的模式,而且正如其他人所指出的那样,总的来说,停止问题并不能解决)无论如何都可以通过算法解决,因此必须以“尽力而为”的某种合理定义来划清界线。

.setVisible(true)立即重绘

.setVisible(true)立即重绘

在一个简短的方法中,我使用setVisible(false)隐藏了一个JFrame。然后,截屏并使用setVisible(true)还原JFrame。

在再次显示之后,窗口应该显示与以前不同的图片(可以说是截图的一部分)。

问题是,在调用setVisible(true)之后,将窗口与旧内容一起闪烁一秒钟,然后再调用paintComponent并绘制更新的状态。

我可能会以丑陋的方式解决此问题,但我想知道是否有更好的解决方案。

预先感谢您的任何帮助

编辑:在准备示例时,我注意到当不像我在程序中那样使用透明性时,几乎无法观察到这种效果。应该可能已经提到了。这是我想出的:

import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Toolkit;import javax.swing.JFrame;import javax.swing.JPanel;import com.sun.awt.AWTUtilities;public class Test {    static boolean flag = false;    static Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();    public static void main(String[] args) throws InterruptedException {        JFrame frame = new JFrame();        frame.setUndecorated(true);        AWTUtilities.setWindowOpaque(frame, false);  //draw on a transparent window        frame.setSize(scrSize.width, scrSize.height);        frame.setContentPane(new JPanel() {            protected void paintComponent(Graphics g)             {                if (Test.flag) {                    g.setColor(Color.RED);                    g.drawRect(50, 50, scrSize.width - 100, scrSize.height - 100);                }                else {                    g.setColor(Color.GREEN);                    g.fillOval(50, 50, scrSize.width - 100, scrSize.height - 100);                }            }        });        frame.setVisible(true); //green oval shown        Thread.sleep(1000);        frame.setVisible(false);        flag = true; // next draw produces red rectangle        Thread.sleep(1000);        frame.setVisible(true); // before the next draw,                                 // you can see a flash of the green oval    }}

答案1

小编典典

我意识到在提出问题一年后就提出了这个答案,但是我遇到了类似的问题,当然在进行尝试之前进行了一些研究。对于遇到此问题的任何人,请在包装并使其可见之前尝试摆放窗户/框架。

c – 构造函数的右括号中无法访问的代码

c – 构造函数的右括号中无法访问的代码

我正在开发一个用VC9构建的应用程序,我遇到了一个我不完全理解的警告:为什么在构造函数的右括号上有一个“无法访问的代码”警告?

重现问题的最小测试用例是:

__declspec(noreturn) void foo() {
  // Do something,then terminate the program
}
struct A {
  A() {
    foo();
  } // d:\foo.cpp(7) : warning C4702: unreachable code
};
int main() {
  A a;
}

必须使用/ W4编译才能触发警告.或者,您可以使用/ we4702编译以强制检测此警告时出错.

d:\>cl /c /W4 foo.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64
copyright (C) Microsoft Corporation.  All rights reserved.

foo.cpp
d:\foo.cpp(7) : warning C4702: unreachable code

有人可以解释一下,究竟是什么在这里无法到达?我最好的理论是它是析构函数,但我想要一个确定的答案.

如果我想让这段代码警告清洁,我该如何实现呢?我能想到的最好的是将其转换为编译时错误.

struct A {
private:
  A(); // No,you can't construct this!
};
int main() {
  A a;
}

编辑:为了澄清,使用noreturn函数终止程序通常不会在封闭该函数调用的右括号上导致无法访问的代码警告.

__declspec(noreturn) void foo() {
  // Do something,then terminate the program
}
struct A {
  A() {
  }
  ~A() {
    foo();
  }
};
int main() {
  A a;
}

结果是:

d:\>cl /c /W4 foo3.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.21022.08 for x64
copyright (C) Microsoft Corporation.  All rights reserved.

foo3.cpp

解决方法

Gorpik走在正确的轨道上.我创建了两个类似的测试用例,编译它们并对它们进行反汇编,我想我已经理解了它的根本原因:构造函数总是隐式生成一个return语句,并且由于noreturn函数,这个return语句是无法访问的.

noreturn_constructor.cpp

__declspec(noreturn) void foo() {
  // Do something,then terminate the program
}
struct A {
  A() {
    foo();
  }
  ~A() {
  }
};
int main() {
  A a;
}

noreturn_destructor.cpp

__declspec(noreturn) void foo() {
  // Do something,then terminate the program
}
struct A {
  A() {
  }
  ~A() {
    foo();
  }
};
int main() {
  A a;
}

diff -u * .disasm

--- noreturn_constructor.disasm 2012-05-30 11:15:02.000000000 -0400
+++ noreturn_destructor.disasm  2012-05-30 11:15:08.000000000 -0400
@@ -2,7 +2,7 @@
 copyright (C) Microsoft Corporation.  All rights reserved.


-Dump of file noreturn_constructor.obj
+Dump of file noreturn_destructor.obj

 File Type: COFF OBJECT

@@ -35,15 +35,15 @@

 ??0A@@QEAA@XZ (public: __cdecl A::A(void)):
   0000000000000000: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
-  0000000000000005: 48 83 EC 28        sub         rsp,28h
-  0000000000000009: E8 00 00 00 00     call        ?foo@@YAXXZ
-  000000000000000E: 48 8B 44 24 30     mov         rax,qword ptr [rsp+30h]
-  0000000000000013: 48 83 C4 28        add         rsp,28h
-  0000000000000017: C3                 ret
+  0000000000000005: 48 8B 44 24 08     mov         rax,qword ptr [rsp+8]
+  000000000000000A: C3                 ret

 ??1A@@QEAA@XZ (public: __cdecl A::~A(void)):
   0000000000000000: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
-  0000000000000005: C3                 ret
+  0000000000000005: 48 83 EC 28        sub         rsp,28h
+  0000000000000009: E8 00 00 00 00     call        ?foo@@YAXXZ
+  000000000000000E: 48 83 C4 28        add         rsp,28h
+  0000000000000012: C3                 ret

   Summary

无法访问的代码是这个隐式的return语句,它是在构造函数中生成的,而不是析构函数:

-  000000000000000E: 48 8B 44 24 30     mov         rax,qword ptr [rsp+30h]
+  0000000000000005: 48 8B 44 24 08     mov         rax,qword ptr [rsp+8]

c#类,结构或接口成员声明中的’while’标记无效(while循环不起作用)

c#类,结构或接口成员声明中的’while’标记无效(while循环不起作用)

参见英文答案 > Invalid token ‘while’ in class,struct,or interface member declaration in very simple code                                    5个
我是c#的新手但对c非常熟悉,但这个错误对我来说没有多大意义,因为我已经特别遵循了 http://msdn.microsoft.com/en-us/library/2aeyhxcd.aspx所示的必要语法

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
    int years = 1;
    while (years <=10) {

    public Form1()
    {
        InitializeComponent();
    }

    private void numericupdown1_ValueChanged(object sender,EventArgs e)
    {
        int value = Convert.ToInt32(bushels1.Text);
        numericupdown1.Maximum = value;
    }

    private void bushels1_Click(object sender,EventArgs e)
    {

    }

    private void nextYear_Click(object sender,EventArgs e)
    {

    }
    }
   }
}

解决方法

你有直接在类里面,它应该是一个方法的一部分,你不能直接在类内部编写语句.

public partial class Form1 : Form
{
    int years = 1;
    while (years <=10) {
   //^^

它应该是方法的一部分,如:

public partial class Form1 : Form
{
    int years = 1;
    public void SomeMethod()
    {
       while (years <=10) {
      //rest of your code
    }

C++ while(do-while)循环详解

C++ while(do-while)循环详解

while 循环有两个重要组成部分:
  1. 进行 true 值或 false 值判断的表达式;
  2. 只要表达式为 true 就重复执行的语句或块;

图 1 显示了 while 循环的一般格式,右侧流程图直观地描绘了其工作原理。

while 循环的语句结构及流程图
图 1 while 循环的语句结构及流程图

现在来看一看 while 循环的每个部分。第一行,有时称为循环头,由关键字 while 组成,后跟待测试的条件,括在括号中。条件由任何可被判断为 true 或 false 的表达式表示。接下来是循环体,它包含一个或多个 C++ 语句。

循环的工作原理是,首先判断条件表达式的值,如果它是真的,则循环体中的每个语句都被执行;然后,再次测试条件,如果条件表达式仍然为 true,则循环体中的每个语句将再次被执行。如此循环往复,直到条件表达式被判断为 false。

请注意,与 if 语句一样,在有条件执行的主体中的每个语句都以分号结尾,但在括号中的条件表达式后面没有分号,这是因为 while 循环不完整,后面没有跟随的语句。而且,与 if 语句一样,当循环体包含两个或多个语句时,这些语句必须用大括号括起来。当循环的主体只包含一个语句时,可以省略括号。

基本上,while 循环就像是一个可以执行一遍又一遍的 if 语句。只要括号中的表达式为 true,则有条件执行的语句将不断重复。

下面的程序使用了 while 循环打印“Hello”字符串 5 次。
#include <iostream>
using namespace std;

int main()
{
    int count = 1;
    while (count<= 5)
    {
        cout << "Hello ";
        count = count + 1;
    }
    cout << "\nThat's all!\n";
    return 0;
}
程序输出结果:

Hello Hello Hello Hello Hello
That's all!

分析这个程序。在第 6 行中,整数变量 count 被定义并用值 1 初始化。在第 7 行中,while 循环以下面的语句开头:

while (count<= 5)

该语句测试变量 count 以确定其值是否小于或等于 5。因为它确实小于 5,所以循环体(第 9 行和第 10 行)中的语句被执行:

cout << "Hello   ";
count = count + 1;

第 9 行中的语句将显示字符串“Hello”。第 10 行中的语句则给变量 count 加上 1,使其值变成了 2。这是循环体中的最后一个语句,因此在执行之后循环又一次开始。它再次测试表达式“count<=5”,并且由于仍然为 true,循环体中的语句将再次执行,该循环不断重复,直到变量 count 等于 6,使表达式“count<=5”为 false,然后退出循环,如图 2 所示。

while循环工作原理
图 2 while 循环工作原理

循环的每一次执行称为迭代。以上示例中的循环将执行 5 次迭代,直至表达式“count<=5”被测试并且发现为 false,导致循环终止,然后程序继续执行该循环之后的语句。控制循环迭代次数的变量称为循环控制变量,在上面的例子中,count 就是循环控制变量。

while 是一个预测试循环

while 循环是一个预测试循环。这意味着它会在每次迭代之前测试其状态。如果测试表达式为 false,则循环将永远不会迭代。如果要确保一个 while 循环至少执行一次,则必须初始化相关的数据,使测试表达式一开始即为 true。

例如,注意上面程序中变量 count 的定义:

int count = 1;

count 变量被初始化为值 1。如果数字已经被初始化为大于 5 的值,则循环将永远不会执行,如下面的程序段所示:
int count = 6;
while (count <= 5)
{
    cout << "Hello ";
    count = count + 1;
}

无限循环

除极少数情况外,循环必须包括一种终止方式。这意味着循环中的某些内容必须最终使测试表达式为 false。在上面程序中,当表达式“count <= 5”变为 false 时,循环停止。

如果循环没有停止的方式,则称为无限循环。无限循环将持续重复,直到程序中断,示例如下:
int count = 1;
while (count<= 5)
{
    cout << "Hello ";
}
这是一个无限循环,因为它不包含更改 count 变量值的语句。每次测试表达式“count <= 5”时,count 的值都是 1。

小心分号

通过在 while 循环的第一行之后意外地放置一个分号也可以创建无限循环,示例如下:
int count = 1;
while (count <= 5) ; //该分号是一个错误
{
    cout << "Hello ";
    count = count + 1;
}
因为编译器在发现开始语句块的大括号之前看见了第一行末尾的分号,所以它会在分号的位置结束循环。尤其是它会将分号前面丢失的语句解释为空语句,也就是什么都不做的语句,然后将 while 语句和它后面的任何内容断开。

对于编译器来说,整个循环看起来就像下面这样:

while(count<= 5);

这个 while 循环将持续执行空语句,当然它永远不会执行任何操作。该程序似乎“陷入迷惘”,因为没有任何屏幕输出,也不会显示任何活动。

不要忘记大括号

在编写循环语句时,如果有条件执行的语句是一个语句块,则不要忘记将所有的语句都包含在一组大括号中。如果大括号意外被忽略,则 while 语句有条件执行的仅仅是下一个语句,请看下面的代码示例:
int count = 1;
//该循环忘记使用大括号
while (count <= 5)
    cout << "Hello ";
    count = count + 1;
在这段代码中,只有一个语句,也就是 cout 语句,是在 while 循环的主体中。给变量 count 加 1 的语句不在循环体内,所以 count 的值保持为 1,循环测试条件永远为 true。循环将一遍又一遍地打印“Hello”字符串,直到用户停止程序。

不要混清 == 与 =

循环的另一个常见陷阱是,在打算使用 == 运算符时,却意外地使用了 = 运算符。例如,以下示例就是一个无限循环,因为作为循环条件的测试表达式每次都给 remainder 赋值为 1,而不是测试 remainder 是否等于 1:
while (remainder = 1) //错误:条件表达式为赋值语句
{
    cout << "Enter a number: ";
    cin >> num;
    remainder = num % 2;
}
请记住,任何非零值都将被判断为 true。

do-while 循环

除了 while 循环之外,C++ 还提供了 do-while 循环。do-while 循环看起来类似于把一个 while 循环倒过来。图 3 显示了其格式和流程图,右侧流程图直观地描绘了其工作原理。

do-while循环的语句结构及流程图
图 3 do-while循环的语句结构及流程图

与 while 循环一样,如果循环体中只有一个有条件执行的语句,则可以省略大括号。注意,do-while 循环必须在测试表达式的右括号后用分号终止。

除了外观形式,do-while 循环和 while 循环之间的区别是 do-while 是一个后测试循环,这意味着在循环结束时,也就是在每次迭代完成后,才测试其表达式。因此,即使测试表达式在开始时为 false,do-while 也至少要执行一次迭代。

例如,在以下 while 循环中,cout 语句根本不会执行:
int x = 1;
while (x < 0)
    cout << x << endl;
但是在以下 do-while 循环中的 cout 语句将执行一次,因为 do-while 循环在迭代结束之前不会判断表达式 x<0:
int x = 1;
do
    cout << x << endl;
while (x < 0);
如果要确保循环执行至少一次,则应使用 do-while 循环。

今天的关于whiletrue; 循环在无效时抛出无法访问的代码的分享已经结束,谢谢您的关注,如果想了解更多关于.setVisible(true)立即重绘、c – 构造函数的右括号中无法访问的代码、c#类,结构或接口成员声明中的’while’标记无效(while循环不起作用)、C++ while(do-while)循环详解的相关知识,请在本站进行查询。

本文标签: