c++零基础新手入门(七)

while循环

c++中,循环不仅可以通过for来实现,也可以通过while实现,但是while循环对于初学者不太友好,有可能会忘记一些条件导致程序死循环。如果你觉得for循环还没有掌握好,就先把while循环跳过,之后再学习也没有关系。

while的简单字面义是“当......时”,在c++中,我们可以粗略的理解为:当满足xxx条件时,就执行yyy,直到不满足条件xxx时,则自动跳出循环。

这么看有些难以理解,这么看呢?

while(循环继续条件){
    循环内部语句;
}

比如,小于去吃米饭,只要没有吃饱,他就再吃一粒米饭,直到他吃饱之后。就不在吃米饭了。

while(没吃饱){
    吃一粒米饭。
}

也可以这么说:小于找女朋友,只要他没有找到,他就继续找,直到找到为止。

while(单身){
    find girlfriend
}

在程序中,while循环的适用范围也非常的广泛,比如:

如果我需要输出100一下,全部能被3整除的整数,我就可以这样思考:

定义一个变量i,初始值为1,只要满足i小于100,就自动执行判断程序(满足整除3就输出),同时,不要忘记在执行语句中增加i++这个自增条件,否则,i满足小于100将会恒成立,永远在循环。

用文字语言描述过于枯燥,用程序把他表达出来!

#include <iostream>
using namespace std;

int main(){
    int i = 1;
    while(i < 100){
        if(i % 3 == 0){
            cout << i << endl;
        }
        i ++;
    }
    return 0;
}

有几点需要注意的:

i++这个自增语句,不能放在if语句中,如果放进去了,一样会导致死循环,不信你试试!可以思考一下为什么,在评论区里面写出答案。

另外,不要忘记在while循环外面先声明好变量i,否则,while循环在执行的时候,就找不到i的家在哪里,也就找不到i的值了。

细心地同学可以想起来,这个程序完全可以用for循环来做,并且更加简单:

#include <iostream>
using namespace std;

int main(){
    for(int i = 1; i < 100; i++){
        if(i % 3 == 0){
            cout << i << endl;
        }
    }
    return 0;
}

也就是说,可以这样看:

for(A; B; C){
    //sth..   
}

A;
while(C){
    //sth...
    B;
}

竟然是等效的!

所以,同学们在选择循环的时候一定要选择合适的循环,将复杂问题简单化。如果一定要使用while的话,一定不要忘记判断这个循环能否成功调出。

 

循环的一些奇淫巧技

for循环的三个内部语句的含义搞明白之后,我们就可以对他下手脚了。

比如,第三个语句是每次执行完之后需要执行的语句,这个语句其实不止可以写一个,也可以是多个

如果我想要计算从1加到9的和,正常来说,我们会这样写:

    int sum = 0;
    for(int i = 0; i < 10; i++){
        sum += i;
    }

但是,我们也可以这样写:

int sum = 0;
for(int i = 0; i < 10;  sum += i, i ++){}

运行起来就会发现,这两个代码是等效的。

注意了,后者的代码中,sum += i和i++这两个语句是不能替换位置的!否则,i等于10的时候,sum也会加上!

不只是第三个语句,第一个语句中,你甚至可以同时定义两个变量,比如这样:

    for(int i = 0, n = 0; i < 10; i ++){
    }

当然,for有趣的东西还有很多,可以自己去c++的官方手册上探索。

 

下面来说一说while:

有一天,闲的没事的小于写了一个计算器的程序,但是每次计算完一次,就需要重新运行,非常的麻烦,小于想要一个方法能够不断地输入,而不结束程序,这个时候,while就有用了。

我们甚至可以这样对待while:

#include <iostream>
using namespace std;

int main(){
    int n;
    while(cin >> n){
        cout << n;
    }
    return 0;
}

只要有输入,他就不会结束程序。

 

当然了,你甚至可以不写while的循环条件,这个时候。他就和while(true)是等效的,也就是不断运行,没有break语句就不会停下来。

想不起来break的回去看看上一篇教程。

其实,while()和for(;;)的作用是一样的,都是不断地死循环,这种死循环极度不建议大家用,非常容易导致程序长时间卡在同一个地方。

字符型

记得之前写过的这个程序吗?(c++教程一)

nclude <iostream>
using namespace std; 

int main() {    
    int x;    
    cin >> x;    
    cout << x << endl;    
    return 0;
}

这里可以输入一个整数x,并把它输出。

但是如果程序想要只要我们的名字,该如何输入呢?

当然,假设我们的名字是一个字母(后面你就会知道为什么了),虽然没人会这样。

可以试一试把我们的名字输入进去,看看程序会怎么样!

嗯,果然,程序直接停止了!

所以,为了让程序输入像是名字一样的“字符”,我们需要学习一种新的变量类型--字符型。

在c++中,字符型用char来表示。定义方法和int、bool一样,直接这样写就可以:

char s;

让字符型住进变量s也很简单,这样就可以了:

s = 'a';

再输出s,就会发现程序输出了a!

但是如果我们把s住进好几个字母会怎么样呢?

可以试试看这样:

s = 'AB';

编译运行,你就会发现,只输出了B!

原来是因为char型这个小房子只能住下一个字母,如果想让第二个字母住进去,他们就会打一架,打赢坐牢,打输住院的那种,当然,坐牢是不会坐牢,住进char变量是真的。

所以,char变量只能住下一个字母,至于想要输入一段很长的单词怎么办,别着急,后面会有办法。

 

ASCII

ASCII的全名叫做 美国信息交换标准代码 (American Standard Code for Information Interchange),最后两个是I,不是L!不要记错了,小于就闹过这样的笑话。

嗯,美国是一个“霸主”,信息学界什么标准都是它指定的,当然,这个也不例外,他也是一个标准。

这个标准建立了数字和字符的对应表,可以把他当做一个数字和字符映射,简单的理解就是一个“数学函数”,只不过“函数”的结果不是一个数字,而是一个字符罢了。截止目前,这里面一共有128个字符,具体如下表:

ASCII
Bin
(二进制)
Oct
(八进制)
Dec
(十进制)
Hex
(十六进制)
缩写/字符
解释
0000 0000
00
0
0x00
NUL(null)
空字符
0000 0001
01
1
0x01
SOH(start of headline)
标题开始
0000 0010
02
2
0x02
STX (start of text)
正文开始
0000 0011
03
3
0x03
ETX (end of text)
正文结束
0000 0100
04
4
0x04
EOT (end of transmission)
传输结束
0000 0101
05
5
0x05
ENQ (enquiry)
请求
0000 0110
06
6
0x06
ACK (acknowledge)
收到通知
0000 0111
07
7
0x07
BEL (bell)
响铃
0000 1000
010
8
0x08
BS (backspace)
退格
0000 1001
011
9
0x09
HT (horizontal tab)
水平制表符
0000 1010
012
10
0x0A
LF (NL line feed, new line)
换行键
0000 1011
013
11
0x0B
VT (vertical tab)
垂直制表符
0000 1100
014
12
0x0C
FF (NP form feed, new page)
换页键
0000 1101
015
13
0x0D
CR (carriage return)
回车键
0000 1110
016
14
0x0E
SO (shift out)
不用切换
0000 1111
017
15
0x0F
SI (shift in)
启用切换
0001 0000
020
16
0x10
DLE (data link escape)
数据链路转义
0001 0001
021
17
0x11
DC1 (device control 1)
设备控制1
0001 0010
022
18
0x12
DC2 (device control 2)
设备控制2
0001 0011
023
19
0x13
DC3 (device control 3)
设备控制3
0001 0100
024
20
0x14
DC4 (device control 4)
设备控制4
0001 0101
025
21
0x15
NAK (negative acknowledge)
拒绝接收
0001 0110
026
22
0x16
SYN (synchronous idle)
同步空闲
0001 0111
027
23
0x17
ETB (end of trans. block)
结束传输块
0001 1000
030
24
0x18
CAN (cancel)
取消
0001 1001
031
25
0x19
EM (end of medium)
媒介结束
0001 1010
032
26
0x1A
SUB (substitute)
代替
0001 1011
033
27
0x1B
ESC (escape)
换码(溢出)
0001 1100
034
28
0x1C
FS (file separator)
文件分隔符
0001 1101
035
29
0x1D
GS (group separator)
分组符
0001 1110
036
30
0x1E
RS (record separator)
记录分隔符
0001 1111
037
31
0x1F
US (unit separator)
单元分隔符
0010 0000
040
32
0x20
(space)
空格
0010 0001
041
33
0x21
!
叹号
0010 0010
042
34
0x22
"
双引号
0010 0011
043
35
0x23
#
井号
0010 0100
044
36
0x24
$
美元符
0010 0101
045
37
0x25
%
百分号
0010 0110
046
38
0x26
&
和号
0010 0111
047
39
0x27
'
闭单引号
0010 1000
050
40
0x28
(
开括号
0010 1001
051
41
0x29
)
闭括号
0010 1010
052
42
0x2A
*
星号
0010 1011
053
43
0x2B
+
加号
0010 1100
054
44
0x2C
,
逗号
0010 1101
055
45
0x2D
-
减号/破折号
0010 1110
056
46
0x2E
.
句号
0010 1111
057
47
0x2F
/
斜杠
0011 0000
060
48
0x30
0
字符0
0011 0001
061
49
0x31
1
字符1
0011 0010
062
50
0x32
2
字符2
0011 0011
063
51
0x33
3
字符3
0011 0100
064
52
0x34
4
字符4
0011 0101
065
53
0x35
5
字符5
0011 0110
066
54
0x36
6
字符6
0011 0111
067
55
0x37
7
字符7
0011 1000
070
56
0x38
8
字符8
0011 1001
071
57
0x39
9
字符9
0011 1010
072
58
0x3A
:
冒号
0011 1011
073
59
0x3B
;
分号
0011 1100
074
60
0x3C
<
小于
0011 1101
075
61
0x3D
=
等号
0011 1110
076
62
0x3E
>
大于
0011 1111
077
63
0x3F
?
问号
0100 0000
0100
64
0x40
@
电子邮件符号
0100 0001
0101
65
0x41
A
大写字母A
0100 0010
0102
66
0x42
B
大写字母B
0100 0011
0103
67
0x43
C
大写字母C
0100 0100
0104
68
0x44
D
大写字母D
0100 0101
0105
69
0x45
E
大写字母E
0100 0110
0106
70
0x46
F
大写字母F
0100 0111
0107
71
0x47
G
大写字母G
0100 1000
0110
72
0x48
H
大写字母H
0100 1001
0111
73
0x49
I
大写字母I
01001010
0112
74
0x4A
J
大写字母J
0100 1011
0113
75
0x4B
K
大写字母K
0100 1100
0114
76
0x4C
L
大写字母L
0100 1101
0115
77
0x4D
M
大写字母M
0100 1110
0116
78
0x4E
N
大写字母N
0100 1111
0117
79
0x4F
O
大写字母O
0101 0000
0120
80
0x50
P
大写字母P
0101 0001
0121
81
0x51
Q
大写字母Q
0101 0010
0122
82
0x52
R
大写字母R
0101 0011
0123
83
0x53
S
大写字母S
0101 0100
0124
84
0x54
T
大写字母T
0101 0101
0125
85
0x55
U
大写字母U
0101 0110
0126
86
0x56
V
大写字母V
0101 0111
0127
87
0x57
W
大写字母W
0101 1000
0130
88
0x58
X
大写字母X
0101 1001
0131
89
0x59
Y
大写字母Y
0101 1010
0132
90
0x5A
Z
大写字母Z
0101 1011
0133
91
0x5B
[
开方括号
0101 1100
0134
92
0x5C
\
反斜杠
0101 1101
0135
93
0x5D
]
闭方括号
0101 1110
0136
94
0x5E
^
脱字符
0101 1111
0137
95
0x5F
_
下划线
0110 0000
0140
96
0x60
`
开单引号
0110 0001
0141
97
0x61
a
小写字母a
0110 0010
0142
98
0x62
b
小写字母b
0110 0011
0143
99
0x63
c
小写字母c
0110 0100
0144
100
0x64
d
小写字母d
0110 0101
0145
101
0x65
e
小写字母e
0110 0110
0146
102
0x66
f
小写字母f
0110 0111
0147
103
0x67
g
小写字母g
0110 1000
0150
104
0x68
h
小写字母h
0110 1001
0151
105
0x69
i
小写字母i
0110 1010
0152
106
0x6A
j
小写字母j
0110 1011
0153
107
0x6B
k
小写字母k
0110 1100
0154
108
0x6C
l
小写字母l
0110 1101
0155
109
0x6D
m
小写字母m
0110 1110
0156
110
0x6E
n
小写字母n
0110 1111
0157
111
0x6F
o
小写字母o
0111 0000
0160
112
0x70
p
小写字母p
0111 0001
0161
113
0x71
q
小写字母q
0111 0010
0162
114
0x72
r
小写字母r
0111 0011
0163
115
0x73
s
小写字母s
0111 0100
0164
116
0x74
t
小写字母t
0111 0101
0165
117
0x75
u
小写字母u
0111 0110
0166
118
0x76
v
小写字母v
0111 0111
0167
119
0x77
w
小写字母w
0111 1000
0170
120
0x78
x
小写字母x
0111 1001
0171
121
0x79
y
小写字母y
0111 1010
0172
122
0x7A
z
小写字母z
0111 1011
0173
123
0x7B
{
开花括号
0111 1100
0174
124
0x7C
|
垂线
0111 1101
0175
125
0x7D
}
闭花括号
0111 1110
0176
126
0x7E
~
波浪号
0111 1111
0177
127
0x7F
DEL (delete)
删除

看着这些,想必你的眼都要花了,当然,这些并不需要全部记忆,而且他们是有规律的。以下是需要记忆的内容:

49 - 57 对应 0 - 9

65 - 90对应 A - Z

97 - 122对应 a - z

至于二进制,八进制和十六进制,这些就更不需要记忆啦,表中有这个仅仅是因为我懒得删掉了。。

大致了解了ascii码之后,我们来尝试应用它:

char s = 'a';
cout << (int)s;

(int)表示以int的形式输出字符型变量s,运行后你就会发现,他成功地输出了97,也就是ascii表中a的对应值。

既然字符型可以转换为整型,整型是否可以转换为字符型呢?

可以尝试输入以下代码:

int a = 65;
cout << (char)a;

按照上面的ASCII的对应表,65应该对应着大写字母A,试着编译运行这个代码,确实是输出了A。

那么,既然可以输出A,就一定可以输出其他的字母。

 

输出A-Z

还记得之前学的for循环吧,不记得的话就别说是看我教程看到这里的。我们可以使用for循环输出一个区间内的所以数字,也就是下面这段代码:

#include <iostream>
using namespace std;

int main(){
    for(int i = 0; i <= 10; i++){
        cout << i << endl;
    }
    return 0;
}

按照上面int型和char型相互转化的功能,我们也可以把i用字符型输出。

如果想要输出大写字母A-Z,就需要让i从65循环到90,之后再用char型输出。

自己尝试写一下:(↓答案↓)

答案

```cpp
#include <iostream>
using namespace std;

int main(){
for(int i = 65; i <= 90; i++){
cout << (char)i << endl;
}
return 0;
}
```

是不是一行一个字母,一共26行,从A-Z呢?

当然,你可以通过修改i的取值范围来修改输出字符的范围。

 

今日作业:有点难度

现在需要你打印一个m行n列的矩形,要求每一行和每一列的字母都按字典序升序排列,第一行第一列的字母为A。

比如,当m = 3,n = 5时,输出的就是:

ABCDE
BCDEF
CDEFG

难度不小,好好加油

答案↓

答案
抱歉,只有登录并在本文发表评论才能阅读隐藏内容
点赞
  1. FishZe yfz说道:
    大半夜的,累死我了
  2. FishZe FishZe说道:
    Google Chrome Windows 10
    1111

发表评论