一、for循环(确定循环次数通常采纳)
看如下程序:
#include <iostream>
int main(void)
{
using namespace std;
int i;
for ( i = 0; i < 5; i++)
{
cout << "c++ knows loop" << endl; //有时候如果只有一行,就不用括号了
}
cout <<"C++ knows when to stop." << endl;
return 0;
}
c++ knows loop
c++ knows loop
c++ knows loop
c++ knows loop
c++ knows loop
C++ knows when to stop.
*这里需要强调一点,我们的测试表达式就是中间的判断语句,C++并没有将text-experssion的值限制为只能真或假,可以使用任意的表达式,C++会把结果强制转化为bool类型,就是说,如果值为0,才是false,导致循环结束,如果不是0,就会一直执行
再看如下的程序
#include <iostream>
int main(void)
{
using namespace std;
cout << "Enter the starting countdown value: ";
int limit;
cin >> limit;
int i;
for (i = limit; i; i--)
{
cout << "i= " << i << endl;
}
cout << "Done, now that i = " << i << endl;
return 0;
}
Enter the starting countdown value: 5
i= 5
i= 4
i= 3
i= 2
i= 1
Done, now that i = 0
这里的i如果不是0,就一直不会结束,直到为0;
1:for循环的组成部分
1)表达式和语句
来用一个例子试一下:
#include <iostream>
int main(void)
{
using namespace std;
int x;
cout << "The expression : x = 100 has the value " ;
cout << (x = 100) << endl; //如果不加括号,那么<<的优先级高于=,所以会优先打印出x,所以需要()
cout << "Now x = " << x << endl;
cout << "The expressiong x < 3 has the value "; //The expressiong x < 3 has the value 0 ,0就是false,说明不正确
cout << (x<3) << endl;
cout << "The expressiong x > 3 has the value "; //The expressiong x > 3 has the value 1,1就是true,正确
cout << (x>3) << endl;
cout.setf(ios_base::boolalpha); //这行命令可以把bool转换为true 和 false类型
cout << "The expressiong x < 3 has the value "; //The expressiong x < 3 has the value false
cout << (x<3) << endl;
cout << "The expressiong x > 3 has the value ";//The expressiong x < 3 has the value true
cout << (x>3) << endl;
return 0;
}
只要加上分号,所有的表达式都可以称为语句,但不一定有变成意义,比如说rodens是一个变量
rodents + 6;这是一条语句,但是没有意义的。
2)非表达式和语句
对任何表达式加上分号可以成为语句,但是这句话反过来就不对了
3)修改规则
之前C规则是你要在for循环使用i,必须先初始化,但是新的规则是你可以在for循环里面直接声明
比如:for (int i=0; i <5 ; i++),可以在这里直接初始化,但是这个变量只存在于for循环当中
2:回到for循环
下面使用for循环来计算16!,程序如下:
#include <iostream>
const int ArSize = 16;//定义数组长度
int main(void)
{
using namespace std;
long long factorials[ArSize]; //一定要定义数组,不然你for循环的值怎么一个一个相乘呢
factorials[0] = factorials[1] = 1; //0和1比较特殊,所以特殊处理赋值
for (int i = 2; i < ArSize; i++) // 然后从2开始依次把这个数乘上前面的数,然后循环
{
factorials[i] = i * factorials [i-1];
}
for ( int i = 0; i < ArSize ; i++) //从0开始一个一个打印
{
cout << i << "! = " << factorials[i] << endl;
}
return 0;
}
结果如下:
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
10! = 3628800
11! = 39916800
12! = 479001600
13! = 6227020800
14! = 87178291200
15! = 1307674368000
*注意要定义一个数组来存放值呢
3:修改步长
使用表达式i = i + by;
见下面的程序:
#include <iostream>
int main(void)
{
using namespace std;
cout << "Enter an integer: ";
int by; //定义了步长
cin >> by;//步长输入
cout << "Counting by " << by << endl;
for ( int i = 0; i < 100; i = i + by)
{
cout << i << endl;
}10
10
return 0;
}
设置步长为0,结果如下:
Enter an integer: 10
Counting by 10
0
10
20
30
40
50
60
70
80
90
4:使用for循环访问字符串
for循环提供了一种依次访问字符串中的每个字符的方式,在这个例子中,你可以使用string对象或者char数组。
我们来反向输出字符串。string类的size()获得字符串中的字符数;循环在其初始化表达式中使用这个值,将i设置为字符串中的最后一个字符的索引,每轮循环后递减。程序如下:
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
cout << "Enter a word : ";
string word;
cin >> word;
for (int i = word.size()-1; i >= 0; i--) //在这里size()方法是最核心的
{
cout << word[i]; //依次打出字符即可
}
return 0;
}
Enter a word : hello
olleh
5:递增运算符(++)和递减运算符(- -)
对于这俩没啥问题。有一个和i ++比较像的 ++ x
它们影响的结果是没有问题的,但是影响时间不同。
就像你干一件事,先付钱和后付钱对钱包来说没什么问题,但是支付钱的时间不一样
i++就是先用后付钱,++ i就是 先付钱再用
看下例:
#include <iostream>
int main(void)
{
using namespace std;
int a = 20;
int b = 20;
cout << "a= " << a << ", " << "b = " << b << endl;
cout << "a++ = " << a++ << ", " << "++b = " << ++b << endl;
//a++就是先用,再付钱,所以直接打印a,然后a才变成21,++b是先付钱再用,所以b直接变成了21
cout << "a= " << a << ", " << "b = " << b << endl;//这就是最后的结果,它们都会变成21的,只是时间的问题
return 0;
}
a= 20, b = 20
a++ = 20, ++b = 21
a= 21, b = 21
*可以好好看一下注释
同样要注意不要再一段程序中多次使用++ 或者--;
6:前缀格式和后缀格式
for(n=lim; n>0 ;--n)
,,,;
for(n= lim ; n >0 ; n--)
...;
这两个表达式的值并没有被使用,所有只存在副作用,对于逻辑来说,这两个表达式结果完全相同
但是C++允许我们针对类定义这些运算符,在这种情况下,用户这样定义前缀函数;将值+1,然后返回结果。但是后缀版本首先复制一个副本,将其+1,然后将复制的副本返回,因此对于类而言,前缀版本的效率比后缀版本高
7:递增/递减运算符和指针
代码如下:
#include <iostream>
int main(void)
{
using namespace std;
double arr[5] = {21.1,23.8,23.4,45.2,37.4};
double *pt = arr;
cout << *pt << endl;//这就是第一个地址的内容,21.1
cout << "*++pt = " << *++pt << endl; //23.8
cout << "++*pt = " << ++*pt << endl; //必然是24.8,
cout << "*pt++ = " << (*pt)++ << endl;//
cout << "*pt++ = " << *pt++ << endl;//
return 0;
}
结果:
21.1
*++pt = 23.8
++*pt = 24.8
*pt++ = 24.8
*pt++ = 25.8
1)*++pt:递增递减和取消引用运算符的优先级是相同的,我们按照从右到左的顺序来,所以先++pt,然后取消引用,下面程序结果就是23.8
2)++*pt:上一行已经把指针++了,所以到了23.8,这里就是先把23.8取出来,然后+1
3)(*pt)++:这是一样的,先显示了,但是还是会先用了24.8,用完了再+1的,所以当前还是24.8
4)*pt++:运行完了上一行代码,这时候第二个元素已经变成了25.8了,这行代码先运行pt++(因为后缀运算符的优先级高),但是当前值并没有改变,它会影响下一行而已,所以还是25.8,再调用第二个肯定就是第三个数了
*后缀运算符pt++的优先级比++pt高,所以也比取消引用的优先级高!
8:组合赋值运算符
+=、-=、*=、/=、%=
9:复合语句(语句块)
程序如下:
#include <iostream>
int main(void)
{
using namespace std;
double number,sum = 0.0;
cout << "Calculate five numbers sum and average." << endl;
cout << "Please enter five value: \n";//不需要数组来存放数,只需要加就行了
for (int i = 1; i < 5; i++)
{
cout << "Value " << i << ": ";
cin >> number; //每个值都是捕获自cin
sum += number; //sum把每次的值都加上
}
cout << "The sum = " << sum << endl;
cout << "Average = " << sum/5 << endl;
return 0;
}
Calculate five numbers sum and average.
Please enter five value:
Value 1: 1942
Value 2: 1948
Value 3: 1957
Value 4: 1974
The sum = 7821
Average = 1564.2
*对于语句块,把{}作为循环体内容的
10:逗号运算符
使用逗号运算符实现如下代码:
#include <iostream>
int main(void)
{
using namespace std;
cout << "Enter a word: ";
string word;
cin >> word;
int i,j;
char temp;//临时的值
for(j = 0,i = word.size()-1 ; j < i ;j++ ,i--)
{
temp = word[i]; //把末尾字符的放在临时字符temp中
word[i] = word[j]; //把开头的字符放到末尾的位置
word[j] = temp; //然后把放在temp中的临时字符放到开头
}
cout << word << endl;
return 0;
}
*解释语句放在了注释
Enter a word: morning
gninrom
逗号运算符就是在
for(j = 0,i = word.size()-1 ; j < i ;j++ ,i--)当中使用的逗号,可以把两个语句合并成一个
但是对于int i,j中的,并不是逗号运算符,而是分隔符
花絮:逗号运算符最常见的用途是将两个或更多的表达式放在一个for循环表达式中,不过C++还为这个运算符提供了另外两个特性。
首先它确保计算第一个表达式,然后计算第二个表达式,如下表达式是安全的:
i = 20 , j = 2*i ;
其次C++规定,逗号表达式的值是第二部分的值,例如上述表达式的值是40,因为j = 2 * i的值是40.在所有的运算符当中,逗号运算符的级别是最低的,比如:
cata = 17,240就会被解释为(cata = 17 ),240;所以最好给数字加括号cata = (17,240);
11:关系表达式
<
>
<=
<=
==
!=
关系运算符优先级<算术运算符
x+3 > y-2 就相当于 (x+3) > (y-2)
12:赋值、比较和可能犯的错
别混淆 = 和= = ,判断相等和赋值
程序如下:
#include <iostream>
int main(void)
{
using namespace std;
//首先正确使用条件判断符
int arr[20] = {20,20,20,20,20,19,20,18,20,20};
cout << "Doing is right: " << endl;
int i ;
for(i = 0; arr[i] == 20 ; i++) //这里是==
{
cout << "arr" << i << " is a 20" << endl;
}
//再看如果使用赋值运算符
cout << "Doing is dangerous: " << endl;
for(i = 0; arr[i] = 20 ; i++) //这里是 =
{
cout << "arr" << i << " is a 20" << endl;//这里就会一直打印20,没办法
}
return 0;
}
第二个程序会一直打20,因为20不是0,一直为true!
14:C风格字符串的比较
假设我们要直到字符数组中的字符串是不是mate。如果word是数组名,对于如下语句:
word = "meta";
这里word是数组名,它是数组的首元素地址,meta是字符串,也是首字符地址,这里我们是在判断它们是否存储在相同的地址上,因此如果想比较字符串,可以用cstring中的函数strcmp()
strcmp()函数接收两个字符串地址作为参数,这意味着参数可以是指针,字符串或者字符数组名。如果两个字符串相同,则返回0;如果第一个字符串按字母顺序排再第二个字符串之前,则srtrcmp()将返回负数;如果第一个字符串按字母顺序排在第二个字符串之后,则将返回正数值
请看下面的程序:
#include <iostream>
#include <cstring>
int main(void)
{
using namespace std;
char word[] = "?ate"; //首先定义字符数组,但是首字母不定
for (char ch = 'a'; strcmp (word,"mate"); ch++)//它还是会强制转换为bool类型
{
cout << word << endl;
word[0] = ch; //把第一个元素替换掉
}
cout << "After loop end , word is " << word << endl;
return 0;
}
*定义字符ch,从a开始一直比较word字符串和我们的mate字符串是否相等,不相等就把字符+1,然后把ch替换掉word的第一个字符,最后打印word。
虽然不能用关系运算符比较字符串,但是可以用来比较字符,因为字符本质是ASCII码
运行结果:
?ate
aate
bate
cate
date
eate
fate
gate
hate
iate
jate
kate
late
After loop end , word is mate
15:比较string类字符串
程序如下:
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
string word = "?ate";
for (char ch = 'a'; word != "mate"; ch++)
{
cout << word << endl;
word[0] = ch;
}
cout << "Now , word is " << word << endl;
return 0;
}
可以看出差别在比较时直接使用word!="mate",如果该表达式为false,即word = mate,就会停止loop
如果是true,循环会一直进行
*这两段程序,我们能看出和前面循环的一个差别,它不是计数循环,就是说你不知道循环了多少次,相反,循环会根据情况(true和false)来判定是否停止。对于这种测试,C++程序通常使用while循环
二、while循环(不确定循环次数)
while循环是没有初始化和更新部分的for循环,它只有测试条件和循环体
while (test-condition)
body
看下例:
#include <iostream>
const int ArSize = 20;
int main(void)
{
using namespace std;
char name[ArSize];
cout << "Your first name : ";
cin >> name;//假设没空格
cout << "Here is your name : " << endl;
int i = 0;
while (name[i] != '\0')
{
cout << name[i] << ": " << int(name[i]) << endl;
i++;
}
return 0;
}
结果:
Your first name : frank
Here is your name :
f: 102
r: 114
a: 97
n: 110
k: 107
*也可以把name[i] != '\0' 改成 while(name[i]) ,name[i]会是常规字符,通过bool转换其实也是非零,自动转换为true,如果遇到了空字符,即0,就停止循环。
1:for与while
其实他们俩多数情况下都是通用的
他们的差别如下:
1)for循环如果省略中间的测试条件,呢么我们默认为条件为true,而while循环不可以省略
2)for循环可以使用初始化语句声明变量,比如把int i = 0写到语句中,但是while不行
3)如果有cintinue,情况不同
特别注意:
while (name [i] != '\0');
{
cout <<....
}
如果在while后面的括号加上;,这样就默认循环体为空了,所以不能写错位置!
2:等待一段时间:编写延时循环
long wait = 0;
while (wait < 10000)
wait ++;
这种方法的限制是,当计算机处理速度发生变化时,必须修改技术规则,我们有更好的方法。
C++库中有一个函数clock(),返回程序开始执行后所用的系统时间
这有两个问题,第一是clock()返回时间单位不一定是秒,其次函数返回类型在某些系统可能是long,有些系统可能是unsinged long
头文件ctime提供了这些问题的解决方案。看如下程序:
#include <iostream>
#include <ctime>
int main(void)
{
using namespace std;
cout << "Enter the delay time , in seconds: ";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC;
clock_t start = clock();
while (clock() - start < delay); //只要等待,就执行空语句
cout << "done!\n";
return 0;
}
*ctime中定义了一个符号常量—CLOCKS_PER_SEC,该常量等于每秒钟所包含的系统时间数
因此将系统时间除以这个值,就能得到秒数。或者将秒数乘以CLOCKS_PER_SEC就可以得到以系统时间单位为单位的时间。
其中clock_t 作为clock()返回类型的别名,这意味着可以把变量声明为clock_t类型,它是int类型的别名
类型别名:
C++为类型建立别名的方式有两种
1)第一种是使用预处理器(不推荐)
#defin BYTE char 用char替换掉所有的BYTE,从而使BYTE成为char的别名
2)第二种是使用C++关键字typedef来创建别名
typedef char byte 用byte替换所有的char
通用格式:typedef typeName aliasName;
为什么要用:为了方便辨认名称代表什么
三、do while循环
结构如下:
do
body
while (test-expression);
无论如何先执行一遍body
那什么时候用do-while这种出口条件循环呢?
例如开机,输入密码这种操作,必须先判断输入,然后进行测试
看如下程序:判断输入的是否为7
如果先不采纳do while ,而用while做一遍
#include <iostream>
int main(void)
{
using namespace std;
cout << "Enter numbers in the range 1~10 to fin my favorite number" << endl;
int n;
cin >> n;
while(n!=7)
{
cin >> n;
}
cout << "Yse, 7 is my favorite." << endl;
return 0;
}
也没有问题
但是如果用do while循环
#include <iostream>
int main(void)
{
using namespace std;
int n;
cout << "Enter numbers in the range 1~10 to fin my favorite number" << endl;
do
{
cin >> n;
} while (n != 7);
cout << "Yse, 7 is my favorite." << endl;
return 0;
}
这样写就相当于少写了一次cin,我们上去就执行cin
四、基于范围的for循环(C++11)
C++11新增了一种循环;基于范围的for循环。对数组(或容器类)的每个元素执行相同的操作
1:
double price[5] = {4.99,10.99,2.34,3.21,4.56};
for(double x : prices)
cout << x << endl;
这种不能修改元素的值,要修改可以使用如下的符号&
2:
for (double &x :prices)
x= x*0.8;
&表示x是一个引用变量
3:
还可以这样
for (int x :{3,5,2,8,4})
cout << x << " ";
五、循环和文本输入
我们来看一看循环完成的一项最常见最重要的任务:逐个字符地读取来自文件和键盘的文本
1:使用原始的cin进行输入
如果程序要使用循环来读取来自键盘的文本输入,则必须有办法直到何时停止。一种方法就是选择某个特殊字符——有时被称为哨兵字符,将其作为停止标记。例如下例中把#当作标记。
程序如下:
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters, enter # to quit:" << endl;
cin >> ch;
while(ch != '#')
{
cout << ch;
count++;
cin >> ch;
}
cout << endl;
cout << count << "chararcters read" << endl;
return 0;
}
结果如下:
Enter characters, enter # to quit:
see ken run#really fast
seekenrun
9chararcters read
程序说明:
1)如果读取的第一个值不是#,则进入循环,显示字符,增加计数,注意最后一步
cin >> ch,这一步非常重要, 有了这一步程序才能继续处理下一个字符,不然会一直卡在第一个字符
2)这里ch被定义为char,而不是char数组或者string,因此并不会存在遇到空格就跳过了,但是对于char值而言,cin将忽略空格和换行符,因此输出的时候并没有被显示,也没有被计数
2:使用cin.get(char)进行补救
成员函数会读取输入中的下一个字符(即使是空格),并赋值给ch,再次试一下上面的程序
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters, enter # to quit:" << endl;
cin.get(ch);
while(ch != '#')
{
cout << ch;
count++;
cin.get(ch);
}
cout << endl;
cout << count << "chararcters read" << endl;
return 0;
}
输出:
Enter characters, enter # to quit:
Did you use a #2 pancil?
Did you use a
14chararcters read
3:使用哪一个cin.get(),函数重载
到目前为之,我们碰到过了这几种cin.get()了
1)
char name[ArSize];
....
cin.get(name,ArSize);
cin.get()
这相当于两个连续的函数调用,这里是对字符数组进行的操作
2)
char ch ;
cin . get (ch);
这里的cin.get接受一个char参数
像这种一个函数名以不同的方式或不同的类型执行相同的任务,我们就叫做函数的重载,这时OOP重要的特征,区别于C,函数重载允许创建多个同名函数
4:文件尾条件
我们之前总是用#来表示输入结束, 但是感觉不是特别方便,如果输入来自文件,则可以使用一种功能更强大得计数——检测文件尾(EOF)
看如下程序:
#include <iostream>
int main(void)
{
using namespace std;
char ch;
int count = 0;
cout << "Enter characters, enter # to quit:" << endl;
cin.get(ch);
while(cin.fail() == false ) //EOF的方式
{
cout << ch;
count++;
cin.get(ch);
}
cout << endl;
cout << count << "chararcters read" << endl;
return 0;
}
我们将测试条件变成了EOF中的fail()方法,即cin.fail() == false
最后我们按下ctrl+Z,回车来继续进程即可
输出结果如下:
Enter characters, enter # to quit:
the green bird sings in the winter.
the green bird sings in the winter.
^Z
36chararcters read
1)EOF结束输入
cin方法检测到EOF时,将设置cin对象中一个指示EOF条件的标记。设置这个标记后,cin将不读取输入,再次调用也没用,对于键盘输入来说,后续可能还要用cin其他输入,所以应该使用cin.clear()方法清除EOF标记,使输入继续
2)常见的字符输入做法
①每次读取一个字符,直到遇到EOF的输入循环基本设计如下:
cin.get(ch);
while (cin.fail() == false)
{
..
cin.get(ch);
}
这是最原始的版本,我们逐次进行简化
②取反运算符!可以将true变为false,所以可以这样简化
while (!cin.faile())
③方法cin.get(char) 的返回值是一个cin对象,istream类提供了一个可以将istream对象(如cin)转换为bool值得函数,当cin出现在需要bool值得地方(比如循环while中),该转换函数将被调用,意味着可以这么写
while(cin);
意味着这里的cin被默认转换为bool类型了
④最后由于cin.get(char)返回值为cin,因此可以把循环精简成这样的
while (cin.get(ch))
{
....
}
这样我们的cin.get(char)只被调用一次
六、嵌套循环和二维数组
打印二维数组的所有内容,程序如下:
这里就是既用了嵌套数组和二维数组
for (int row = 0; row <4; row++)
{
for(int col = 0; col < 5 ; ++col)
{
cout << maxtemps[row][col] << "\t";
}
cout << endl;
}
1:初始化二维数组
int maxtemps[4] [5] = { {}, {},{},{} }
表明二维数组有四个元素,每个元素分别为包含5个int变量的一维数组
2:使用二维数组
看如下程序:
#include <iostream>
const int Cities = 5;
const int Years = 4;
int main(void)
{
using namespace std;
const char * cities[Cities] = //这里就是一个字符数组
{
"Gribble City",
"Gribbletown",
"New Gribble",
"San Gribble",
"Grbble Vista"
};
int maxtemps[Years] [Cities] =//这是嵌套数组了,第一个数组是大范围数组,每个第一个数组都包含5个一维数组,但是后面显示是相反的
{
{96,100,87,101,105},
{96,98,91,107,105},
{97,101,93,108,107},
{98,103,95,109,108}
};
cout << "Maximum temperatures for 2008 ~ 2011 \n\n";
for (int city = 0;city < Cities ; ++city)
{
cout << cities[city] << ": \t";//显示城市名,\t是对齐字符
for(int year = 0; year < Years; ++year)
{
cout << maxtemps[year][city] << "\t"; //对于maxtemps数组而言,我们先访问第一列,然后访问city
}
cout << endl;
}
return 0;
}
Maximum temperatures for 2008 ~ 2011
Gribble City: 96 96 97 98
Gribbletown: 100 98 101 103
New Gribble: 87 91 93 95
San Gribble: 101 107 108 109
Grbble Vista: 105 105 107 108
程序说明:
1:这里面,我们也可以使用char数组的数组,而不是字符串指针数组,在这种情况下,声明如下:
char citie s[Cities][25] =
但是指针数组更经济,如果要修改内容,字符串指针数组更方便
2:另外还能用string类对象
const string cities[Cities] =
3: '\t'是对齐的符号
4:
七、复习题和编程练习
1:复习题
1:入口条件循环和出口条件循环之间的区别是什么?各种C++循环分别属于哪一种?
入口条件循环就是入口的时候谈条件,满足了才能进入循环体,for和while都是入口条件循环,而do while是出口条件循环
2:如果下面的代码片段是有效程序的组成部分,它将打印什么内容?
int i;
for (i = 0; i<5; i++)
cout << i;
cout << endl;
会在一行打印出01234,因为;在第一条语句后
3:同理,下面的代码将打印出什么内容?
int j;
for (j = 0; j < 11; j+=3)
cout << j;
cout << endl << j <endl;
0369
12
4:同理,下面的代码会打印出什么内容?
int j = 5;
while (++j < 9)
cout << j++ << endl;
先进行++j操作,会先直接把j变成6,然后6<9,打印出j++,但是j++是先用6,后变成7,然后++j
所以结果为:
6
8
5:同理,下面的代码会打印出什么内容呢?
int k = 8;
do
cout << " k = " << k << endl;
while(k++ < 5 );
k=8,先do,然后再条件,结果如下
k=8
6:编写一个打印1、2、4、8、32、64的for循环,每轮循环都将计数变量的值乘以2。
for(int i =1; i < 64 ; i *= 2)
cout << i << endl;
cout << i << endl;
7:如何再循环体包括多条语句?
{}
8:下面的语句是否有效?如果无效,原因是什么?
int x = (1,024);
有效的,因为有括号,所以先进行逗号运算符,逗号运算符要进行从左到右的运算,整个逗号运算表达式的值是整个逗号右侧的值,所以()内的值最终就是024
int y;
y = 1,024;
有效,但是没啥用。因为,的优先级最低,先把1给y, 然后是024
这时候又来了逗号运算符,是右侧的值,所以整个两条语句下来,最后输出的还是024
9:在查看输入方面,cin >> ch 同cin.get(ch)和ch = cin.get()有什么不同?
1)cin >> ch会把空格直接跳过
2)cin.get(ch)不会跳过空格
3)ch = cin.get 和上一个作用一样
2:编程练习
1:编写一个要求用户输入两个整数的程序。该程序将计算这两个整数之间所有整数的和。假设这里先输入较小的整数。例如,如果用户输入的是2和9,则程序将指出2~9之间所有的整数和为44.
#include <iostream>
int main(void)
{
using namespace std;
int i,j,sum=0;
cout << "Please enter two numbers." << endl;
cout << "First number is : ";
cin >> i;
cout << "Second number is : ";
cin >> j;
while (i <= j)
{
sum += i; //这才是精髓啊。。
++i;
}
cout << sum << endl;
return 0;
}
*sum是重点,你要求和得话,必须得先定义一个和然后打印他才对。
2:使用array对象(不是数组)和long double重新编写如下程序(5-4),并计算出100!的值。
#include <iostream>
const int ArSize = 16;//定义数组长度
int main(void)
{
using namespace std;
long long factorials[ArSize]; //一定要定义数组,不然你for循环的值怎么一个一个相乘呢
factorials[0] = factorials[1] = 1; //0和1比较特殊,所以特殊处理赋值
for (int i = 2; i < ArSize; i++) // 然后从2开始依次把这个数乘上前面的数,然后循环
{
factorials[i] = i * factorials [i-1];
}
for ( int i = 0; i < ArSize ; i++) //从0开始一个一个打印
{
cout << i << "! = " << factorials[i] << endl;
}
return 0;
}
#include <iostream>
#include <array>
const int ArSize = 100;//定义数组长度
int main(void)
{
using namespace std;
array<long double,ArSize> factorials;
factorials[0] = factorials[1] = 1; //0和1比较特殊,所以特殊处理赋值
for (int i = 2; i < ArSize; i++) // 然后从2开始依次把这个数乘上前面的数,然后循环
{
factorials[i] = i * factorials [i-1];
}
for ( int i = 0; i < ArSize ; i++) //从0开始一个一个打印
{
cout << i << "! = " << factorials[i] << endl;
}
return 0;
}
*修改部分就这样:
array<long double,ArSize> factorials;再添加个头文件即可!
3:编写一个要求用户输入数字得程序。美如输入后,程序都将报告到目前为止,所有输入得累计和,当用户输入0时,程序结束。
#include <iostream>
int main(void)
{
using namespace std;
double num,sum = 0;
do
{
cin>> num;
sum += num;
} while (num!=0);
cout << sum << endl;
return 0;
}
结果如下:
2
3
4
5
6
7
12
0
39
*要把cin放在循环体内,每次才能输入,不然只能输入一次然后就卡住了
4:Daphne以10%得单利投资了100美元,也就是说,每一年得利润都是投资得10%,每年10美元
利息 = 0.10×原始存款
而Cleo以5%的复利投资了100美元,也就是说,利息是当前存款(包含利息)的5%;
利息 = 0.05×当前存款;
Cleo再第一年投资100美元的盈利是5%,得到了105美元,下一年盈利是105美元的5%,就是5.25美元,以此类推
设计出一个程序计算多少年后,Cleo的投资价值才能超过Daphne的投资价值,并显示两个人的投资价值
#include <iostream>
int main(void)
{
using namespace std;
const int origin = 100;
int years=0;
double Daphne_value = origin;
double Cleo_value = origin;
while (Daphne_value >= Cleo_value)
{
Daphne_value = (origin * 0.1) + Daphne_value;//或者Daphne_value += (origin * 0.1)
Cleo_value = (Cleo_value * 0.05) + Cleo_value;
years++;
}
cout << "years : " << years << endl;
cout << "Daphne_value: " << Daphne_value << endl;
cout << "Cleo_value: " << Cleo_value << endl;
return 0;
}
结果:
years : 27
Daphne_value: 370
Cleo_value: 373.346
*代码说明:
while循环里面的计算复利的方法并没有用到yeas,因为给了Daphne和leo的初始值,然后给了它计算公式,每次会更新里面的值就行
5:假设要销售C++一本书,请编写一个程序,输入全年中每个月的销售量(图书)。程序通过循环,使用初始化为月份字符串的char*数组(或string对象数组)逐个月进行提示,并将输入的数据存储再一个int数组中,然后程序计算数组中的个元素的总数,并报告这一年的销售情况。
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
int num[12];
const string Month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int sum = 0;
for (int i = 0; i < 12; i++)//输入月份先得来一个for循环
{
cout << "Enter the sale number of " << Month[i] << ": " << endl;
cin >> num[i];
}
cout << "Input done! " << endl;
for (int i = 0; i < 12; i++)
{
sum += num[i];
}
cout << "We have sale " << sum << " books in this year." << endl;
return 0;
}
我们用了两次for循环
第一次for循环是为了把输入的每个月份的值存放在int数组中
第二次是为计算总共卖了多少本
最后把总数打出来就行了
6:还是上面的题,这次用一个二维数组来存储输入——3年中每个月的销售量。程序将报告每年销售量以及三年的总销量
*其实就是每年的销售量的数组是新数组的元素嘛。。。
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
int num[3][12]; //加上3就变成了二维数组
const string Month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int sum = 0;
for (int j = 0; j < 3; j++) //嵌套循环就是为了二维数组而生的。。。。
{
cout << "Starting " << j+1 << " year's data." << endl;
for (int i = 0; i < 12; i++)//输入月份先得来一个for循环
{
cout << "Enter the sale number of " << Month[i] << ": " << endl;
cin >> num[j][i];
}
cout << "Input done! " << endl;
}
for (size_t i = 0; i < 3; i++)
{
for (int j = 0; j < 12; j++)
{
sum += num[i][j];
}
}
cout << "We have sale " << sum << " books in three years." << endl;
return 0;
}
*
1)嵌套循环对于二维数组是最优选择
2)注意i和j的变化,二维数组前面的字母是外层的,后面的字母是内层的
7:设计一个名为car的结构,用它来存储下述有关汽车的信息:生产商(存储在char字符组或string对象)、生产年份(整数)。
编写一个程序,向用户询问又多少辆汽车。随后使用new来创建一个由相应数量car结构组成的动态数组。接下来,程序提示用户输入每辆车的生产商(可能有多个单词)和年份信息。
最后程序将显示每个结构的内容。程序的运行情况如下:
#include <iostream>
#include <cstring>
struct car_info
{
char brand[20];
int years;
};
int main(void)
{
using namespace std;
int num;
cout << "How many car do you have ? " << endl;
cin >> num;
cin.get();
car_info *pcar = new car_info[num];
for (int i = 0; i < num; i++)
{
cout << "Car # " << i+1 << ":" << endl;
cout << "Please enter the maker : " ;
cin.getline(pcar[i].brand ,20);
cout << "Please enter the year made :";
cin >> pcar[i].years;
cin.get();
}
cout << "Here is your collection :" << endl;
for(int i = 0; i < num; i++)
{
cout << pcar[i].years << " " << pcar[i].brand << endl;
}
return 0;
}
*这里我使用了char数组
1)初始化动态数组的格式就是:
类型 *名称 = new 类型[数组大小]
2)使用getline捕获字符和数字后一定要用get()释放
8:编写一个程序,它使用char数组和循环来读取每个单词,直到用户输入done为之。
随后该程序指出用户输入了多少个单词(没有done)。下面是运行情况:
strcmp()是字符串比较函数
#include <iostream>
#include <cstring>
int main(void)
{
using namespace std;
const char DONE[] = "done";//定义了字符串数组,来存放done,然后把输入的东西跟它比较就行了
int counter = 0;
char words[20];
cout << "Enter words (to stop , type the word done):" << endl;
do
{
cin >> words;//这里我们是单词,就意思直接读就行了
cin.get();//消耗了word
counter++;
} while (strcmp(DONE,words));
cout << "You entered a total of " << counter - 1 << " words." << endl;
return 0;
}
运行结果如下:
Enter words (to stop , type the word done):
leikang
lijing
lijingsb
done
You entered a total of 3 words.
9:编写一个满足前一个练习中描述的程序,但是使用string,并使用关系运算符比较
#include <iostream>
#include <string>
int main(void)
{
using namespace std;
const char DONE[] = "done";//定义了字符串数组,来存放done,然后把输入的东西跟它比较就行了
int counter = 0;
string words;
cout << "Enter words (to stop , type the word done):" << endl;
do
{
cin >> words;//这里我们是单词,就意思直接读就行了
cin.get();//消耗了word
counter++;
} while (words!= DONE);
cout << "You entered a total of " << counter - 1 << " words." << endl;
return 0;
}
*
改了头文件
比较直接就是words!= DONE
10:编写一个使用嵌套循环的程序,要求用户输入一个值,指出要显示多少行。然后程序将显示相应行数的星号,第一行由一个星号(*),以此类推。
每一行包含的字符数等于用户指定的行数,星号不够的情况下,在星号前加上句号,程序运行情况如下:
#include <iostream>
int main(void)
{
using namespace std;
int row;
cout << "Please enter the number of rows: ";
cin >> row;
for (int i = 0; i < row; i++) //外层是表示行呢
{
for (int j = 0; j < row - i - 1; j++) //这里稍微计算一下
{
cout << ".";
}
for (int j = 0; j <= i; j++)
{
cout << "*";
}
cout << endl;
}
return 0;
}
运行结果:
Please enter the number of rows: 10
.........*
........**
.......***
......****
.....*****
....******
...*******
..********
.*********
**********
*该题提示了循环嵌套
最外面肯定是行,然后里面使用了两个for循环,一个for循环来打印点,另一个for循环打印*,打印次数就是多少个点,多少个星,就这个意思