C++入门——Day4_循环和关系表达式

一、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循环打印*,打印次数就是多少个点,多少个星,就这个意思

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laker404

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值