c++程序:为什么这个程序运行时候好像没有可执行程序for循环??为什么直接就结束了??

以下试题来自:
单项选择题以下说法中正确的是 ______。A.C++程序总是从第一个定义的函数开始执行的B.在C++程序中,要调用的函数必须在main()函数中定义的C.C++程序总是从main()函数开始执行的D.C++程序中的main()函数必须放在程序的开始部分
为您推荐的考试题库
你可能感兴趣的试题
1A.x+y+z=48B.x+y+z=35C.x+z=35D.不确定值2A.int a=111;B.Myclass(Int x,C.Myclass(D.~Myclass();3A.程序的内部逻辑B.程序的复杂结构C.使用说明书D.程序的功能4A.5B.6C.1D.无限5A.9B.10C.11D.12
热门相关试卷
最新相关试卷为什么执行循环的时候程序就停止运行了呢?_c++吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:269,269贴子:
为什么执行循环的时候程序就停止运行了呢?收藏
#include &stdio.h&#include &string.h&struct student{ char sex[10];};void Judge(student stu);void Display(char );int main(){
student stu1;
char c='y';
Display(c); printf("告诉我您的性别(boy/girl):"); scanf("%s",stu1.sex); if((!strcmp("boy",stu1.sex))&&(!strcmp("girl",stu1.sex)))
printf("输入错误!\n");
} printf("请输入您的身高(单位:cm):"); scanf("%f",&stu1.high); if(stu1.high&=0) {
printf("输入错误!\n");
return 0; } printf("请输入您的体重(单位:kg):"); scanf("%f",&stu1.weight); if(stu1.weight&=0) {
printf("输入错误!\n");
return 0; }
Judge(stu1); printf("继续请输入Y/y,退出请输入N/n"); scanf("%c",c);
}while(c=='y'||c=='Y');
return 0;}void Judge(student stu){
float weight_ if(strcmp("boy",stu.sex))
weight_standard=(stu.high-80.0)*0.7;
printf("标准体重范围为%0.3f--%0.3fkg\n",weight_standard*0.8,weight_standard*1.2);
if((stu.weight&=weight_standard*0.8)&&(stu.weight&=weight_standard*1.2))
printf("您的体重正常!\n");
if(stu.weight&weight_standard*1.2)
printf("您的身体偏胖!\n");
printf("您的身体偏轻!\n");
weight_standard=(stu.high-70.0)*0.6;
printf("标准体重范围为%0.3f--%0.3fkg\n",weight_standard*0.8,weight_standard*1.2);
if((stu.weight&=weight_standard*0.8)&&(stu.weight&=weight_standard*1.2))
printf("您的体重正常!\n");
if(stu.weight&weight_standard*1.2)
printf("您的身体偏胖!\n");
printf("您的身体偏轻!\n");
}}void Display(char ch){ if(ch=='y'||ch=='Y') { printf("\t*************************\n\n\n"); printf("
欢迎使用身材测评系统
printf("\t*************************\n\n\n"); } else {
printf("\t*************************\n\n\n");
谢谢使用身材测评系统
printf("\t*************************\n\n\n");
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或8099人阅读
【C++进阶】(17)
【C++进阶】for循环以及for循环运行机制
for (expr1; expr2; expr3)
第一个表示式只在循环开始前执行一次并且无条件执行。
第二个表示式从第一次执行循环开始就在循环开始前运行做一次判断该表达式布尔值,是真就执行循环,是假就中断。如果第一次循环就是假,直接不执行for体。
第三个表达式从第一次执行循环开始就在每次循环结束后执行一次。
&几乎每种程序设计语言的语法中都会有语句的循环,跳转。像最为熟知的C语言便有 for 、 while 、 do---while 等等。这些循环一般都很容易理解和使用,对于程序中逻辑的实现也很有帮助。
只是很多人不曾知道,这些循环、跳转在计算机内部、在底层是如何实现的,于是在出现问题时还是没有好的解决办法,或者是虽然写出来程序,对于内部的逻辑,却还是隔了一层迷雾。
比如有人对这样一个问题:
for( i=0 ; i& 10 ; i++)
printf(”%i“,i);
for语句里面的 i++ 是什么时候执行的呢? 当循环开始时,是先执行括号里的 i++ 还是printf(”%i“,i)? 也就是说 ,第一个打印的数字是0 还是 1?
我相信这个问题很多人都遇到过,就是当for 循环结束后 i 的值到底是多少不是很确定,在这个问题上犯难,是在不值得。如果你也曾有过这种疑问,那么这篇文章就很值得继续看下去。
这篇文章将拨开迷雾,让你看到循环的本质。
这篇文章主要谈一下C中的这些循环, 跳转语句的内部实现机制。通过深入了解他们的内在,将让你在编程的时候逻辑更加清晰,出现问题的时候也更容易排查。
注:这篇文章中会涉及到一些基本的汇编知识,我们将通过分析&for 、 while 、 do---while &等的汇编表示形式,来弄清楚他们的实现机理。
&if--else是基本的条件转移控制指令,也可以说是程序循环跳转实现的基础。
先看一个具体的例子,函数absdiff()比较两个参数x,y 的大小,返回他们差的绝对值。
我们创建了对于的C语言版本(a)、goto形式的版本(b)、 以及其对应的汇编形式(c):
创建goto版本是为了能更好的理解他的汇编形式。因为里面的goto语句很类似于汇编中的跳转语句。
(a)中 的C代码应该不用多做解释了吧,大家应该都能看懂。
(b)中的got0语句形式:第4 行是一个跳转语句,跳转到执行第8 行。也就是说当第3 行的条件满足的时候,跳转到第8 行执行。如果第3 行的条件不满足,则执行第 5 行的语句。 然后无条件跳转到代码的结尾:“ goto done;” 使用goto 语句通常被认为是一种不好的 编程风格,因为这样的语句通常难于调试和阅读,这里使用goto语句是为了构造出一种类似汇编实现的C语句。
(c)就是我们要讨论的重点了。其实条件跳转指令的汇编形式和他的goto形式有一定的相似之处。有语句跳转的时候都是这样的过程:先判断是否满足某个条件,如果满足,则跳到一个指定的的代码段继续执行程序,如果不满足,则执行另一条语句。
为了弄清楚它内部是如何实现的,现在我们来详细看一下他的汇编指令形式(c)
程序的 1 、2 行取得x y 的值。放在寄存器 edx eax 中,第三行比较x y 的大小(也就是比较edx eak &的大小)如果x & y 则跳到 .L2的地方执行(8 、9 行)执行x - y ,并将结果放在返回值中,然后程序顺序执行到程序结束处 .L3,反之,如果第三行判断结果是x&y ,则语句不会跳转,顺序执行y-x,并跳转到程序结束处 .L3.
现在,我们基本了解if --else 的执行机理了。主要是先判断条件值,从这个例子出发就是第 3 条语句: cmpl &%eax,%edx。学过汇编的同学应该知道,cmpl是一条比较指令,他的执行会影响标志位。做个简单的假设: cmpl & & A,B 是比较A,B两个数的大小,比较结果存放在标志位 F 中,当A&B时,F为0,A&BF为1。 后面的jge &.L是跳转语句,他的执行是和上一步比价的结果相关的,这里也就反映在标志位F 当中。当F 为1时(A&B),则跳转到 .L2执行 B-A。当比较结果为A&B
查看后标志位为0,则jge不跳转, 程序继续往下执行。
C中的if --else 的通用模板是这样的:
这里的 test-expr 是一个整数表达式,它的值为真(1、&0)则会执行第一个分支语句 , 否则执行第二个。但不管怎么样,都只会执行其中的一个。
对于这种模板,汇编的实现通常会用下面的形式:(这里用C语言描述)
汇编器会为 then-statement 和else-statement产生各自的代码快 ,通过条件跳转来执行相应的代码。
注意:程序并不是智能的,执行跳转的时候只会有两种判断(真和假),而且内部的跳转形式都是基于 go to 模式。所以说虽然goto 在编程中要少用,但在理解程序跳转的时候还是很重要的。我想因为goto 的实现方式和程序最终的实现方式如此的相似,才在C中引入goto 吧。
do---while
C中提供了多中循环结构,do-while &while 和 for ,然而汇编中没有相应的指令存在。通过上面对 if -else 的分析, 已经知道了 C 中条件跳转在汇编中的基本实现方式(goto),现在要讨论的这些循环,在循环中都有一个条件判断的环节,当条件满足时,继续循环体, 如果条件不满足,则跳出循环体。和if-else 不同的在于这里的条件表达式可能会有改变,也就是每次判断的条件和上次不同。
只要理解了上面的if-else 的内容 ,其他的循环都能通过对if -else 的改进来实现。先给出这些循环的goto 形式,就能很快推测出其内部的实现方式。
通用形式:
do-while的通用形式如下:
  body-staement
  while(test-expr)
这个循环的效果就是反复执行 body-staement,对test-expr进行求值,如果求值结果不是0 则继续执行。可以看到,body-statement至少会被执行一次。
do-while 的通用形式可翻译为 如下所示的goto 语句:
  body-statement
  t=test-
对于上面的goto形式, 可以先想想汇编会是如何实现的:把loop里的代码放在一个单独的代码段里面(包含if 的判断跳转部分)程序顺序执行下来,第一次执行不用判断条件。执行玩body-statement后判断条件,如果满足,则继续这个循环。
好了,下面看一个具体的例子:
这是一个计算阶乘的函数实现,
&(a)是c代码, &
(c)是对应的汇编形式
(b)是汇编中寄存器和变量的映射关系
(a)中的代码比较简单就不在解释了。现在看(c)中的代码:
第 1 行是获得函数参数n的值,放在寄存器 edx 中,第 2 行设置 result =1 &第 3 行的 L2 表明这是一个循环体。 (c) 中的第 4、 5 行实现了 (a)中 5、 6 行的功能。
(c)中的第6 行判断循环的条件,如果条件满足,则执行第 7 行 的跳转语句。
和do- while的通用形式所描述的一样,body-staement至少会被执行一次,这从汇编代码中也有体现,观察循环体 L2,在L2 没有关于L2 的跳转代码,也就是说在程序顺序往下执行的情况下,L2 至少会被执行一次,然后在 L2 内部判断是否继续执行循环体 L2。
&whil循环和do-while类似,他的通用形式如下:
while(test-expr)
  body-statement
和do-while不同的是,他先对test-expr求值,所以body-statement可能一次都不被执行。将while翻译为机器码有多种方法,其中一种常见的方式i就是把他翻译成do-while的形式。在第一次执行循环体之前加一个判断条件,如果条件满足,则进入do-while的循环体,如果不满足,直接跳过循环体。也就是上面说的:body-statement可能一次都不被执行。
下面先把while转换为do-while循环:
if(!test-expr)
  body-statement
  while(test-expr);
接下来可以吧这个do-while循环转换为goto语句:
  body-statement
  t=test-
这个goto的版本和do-while的版本只是在循环体loop的前面加上了一个判断条件,如果条件满足, 就执行上面中的do-while循环体,如果不满足,直接跳过循环。
通过上面的goto版本,现在应该可以想一下while 的 汇编是如何实现了吧:
现在就可以猜测,while 的汇编只是在do-while汇编的基础上做出一些改动:在循环体loop之前加一个判断条件,如果条件成立,则执行loop,不成立则跳过loop。
下面还通过一个具体例子来说:
还是计算n 的阶乘,不过这次是用while实现
下面是C代码:
这很简单,就不做解释了,下面看他的goto形式:
和上面描述的一样,在3、4 行中加入了条件判断,如果条件不满足 第5行直接跳攻loop循环体,只有当条件满足时才进入循环体loop。再看loop中,7、8 行执行计算阶乘的必要操作,9、10行通过判断test-expr 决定是否继续循环。
好,下面来看while的汇编形式:
现在看汇编代码应该比较有经验了吧,这里的3、4 行执行条件判断,决定是否进入循环体.L10,相当于goto版本中的4、5 行,如果不满足,直接跳转到.L7的位置。
再看一下.L10 循环体:6、7 行执行阶乘的必要操作,相当于goto中的 7、8 行,这里的8、9 行判断循环是否继续,相当于goto中的9、10行。
for循环的通用形式如下;
for(init- test- update-expr)
  body-statement
大概在学C的时候会提到for 循环可以用while 来表示:
while(test-expr){
  body-statement
  update-expr
程序首先初始化表达式init-expr的值,然后进入循环,再循环中先对测试值test-expr求值,如果为假,则退出循环,否则执行循环体body-statement,并更新表达式update-expr的值。
基于前面讲过的do-while到while的转换,先给出do-whle形式:
然后将它转为goto代码:
和上面一样,我们将用一个实例来说明问题:
考虑用for 循环写的阶乘函数
用for循环写的计算阶乘的函数是从2 开始,这和前面的从1开始不同,不过这并不影响其逻辑实现的结构,这段代码中,for循环的组成如下:
通过上面的分析,可以得到其goto形式:
到现在为止 ,已经在实例中给出了他的C 形式和goto形式,现在请看他的汇编形式:
上面都解释了很多,这里就不在解释这个汇编指令了,通过上面应该都能看懂。
开始的问题
到现在,应该弄清楚文章开头所说的问题了吧
for( i=0 ; i& 10 ; i++)
printf(”%i“,i);
现在应该了解什么时候执行 i++ 设么时候执行printf(”%i“,i); 了吧。
按照我们的分析,执行顺序应该是这样的:
1、 初始化 i=0
2、判断条件是否满足 i&10 是否成立
3、如果成立则执行循环体printf(”%i“,i); 并执行自加运算 i++
可以这段代码在自己的编译器中运行一下,看首先打印出来的是0 &还是1 &(按照我们的分析,应该从0 开始答应哦)
&其实这篇文章阐述的道理很简单,就是C 语言中循环的实现问题。如果你在linux环境下操作的话,要理解这一部分就更容易了,在linux下可以直观的看到一个程序编译后的汇编形式,在自己电脑上分析自己的程序,这样学起来才更有兴趣,更深刻。
简单介绍:
linux下编译器:GCC、
可执行文件查看器:objdump、还有一个好像是 elfread,不确定了。
如果调试上面的for语句的话,可以用gdb调试器,这样能让程序一步步执行,并且跟踪变量的值。关于linux下的这些命令这里不是本文重点,不再介绍。
参考:http://blog.csdn.net/ownfire/article/details/6996176
&&/yanlingyin/archive//2419304.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:335683次
积分:4175
积分:4175
排名:第5810名
原创:66篇
转载:120篇
评论:48条
(1)(1)(1)(6)(2)(5)(1)(8)(2)(3)(3)(3)(2)(13)(2)(11)(14)(34)(23)(24)(3)(3)(5)(1)(1)(9)(1)(1)C/C++程序设计 -
ChinaUnix.net
谈到实时,大家很容易想到春节“走红”的微信红包吧!2015年春节联欢晚会上...
24日10日08日07日06日06日03日
张友东网名zyd_cu,人气博主
目前任淘宝核心系统部TFS的开发工作, 毕业于华中科技大学,研究生阶段主要从事分布式...
高 峰2011 CU博客年度贡献博主
现任职于A10 Networks公司SLB方向软件工程师,热爱技术,原创技术文章达到180以上,乐...
江均勇驱动与软件开发
国内某网络安全民营企业产品总监,研究设计开发了国内首款透明代理架构Web应用防火墙...
刘歧图形系统 Linux内核
爱好Linux平台软件开发,擅长图形系统,Linux内核,嵌入式系统,Linux软件研发,目前...
联系方式:010--}

我要回帖

更多关于 可执行程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信