Mohican_12/10 C语言—分支结构

课堂内容

PART A:基本数据类型和输出语句

1.关于scanf的扩展,了解getchar(),缓存区,加深。

引入 :不推荐使用scanf

scanf 的定义

scanf函数的一些陷阱

举例情况:

1.输入 scanf(“%d,%d”,&a&b);

输出结果

A是正常 但是B为”随机数”,原因?

以下,从 MSDN 中节选:
[1] Characters outside format specifications are expected to match the sequenceof characters in the input stream;

就是说,你写的"%d,%d,%d,%d" 中的逗号,被期待在你的输入中出现。

[2] the matching characters in the input stream are scanned but notstored.

就是说,你写的逗号仅仅会被扫描(不会被存储到某个 field 之中)。

[3] If a character in the input stream conflicts with the formatspecification,scanf terminates, and the character is left in the inputstream as if it had not been read.

。重点是,你的输入 "1 2 3 4 ...",和你写的指定格式“%d,%d,%d,%d" 首次发生冲突时,scanf 就会终止。其余字符停留在输入缓冲区中。

因此,你写的代码,在扫描到空格时, a 会被赋值。然后 scanf因为需要扫描到一个逗号,但是输入流缓冲区中当前位置不是逗号,于是 scanf 就结束了。后面的 b,c,d 没有被赋值。

简而言之:bcd都匹配失败了,没有改变,又因为没有初始化,所以是随机数

代码:

#include<stdio.h>

int main()

{

    int a ;

    int b;

    scanf("%d ,%d",&a,&b);

    printf("%d %d\n",a,b);

return 0;

}

2.输入scanf(“%d%d”,&a&b);

正常输入结果

代码:

#include<stdio.h>

int main()

{   int a ;

    int b;

    scanf("%d %d",&a,&b);

    printf("%d %d\n",a,b);

return 0;

}

3.在定义变量的同时初始化,也是正常输出,程序如下:

#include<stdio.h>

int main()

{

    int a =4 ;

    int b=5;

    printf("%d %d\n",a,b);

return 0;

}

2.%d换成%c后

#include<stdio.h>

int main()

{

    char a ;

    char b;

    scanf("%c ,%c",&a,&b);

    printf("%d %d\n",a,b);

 

return 0;

}

程序输出正常

(1)    scanf格式控制串"%c %c"之间有空格(逗号)时,输入的数据之间可以有空格间隔。这时候我们应该这样输入’a’空格’(逗号)b’。

(2)  空格,回车,跳格等结束符在输入前碰到的话,会自动抛弃,输入后碰到的话,就会认为结束。

(3)  以上是针对除了%c而言的

对于%c,遇到这些字符都会读取的。

Getchar 可以吃回车

如果输入:

scanf(“%c”,&m);
scanf(“%c”,&n);
输入a[回车]b的话
就会使m=a,n=回车
但如果中间加上getchar()
得到m=a,n=b,

所以一般用getchar来吃回车时,是用在%c后面。

那么接下来,关于scanf和getchar以及缓存区的影响,扩展一下。

1. getch getche getchar的区别和缓冲区的概念http://blog.csdn.net/cxyol/article/details/628324

2. c语言学习笔记--chapter0-getchar,scanf以及缓冲区的概念

http://blog.chinaunix.net/uid-20568790-id-1632289.html

 

2、常量和变量

 

 3、数据类型

 

4、整型数据

 

5、字符型数据

 

 6、浮点型数据

 

 7、强制类型转换

 

PART B

1. if else语句

a. 单分支 (执行这个操作;跳过它)

 

b. 双分支(两个不同的操做,选择一个来执行)

 

c. 多分支(多个不懂的操作,选择一个来执行)

 

d. If else 和 else if

 

if(条件句)+执行句
else +
执行句
end

如果条件句成立,则执行if 后面的执行句。如果不成立,则执行esle后面的句子;
if
(条件句1)+执行句
elseif
(条件句2)+执行句
else +
执行句
end

如果条件句1成立,则执行if后面的执行句,如果条件句1不成立,然后条件句2成立,则执行elseif后面的执行句,如果条件句1和条件句2都不成立,则执行else后面的执行句。

 

2. switch 语句

switch(表达式 1)---常量表达式

{ case 常量表达式 1: 语句块 1; break;

 case 常量表达式 2: 语句块 2; break;

 ....

default: 语句块: break; }

从表达式值等于某个case语句后的值开始,它下方的所有语句都会一直运行,直到遇到一个break为止。随后,switch语句将结束,程序从switch结束大括号之后的第一个语句继续执行,并忽略其他case
假如任何一个case语句的值都不等于表达式的值,就运行可选标签default之下的语句。假如表达式的值和任何一个case标签都不匹配,同时没有发现一个default标签,程序会跳过整个switch语句,从它的结束大括号之后的第一个语句继续执行。

 

PART C

课堂问题:

1. 关于sizeof ()的使用

int main()

{int a = 10;

    int n = sizeof(a++);//sizeof(a++)

    printf("%d,%d\n",a,n);

    return 0;}

程序输出: 10;4


sizeof()函数在预处理的时候就执行了, ()里面的表达式不参与运算

a++ 中,a在定义的时候就是一个整形变量, 在预处理的时候相当于 int n = 4,但是没有执行a 的自增运算,所以输出还是4 ?

2. switch 表达式

switch()//表达式

{case ;}//常量  为什么float,double不可以

选自:https://stackoverflow.com/questions/15572657/why-can-switch-only-compare-to-const-values#

总结如下:

因为在编译时进行类型检查,编译的时候就应该知道值是什么
函数在运行时候才知道返回值,变量运行的时候才知道值是什么,所以不能。

switch(myVar)

{

case(label):

   ...

   break;

}

3. switch 和 if else 区别

switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch...case不用像if...else那样遍历条件分支直到命中条件,而只需访问对应索引号的表项从而到达定位分支的目的。
具体地说,switch...case会生成一份大小(表项数)为最大case常量+1的跳表,程序首先判断switch变量是否大于最大case 常量,若大于,则跳到default分支处理;否则取得索引号为switch变量大小的跳表项的地址(即跳表的起始地址+表项大小*索引号),程序接着跳到此地址执行,到此完成了分支的跳转。

 

4. if 和switch那个效率更高 (深入理解计算机系统)

switch有点以空间换时间的意思.

a.     当分支较多时,当时用switch的效率是很高的。因为switch是随机访问的,就是确定了选择值之后直接跳转到那个特定的分支,但是if。。else是遍历所以得可能值,知道找到符合条件的分支。如此看来,switch的效率确实比ifelse要高的多。

b.    .由上面的汇编代码可知道,switch...case占用较多的代码空间,因为它要生成跳表,特别是当case常量分布范围很大但实际有效值又比较少的情况,switch...case的空间利用率将变得很低。

c.     switch...case只能处理case为常量的情况,对非常量的情况是无能为力的。例如 if (a > 1 && a < 100),是无法使用switch...case来处理的。所以,switch只能是在常量选择分支时比ifelse效率高,但是ifelse能应用于更多的场合,ifelse比较灵活

5. const 和 define的区别

a. define 实在编译预处理时展开

const 常量在编译运行时候使用

b.define宏没有类型,不做类型检查

  const常量有类型,编译时会检查

c.宏定义不分配内存,变量定义分配内存

   const会在内存中分配(堆或者栈)

 

6. if 三个分支

 错误 .可以嵌套,但是复杂都会增加不如用switch

 

7. 宏

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值