【c++】4.循环和关系表达式

第五章 循环和关系表达式

for循环

递增/递减运算符和指针

前缀递增、前缀递减和解除应用运算符的优先级相同,以从右至左的方式进行结合。

后缀递增和后缀递减的优先级相同,但比前缀运算符的优先级高,这两个运算符以从左至右的方式进行结合。

*pt=ar[1];

++*pt; //先取得pt指向的值,然后将这个值加1,不是下一个元素

*++pt; //指针加1,取得的是下一个元素的值

x=* pt++; //后缀++运算符的优先级更高,这意味着将运算符用于pt,而不是 *pt,因此对指针递增。 *pt++的值为下一个元素的值,pt的值为下下个元素的地址

int main(){
	using namespace std;
	float x,y;
	double arr[5]={1.2,3.4,5.6,6.7,6.7};
	double *pt=arr;
	++pt;
	cout<<*pt<<endl;
	cout<<pt<<endl;
	cout<<*++pt<<endl;
	cout<<*pt<<endl;
	cout<<++*pt<<endl;
	cout<<pt<<endl;
	cout<<pt<<endl;
	cout<<*pt++<<endl;
	return 0;
}

1553674482089

组合赋值运算符

+=;-=;*=;/=;%=

复合语句

在循环体中包含任意多条语句,用两个花括号来构造一条复合语句(代码块)。

for(int i=1;i<=5;i++)
{
	cout<<"value: "<<i<<endl;
	cin>>number;
	sum+=number;
}

for后没有冒号。

如果在语句块中定义一个变量,则仅当程序执行该语句块的语句时,该变量才存在,执行完该语句块后,变量将被释放。

在外部语句块中定义的变量在内部语句块中也是被定义了的。

如果在一个语句块中声明一个变量,而外部语句块中也有一个这种名称的变量,则在声明位置到内部语句块结束的范围内,新变量将隐藏旧变量:然后旧变量再次可见。

int main(){
	using namespace std;
	int x=20;
	{
		int y=100;
		cout<<x<<endl;
		//x=50;
		cout<<x<<endl;
		cout<<y<<endl;
	}
	cout<<x<<endl;
	//cout<<y<<endl;
	return 0;
}

如上边程序所示,输出为20 20 100 20

如果不注释掉cout<<y<<endl;则会编译出错

如果不注释掉x=100;输出为20 50 100 50

逗号运算符

逗号运算符允许把两个表达式放在c++句法只允许放在一个表达式的地方,例如:

假设一个循环,每轮都将一个变量加1,将另一个变量减1,则**++j,–i**

还有 int i,j;

int x=(1,024); //值为右侧表达式的值,024为20,所以x=20

int y;

y=1,024; //运算符优先级导致被判定为(y=1),024;。所以y=1

赋值、比较和可能犯的错误

m==4;和 m=4;

C风格字符串的比较

word=="mate";//word是数组名

数组名是数组的地址,用括号引起的字符串常量也是其地址,因此上面的语句是判断地址是否相同,答案是否定的。应使用strcmp()函数来比较:

strcmp()

该函数接受两个字符串地址作为参数,这意味着参数可以是指针、字符串常量或字符数组名。如果两个字符串相同,该函数返回0;如果第一个字符串按字面顺序排在第二个字符串之后,则strcmp()返回一个正数值。实际上,按系统排列顺序更准确,例如ASCII码所有的大写字母的编码都比小写字母小。

虽然不可以用关系运算符比较字符串,但可以用来比较字符,因为字符实际上是整型。

#include <iostream>
int main(){
	using namespace std;
	char word[5]="?ate";
	for(char ch='a';strcmp(word,"cate");ch++)
	{
	cout<<word<<endl;
	word[0]=ch;
	}
	cout<<"loop end word "<<word<<endl;
	return 0;
}

1553680581553

用strcmp()检测相等或排列顺序

如果str1和str2相等:strcmp(str1,str2)==0 表达式为true

如果str1和str2不相等:strcmp(str1,str2)!=0以及strcmp(str1,str2)表达式为true

如果str1在str2的前面:strcmp(str1,str2)<0表达式为true

如果str1在str2的后面:strcmp(str1,str2)>0表达式为true

根据要如何设置测试条件,strcmp()可以扮演==、!=、<和>运算符的角色。

比较string类字符串

使用string类字符串将比C-风格字符串更为简单

#include <iostream>
#include <string>
int main(){
	using namespace std;
	string word="?ate";
	for(char ch='a';word!="cate";ch++)
	{
	cout<<word<<endl;
	word[0]=ch;
	}
	cout<<"loop end word "<<word<<endl;
	return 0;
}

1553681701501

while循环

等待一段时间,编写延时循环

让程序等待一段时间很有用,例如,读者可能会遇到这样的程序,在屏幕上显示了一条信息,还没来得及阅读之前,又出现了其他内容。

long wait =0;
while(wait<10000)
    wait++;

这种方法的问题是,当计算机处理器的速度发生变化时,必须修改技术限制。更好的方法是让系统时钟来完成这种工作。

有一个函数可以完成这项工作,函数名为clock(),返回程序开始执行后所用的系统时间。但涉及到两个问题:首先,clock()返回的不一定是秒,其次,该函数返回的类型在某些系统上可能是long,在另一个系统可能是unsigned long或其他类型。

头文件ctime提供了解决方法:

  • 首先,定义了一个符号常量——CLOCK_PER_SEC,该常量等于每秒钟包含的系统时间单位数。系统时间除以这个值,可以得到秒数。
  • ctime将clock_t作为clock()返回类型的别名,这意味着可以讲变量声明为clock_t类型,编译器把它转换为long、unsigned long或其他适合系统的类型。
#include <iostream>
#include <ctime>
int main(){
	using namespace std;
	cout<<"Enter the delay time: ";
	float secs;
	cin>>secs;
	clock_t delay=secs*CLOCKS_PER_SEC;
	cout<<"starting\a\n";
	clock_t start=clock();
	while (clock()-start<delay)
		;
	cout<<"done\a\n";
	return 0;
}

类型别名

c++为类型立别名的方式有两种:

  1. 使用预处理器

    #define BYTE char //在编译程序时用char替换所有的BYTE,从而使BYTE成为char的别名。

  2. 使用typedef

    typedef char byte;//将byte作为char的别名

不过声明一系列变量时,用define不适用:

#define FLOAT_POINTER float *
FLOAT_POINTER pa,pb;

预处理器将声明转换为这样:

float *pa,pb; //pa转换为float指针,而pb只是一个float。

typedef则不会有这样的问题。

do while 循环

do while 属于出口条件循环,先执行循环体,在再判定测试表达式,这样循环至少执行一次。

有时使用do while循环更为合理,例如:请求用户输入时,程序必须先获得输入,然后对他进行测试。

#include <iostream>
int main(){
	using namespace std;
	cout<<"Enter the delay time: ";
	int n;
	cout<<"enter number ";
	cout<<"my \n";
	do
	{
		cin>>n;
	}while(n!=7);
	cout<<"Yes\n";
	return 0;
}

基于范围的for循环(c++11)

它简化了一种常见的循环任务:对数组(或容器类,如vector或array)的每个元素执行相同的操作。

double prices[5]={1.2,3.4,5.6,6.7,6.7};
for (double x:prices)
	cout<<x<<std::endl;

该循环显示数组中的每个值。

要修改变量中的元素,使用不同的变量语法:

for (double &x:prices)
	x=x*0.80;

循环和文本输入

使用原始的cin进行输入

#include <iostream>
int main(){
	using namespace std;
	char ch;
	int count=0;
	cout<<"enter \n";
	cin>>ch;
	while(ch!='#')
	{
		cout<<ch;
		++count;
		cin>>ch;  //这一步极其重要,没有这一步,循环将反复处理第一个输入字符
	}
	cout<<endl<<count<<"read\n";
	return 0;
}

但存在一个问题是,输入中的空格没有被回显,原因在于cin在读取char时,会忽略空格和换行符。

使用cin.get(char)进行补救

通常,逐个字符读取输入的程序需要检查每个字符,包括空格、制表符和换行符。

cin.get(ch)读取输入中的下一个字符(即使它是空格),并将其赋给变量ch 。使用这个函数调用替换cin>>ch;可以修补上一个程序的问题。

使用哪一个cin.get()

函数重载允许创建多个同名函数,条件是它们的参数列表不同。例如:

c++中使用cin.get(name,Arsize)和cin.get(ch)

文件尾条件

很多操作系统都支持重定向,允许用文件替换键盘输入。例如,假设在windows中有一个名为gofish.exe的可执行程序和一个名为fishtale的文本文件,则可以再命令提示符模式下输入下面的命令:gofish <fishtale

这样程序将从fishtale文件(而不是键盘)获取输入。

getchar()和putchar()

需要包含头文件stdio.h(或cstdio)

不接受任何参数的cin.get()成员函数返回输入中的下一个字符:

ch=cin.get();

也可以使用cout.put()来显示字符:

cout.put(ch);

嵌套循环和二维数组

#include <iostream>
const int Cities=5;
const int Years=4;
int main(){
	using namespace std;
	const char * cities[Cities]={
	"a","b","c","d","e"
	};

	int maxtemps[Years][Cities]={
		{1,2,4,4,5},
		{1,2,7,4,5},
		{1,2,4,8,5},
		{1,2,5,4,5}
	};

	cout<<"max:\n";
	for (int city=0;city<Cities;++city){
		cout<<cities[city]<<":\t";
		for (int year=0;year<Years;++year)
			cout<<maxtemps[year][city]<<"\t";
		cout<<endl;
	}
	return 0;
}

1553765113070

输出中使用制表符比使用空格可使数据排列更有规则。

猜你喜欢

转载自blog.csdn.net/susanhc/article/details/88879001