精华内容
下载资源
问答
  • Python中什么情况使用for和while循环
    2021-07-07 16:21:33

    对于固定次数的情况下的循环 for 循环更加的好用

    而对于不固定次数,或者次数不明的情况则使用 while 循环更加的方便。

    更多相关内容
  • python打印三位数水仙花数的时候。 i=100 while i a=i//100 b=(i-a*100)//10 ... 为什么a,b,c三个式子要放在while里面而不是while外面呢?? 本人尝试过放在外面,但是无法输出。
  • 虚假唤醒 Spurious wakeiups 指 :在线程的 等待/唤醒 的过程中,等待的线程被唤醒后,在条件满足的情况依然继续向下运行了。 Java官方给的Api 的代码块如下 synchronized (obj) { while (<condition does not ...

    虚假唤醒<spurious wakeups>

    -----写在前面: 最近学习java因为这个问题困扰了好几天,结果发现是因为一个特别明显的原因。因此写下这篇文章提醒自己! 与君共勉!

    虚假唤醒 Spurious wakeiups 指 :在线程的 等待/唤醒 的过程中,等待的线程被唤醒后,在条件不满足的情况依然继续向下运行了。

    Java官方给的Api 的代码块如下

    synchronized (obj) {
             while (<condition does not hold> and <timeout not exceeded>) {
             	//.....省略.......
                 obj.wait(timeoutMillis, nanos);
             }
         }
    

    那么,为什么官方推荐使用 while 关键字 而不是 if 关键字呢?

    while or if ?

    我们先看以下代码

    public class WhyWhile {
    
        //判断线程是否运行的条件,
        static int control;
    
        //锁对象;
        static final Object lock = new Object();
    
        //主线程;
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
    
            //只有control == 1才打印的线程;
            new Thread(() -> {
                while (true) {
                    synchronized (lock) {
                        **while** (control != 1) {
                            System.out.println("A wait 前");
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("A wait 后");
                        }
                        System.out.println("== 1");
                        lock.notifyAll();
                    }
                }
            },"Thread-1").start();
    
            //只有control == 2才打印的线程;
            new Thread(() -> {
                **while** (true) {
                    synchronized (lock) {
                        while (control != 2) {
                            System.out.println("B wait 前");
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("B wait 后");
                        }
                        System.out.println("== 2");
                        lock.notifyAll();
                    }
                }
            },"Thread-2").start();
    
            while (true) {
                control = sc.nextInt();
                //输入后,通知所有需要lock的线程
                synchronized (lock) {
                    lock.notifyAll();
                }
            }
        }
    }
    

    以上代码包含了 三个线程 :main,Thread-1(下文用 线程1 代替),Thread-2(下文用 线程2 代替)。以上代码简要如下

    control == 1线程1 打印 “ == 1”
    control == 2线程1 打印 “ == 2”
    control != 1 and control != 2线程 1 和 线程 2 进入到等待状态
    main 线程是用来 设置 数字control,之后通知所有线程

    运行以上代码;
    输入1后,我们可以看到如下结果;
    运行-等待输入
    这说明:当前 线程1线程2 都进入到了等待状态;

    尝试输入一个1
    输入1
    可以看到 输入1以后,线程1 被唤醒,从lock.wait()下一行开始运行,也就是从等待后的位置开始运行;

    继续往下看结果,可以看到如下
    线程2也被唤醒
    可以看到,线程2在次过程中也被 lock.notifyAll()唤醒过 (这里指 线程1 的代码块中的notifyAll)

    如过我们把 线程2 中的 while 换成 if 呢?

            //只有control == 2才打印的线程;
            new Thread(() -> {
                while (true) {
                    synchronized (lock) {
                    //只把 while 修改成了 if
                       if (control != 2) {
                            System.out.println("B wait 前");
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            System.out.println("B wait 后");
                        }
                        System.out.println("== 2");
                        lock.notifyAll();
                    }
                }
            }).start();
    

    接下来我们再运行一次,同样输入 1;

    更改了while为 if后得到结果片段

    可以看见,有时候 线程2 也会被唤醒后输出结果; 这明显出现了 错误结果

    错误结果分析

    在进行错误结果分析前需要记住通过以上代码得到的两个结论:

    1. 线程被唤醒后,会从 wait() 处开始继续往下执行;
    2. while 被掉换成 if 后出现了虚假唤醒,出现了我们不想要的结果;

    While 和 if 特点

    if(condition){
    	代码块.....
    }
    输出语句....
    

    如上,if 判断condition为 true后,会
    先执行代码块,再执行输出语句
    先执行代码块,再执行输出语句
    先执行代码块,再执行输出语句

    通过这一条,我们分析 线程2 的while被替换成if后,以及替换前的代码的运行顺序;

    首先是 if

                        if (control != 2) {
                            System.out.println("B wait 前");
                            try {
                            	//1.在这等待
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //2.被唤醒后输出"B wait 后";
                            System.out.println("B wait 后");
                        }
                        //3.跳出if输出"== 2";
                        System.out.println("== 2");
                        //4.通知其他需要锁的对象;
                        lock.notifyAll();
    

    然后 while 呢?

    					//3.回到while条件继续判断
                        while (control != 2) {
                            System.out.println("B wait 前");
                            try {
                            	//1.在这等待
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //2.被唤醒后输出"B wait 后";
                            System.out.println("B wait 后");
                        }
                        //运行不到,
                        System.out.println("== 2");
                        lock.notifyAll();
    

    if 和 while 不同的判断逻辑让使用 while 可以避免虚假唤醒,因为唤醒后继续向下运行,还是需要再次判断条件。而 if 就 直接运行下去了,如果要使用 if 避免虚假唤醒,需要与else搭配使用(如下),或者直接把正确的输出语句放入if代码块中;

                        if (control != 2) {
                            System.out.println("B wait 前");
                            try {
                            	//1.在这等待
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //2.被唤醒后输出"B wait 后";
                            System.out.println("B wait 后");
                        }else{
                        	System.out.println("== 2");
                        	lock.notifyAll();
                        }
    

    总结

    1. 线程如果进入等待状态,被唤醒后从wait()开始向下继续执行代码;
    2. 如果要用 if 判断线程的运行条件,最好与else相结合;
    展开全文
  • #includemain(){chara;scanf_s("%c",&a);while(a!...}运行结果是循环停止,但是跳出来,知道为什么。解决方案10不要使用while(条件)更不要使用while(组合条件)要使用while(1){if(条件1)br...

    #include

    main(){

    char a;

    scanf_s("%c", &a);

    while (a!= "@")

    {

    scanf_s("%c", &a);

    printf("kek ");

    }

    printf("oo ");

    }

    运行结果是循环能停止,但是跳不出来,不知道为什么。

    解决方案

    10

    不要使用

    while (条件)

    更不要使用

    while (组合条件)

    要使用

    while (1) {

    if (条件1) break;

    //...

    if (条件2) continue;

    //...

    if (条件3) return;

    //...

    }

    原因是前两种写法在语言表达意思的层面上有二义性,只有第三种才忠实反映了程序流的实际情况。

    典型如:

    下面两段的语义都是当文件未结束时读字符

    while (!feof(f)) {

    a=fgetc(f);

    //...

    b=fgetc(f);//可能此时已经feof了!

    //...

    }

    而这样写就没有问题:

    while (1) {

    a=fgetc(f);

    if (feof(f)) break;

    //...

    b=fgetc(f);

    if (feof(f)) break;

    //...

    }

    相似的例子还可以举很多。

    10

    printf里面的%和变量的一一对应关系

    scanf里面的%和变量以及变量前加不加&的一一对应关系

    是C代码中非常容易出错的地方,而且通常编译还不出错。

    所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

    在每个最后不带\n的printf后面加fflush(stdout);

    在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin);

    另外请检查scanf的返回值。

    //请今后要用

    char c;

    scanf("%c",&c);

    //时,都改为

    char s[2];

    char c;

    scanf("%1s",s);

    c=s[0];

    10

    scanf_s要指定每个对应“c”、“s”以及传说中的“[”格式的缓冲区的大小。

    char c;

    scanf_s("%c", &c, 1); // 思考题:为什么不用sizeof?

    引用:

    Quote: 引用:

    //请今后要用

    char c;

    scanf("%c",&c);

    //时,都改为

    char s[2];

    char c;

    scanf("%1s",s);

    c=s[0];

    诶,这段代码没看懂,为什么啊?

    本意是为了“吃”掉换行,和在之后加fflush(stdin)的做法相似(但fflush“吃”得更多)。

    然而这“都”字散发着浓郁的经验主义(教条主义)的气息。

    10

    引用:

    是原因是sizeof返回的是字节大小,所以不行?(一本正经的胡说八道)本人也不知道

    这个系列要的“缓冲区大小”指的是“能容纳的字符个数”而不是“字节个数”。

    窄字符版本要的是char的个数,宽字符版本要的是wchar_t的个数。

    所以对于数组缓冲区(buf),直接sizeof(buf)是错误的;sizeof(buf)/sizeof(buf[0])、_countof(buf)之类才是正确的。

    而对于单个字符的缓冲区,1个char c的大小就是1,1个wchar_t c的大小也是1;sizeof(c)一则多余,二则对于后者是错误的。

    CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明这个while循环终止了却跳不出来为什么!

    展开全文
  • c++中while(cin)不能执行的问题

    千次阅读 2019-03-20 22:21:12
    前几天在链表实现大整数求和的时候,因为要输入两个大整数,我接连使用了两个while(cin),但是运行的时候,却只能输入第一个整数,当第一个整数输入并回车后程序就直接就运行完毕,并没有输入第二个数的机会。...

     

     

    前几天在用链表实现大整数求和的时候,因为要输入两个大整数,我接连使用了两个while(cin),但是运行的时候,却只能输入第一个整数,当第一个整数输入并回车后程序就直接就运行完毕,并没有输入第二个数的机会。

    结果如下:

    当时的代码:

    # include <iostream>
    # include <vector>
    using namespace std;
    struct ADD
    {
    	int number;
    	struct ADD *next;
    };
    int main()
    {
    	vector<int> result;
    	struct ADD *head_a = new ADD, *head_b = new ADD, *p, *p1, *p2, *q, *q1, *s, *temp;
    	int count_a = 0, count_b = 0;
    	s = p = head_a; q = head_b;        //头插法保存头结点
    	head_a->next = NULL; head_b->next = NULL;
    	p1 = new ADD;
    	cout << "请输入第一个加数(每位数之间加一个空格且输入n结束):" << endl;
    	while (cin >> p1->number) {                                      //*********************第一个while(cin)
    		count_a++;
    		p1->next = head_a->next;
    		head_a->next = p1;
    		p1 = new ADD;
    	}
    	cout << "请输入第二个加数(每位数之间加一个空格且输入n结束):" << endl;
    	q1 = new ADD;
    	while (cin >> q1->number) {                                      //***********************第二个while(cin)
    		count_b++;
    		q1->next = head_b->next;
    		head_b->next = q1;
    		q1 = new ADD;
    	}
    	if (count_b > count_a) {
    		temp = p;
    		p = q;
    		q = temp;
    	}
    	s = p = p->next;
    	q = q->next;
    	while (q) {
    		if ((q->number + p->number) < 10) {
    			p->number = q->number + p->number;
    		}
    		else {
    			p->number = (p->number + q->number) % 10;
    			if (p->next) {                      //检测是否p->next还有值,如果位数相等则访问会有冲突
    				(p->next)->number++;
    			}
    			if (!p->next) {                    //p->next为空即证明位数相等,因为已经确定p>=q的长度,加一个一
    				p2 = new ADD;
    				p2->number = 1;
    				p->next = p2;
    				p = p2;
    				p->next = NULL;
    			}
    		}
    		p = p->next; q = q->next;
    	}
    	while (s) {
    		result.push_back(s->number);
    		s = s->next;
    	}
    	for (auto c = result.rbegin(); c != result.rend(); c++) {
    		cout << *c;
    	}
    	system("pause");
    	return 0;
    }

    后来想到以前在使用stringstream流时每使用一次都要用到.clear()来清空流中的数据,但是加了之后还是不起作用,当时感觉那叫一个崩溃,后来请教学长才知道,原来还需要一个.ignore()

     

    cin.clear();   //清除错误状态 
    cin.ignore();//跳过无效数据

     

    在两个while(cin)加入上边两行就正确了:

    仔细想了想,问题就处在cin输入流对象上。cin是一个输入流对象,当进行第一个while循环时我输入了一个字母来结束循环,而最后输入字母完全是为了结束输入数字,这个字母没有任何的意义,所以加上cin.ignore()来路过无效数据,而此时第二个while(cin)因为使用同一个cin对象,所以也被判断为假,造成第二个循环不能执行,因此,要加上cin.clear()来清除错误状态,才能使第二个while(cin)能够正常执行。

    这个以前真的时没注意过,发上来分享一下。

    展开全文
  • java多线程wait时为什么用while而不是if

    千次阅读 多人点赞 2018-11-06 17:44:52
    从上面的截图,我们可以看出,在使用wait方法时,需要使用while循环来判断条件十分满足,而不是if,那么我们思考以下,如果使用if会怎么样? 为方便讲解,我们来看一个被广泛使用的生产消费的例子。代码部分参考 ...
  • 遇到一个BUG: scheduling while atomic: kworker/0:2/370/0x00000002;看了这篇文章BUG: scheduling while atomic 分析...先看下为什么会打印出这句: schedule() -> __schedule() -> schedule_debug() s...
  • 知识点:for循环,while循环 思路:在第一层循环中依次遍历数组,遇到0时,后位依次往前挪一个位置;因为数组中0的数量是未知的,如果遇到连续的两个0,则第二个零依然在数组里,所以这里用到while,同时加个计数器...
  • 大家用的最多的循环语句肯定是for,那能不能用while模拟一下for完成一些循环? 如题,用while去模拟for,打印数组的全部元素 let arr = [1, 2, 3]; for(let i = 0; i < arr.length; i++) { consoel.log(arr[i]);...
  • } 2.for语句的注意事项 (1)各表达式之间分号不能省略 (2)表达式1与表达式2与表达式3均可省略,一般是不省略的。 ①当表达式1省略时,相当于省去了为循环变量赋初值,此时应在for语句之前给循环变量赋初值 ②当...
  • 作为一个新手,才下载好vs code,设置中文的时候显示error while fetching extensions.xhr failed,不能使用扩展(图是后来截的图,报的错不一样) 我也是找了很久才找到方法,原因很简单,打开此电脑,在c盘中...
  • while循环使用方法

    千次阅读 2021-06-22 19:37:43
    while循环使用方法2019-11-01 08:53:38文/陶凯月while是计算机的一种基本循环模式。可是有什么用法呢?下面就和小编一起了解一下吧,希望对大家有所帮助。while循环的用法while循环开始后,先判断条件是否满足,如果...
  • while循环的基本用法: 基本格式: while (表达式) 语句A; 使用范围: while也是只能控制一个语句,若要控制多个语句则需要加{}花括号。 注意: while 与for循环是可以相互转化的。 如: for(1; 2...
  • 详解python基础之while循环及if判断

    千次阅读 2021-02-03 10:11:32
    wlile循环while True表示永远为真,不管是什么条件都会向下执行,下面是写的一个例子。 #!/usr/bin/env pythonage = 24 #给age赋一个值while True: #进入循环inputting = int (input("The input number i...
  • MFC中做了一个while循环,利用一个标识变量(flag=1)。现在发现当while执行的时候,其他的按钮都不能动。所以也没有办法改变标识,即使按了stop的按钮,修改标识(flag=0)也没有办法退出while循环。
  • break语句用于终止循环,可以while循环和for循环中,当循环条件为False或者序列还没有完全被迭代完毕时,使用break语句也可以使循环停止执行。在for循环使用break在下面这个例子中,正常运行结果应该输出1到10...
  • python中的while循环和for循环的使用

    千次阅读 2021-02-02 22:55:19
    while语句包含几部分组成关键字条件(求值为true或flase的表达式:换句话说就是判断语句)以冒号结尾从新行开始时,缩进的代码块,被称为(while的子句)代码举个例子:a=0while a<9:print("输出了”)a+=1最后输出...
  • word)这种循环时,编译运行往往会出现循环不能终止的状况,所以我们有了不知道如何结束这种循环的疑惑。   在 Unix 系统中的实际的现象为:  * 当输入为“字符串,回车,Ctrl+D”的时候,跳出循环; * 当输入...
  • 当有多个消费者的时候,还使用if判断是否await就会产生问题,这是因为一个生产者消费者模型的任务队列,一个消费者一次放入多个任务,然后notifyAll通知消费者,但是并非所有被唤醒的消费者都取到一个任务,那么...
  • 一、while循环while 条件: 如果条件为True,会一直循环代码块(循环体)else:当上面的条件为假。才会执行执行顺序:判断条件是否为真。如果真,执行循环体。然后再次判断条件....知道循环条件为假,程序退出。死循环:...
  • while语法 while (条件) { 要执行的代码块 ...不能忘记i++ 语句,否则会变成死循环。 dowhile语法 do { 要执行的代码块 } while (条件); 例子: var i=0; do{ console.log(i) i++; } ...
  • while(true)何时跳出循环?

    千次阅读 2021-02-13 01:00:33
    while(true)是不会跳出循环的。在while中括号里为一个条件值,只要当条件为真的时分,会执行这条语句,直到条件为false的时分,则会跳出该循环语句。而在这里括号里的值为true,也就意味着会不断执行该条语句。除了...
  • 在多线程的编程实践中,wait()的使用方法如下: synchronized (monitor) { //判断条件是否得到满足 while(!locked) { //等待唤醒 ...那为什么非要while判断,而采用if判断呢? synchronize...
  • 假设有三个线程ABC,A为生产者线程,B为消费者线程,C为破坏者线程。三个线程都进入一个共享对象的方法(当然不是...如果是while一样了,就会继续检查条件。1.容器类EventStoage.javapackage sss; import java....
  • if 和 while使用区别

    千次阅读 2020-11-22 15:15:09
    欢迎使用Markdown编辑器 项目场景: 提示:这里简述项目相关背景: 例如:项目场景:示例:通过蓝牙芯片(HC-05)与手机 APP 通信,每隔 5s 传输一批传感器数据(不是很大) 问题描述: 提示:这里描述项目中遇到的问题...
  • while的用法_C语言中while的用法

    万次阅读 2021-05-19 05:44:46
    c语言中while的用法当n==1时执行while循环结构里的语句,当n等于1时,则跳过该循环执行循环体外的语句。while 循环的格式:while (表达式){语句;}while 循环的执行顺序:当表达式为真,则执行下面的语句,语句...
  • 说实话,第一遍看这个概念并没有看懂,第二遍硬磕了一下,发现原来...while(){…}如果说满足了条件,那么就会进入大括号里面,在里面呆了一段时间,要想出来那得先去while判断一下,如果满足,还是不能出来。 即if...
  • 而这些方面的差异,又是比较细微的,所以往往在学的时候依靠经验很快理解,但过后却发现并未使(掌)(握)。 do / while循环的意义,其实就是重复执行语句,当然,还会有相应的条件判断,不然就成死循环了。...
  • 首先你要确定for和while里面的各个字段分别表示什么含义: Python 中的循环语句有 2 种,分别是 while 循环和 for 循环 for 循环语句的执行流程如图 1 所示。 for 循环语句的执行流程图 图 1 for 循环语句的执行...
  • while(1) 什么意思 while(i--)什么意思? 在C++语言中,i++与++i有什么区别?那i--和--i呢while(1) 什么意思 while(i--)什么意思? 在C++语言中,i++与++i有什么区别?那i--和--i呢相关问题:匿名网友:while语句的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 998,343
精华内容 399,337
关键字:

while什么时候不能用