目录
- 一.开始
- 1.1
- 二.变量和基本类型
- 1.1
- 1.2
- 1.3
- 1.3
- 1.4
- 1.5
C++ Peimer习题集第5版练习。
一.开始
1.1
编写程序,提示用户输入2个整数,打印出这两个整数指定的范围内的所有整数。
方式1:使用while循环。
#include<iostream>
using namespace std;
int main()
{cout<<"请输入2个整数:"<<endl;int v1,v2;cin>>v1>>v2;cout<<"输入结束"<<endl;if(v1>v2){while(v1>=v2){cout<<v1<<",";v1--;}}else{while(v1<=v2){cout<<v1<<",";v1++;}}cout<<endl;return 0;
}
方式2:使用for循环。
#include<iostream>
using namespace std;
int main()
{cout<<"请输入2个整数:"<<endl;int v1,v2;cin>>v1>>v2;cout<<"输入结束"<<endl;if(v1>v2){for(;v1>=v2;v1--){cout<<v1<<",";}}else{for(;v1<=v2;v1++){cout<<v1<<",";}}cout<<endl;return 0;
}
思考:对比for循环和while循环,两种形式的优缺点是什么?
在循环次数已知的情况下,for循环的形式更加简洁。
在循环次数无法预知时候,用while循环实现更适合。
二.变量和基本类型
1.1
读程序写结果。
#include<iostream>
using namespace std;
int main()
{unsigned u=10,u2=42;cout<<u2-u<<endl;cout<<u-u2<<endl;int i=10,i2=42;cout<<i2-i<<endl;cout<<i-i2<<endl;cout<<i-u<<endl;cout<<u-i<<endl;return 0;
}
运行结果:
32
4294967264
32
-32
0
0
思考:为什么u-u2会等于4294967264?
- 首先看u2-u,42-10=32没有疑问。
- u-u2属于无符号数之间的减法,无符号数字做减法,一定要确保结果非负数,否则会输出取模后的值。
- i2-i=32。
- i-i2=-32。
- i-u和u-i,当算术表达式中,既有无符号数值又有int值时,int值被转换为无符号数。具体转换的数值根据对应计算机环境中int的占位数。
因此,为了避免错误,切勿混合使用带符号类型和无符号类型。
1.2
编写代码分别更改指针的值以及指针所指对象的值。
#include<iostream>
using namespace std;
int main()
{int i=5,j=10;int *p=&i;cout<<p<<" "<<*p<<endl;p=&j;cout<<p<<" "<<*p<<endl;*p=20;cout<<p<<" "<<*p<<endl;j=30;cout<<p<<" "<<*p<<endl;return 0;
}
运行结果:
0xca7b9ff964 5
0xca7b9ff960 10
0xca7b9ff960 20
0xca7b9ff960 30
思考:本题旨在考查指针的含义,指针本身的值和指针所指对象的值的区别。
1.p是一个整型指针,初始的时候令p指向变量i,此时cout<<p即输出p所指对象的内存地址0xca7b9ff964,cout<<*p即输出p所指对象的值5。
2. p=&j,会更改指针的值,令p指向整数j,此时cout<<p即输出p所指对象的内存地址0xca7b9ff960 ,cout<<*p即输出p所指对象的值10。
3. *p=20和j=30,都改变了指针所指向对象的值,但是指针所指向的地址没有发生变化。
1.3
解释代码:
#include<iostream>
using namespace std;
int main()
{int i=42;int *p1=&i;*p1=*p1 * *p1;cout<<*p1<<endl;return 0;
}
运行结果:
1764
思考:首先定义了一个整形变量i并将其设初值为42,接着定义了一个整型指针p,指向i,然后取出指针p1所指对象的值,计算平方后重新赋给p1所指向对象的值。
1.3
下面的语句在C++中合法吗?
int i=0;
int *ip=i;
非法的,不能直接把int变量赋给int指针,正确的做法是通过取地址运算符得到变量i在内存中的地址,然后将该地址赋给指针。
1.4
假设p是一个int类型指针,请说明下述代码的含义。
if(p)//...
if(*p)//...
先来看一段程序:
#include<iostream>
using namespace std;
int main()
{int i=0;int *p1= nullptr;//空指针int *p=&i;if(p1)//检验指针的值(即指针所指向对象的地址){cout<<"p1 pass"<<endl;}if(p) //检验指针的值(即指针所指向对象的地址){cout<<"p pass"<<endl;}if(*p) //检验指针所指对象的值{cout<<"i pass"<<endl;}return 0;
}
运行结果:
p pass
对于if语句来说,if(表达式)括号里的表达式为1或者true时,才会满足条件执行。当指针p作为if语句的条件时,实际检验的是指针本身的值,即指针所指向对象的地址。
上面的程序中,p和p1是两个整型指针,其中p1被定义为空指针(nullptr),p则指向整数i。在三个if判断条件中,p1指向为空,即指向地址为0,条件不满足;p指向i,在内存中有一个实际的地址值且不为0,因此满足条件;p表示所指对象的值,即p=0,因此if条件不满足,所以最终输出结果为p pass。
1.5
说明下面的定义是什么意思,挑选出其中不合法的。
- int i,*const cp;
- int *p1,*const p2;
- const int ic,&r=ic;
- const int *const p3;
- const int *p;
1是非法的,cp是一个常量指针,因为常量指针所指向的值不能被改变,因此必须初始化,如:int i=0;*const cp=&i。
2是也是如此,p2是一个常量指针,因为常量指针所指向的值不能被改变,因此必须初始化。
3是非法的,ic是一个常量,他的值不能被改变,因此必须初始化。
4是非法的,p3是一个常量指针,他的值不能被改变,必须初始化;同时p3是常量,因此不能通过p3改变所指对象的值。
5是合法的。
思考:要注意常量引用、常量指针、指向常量的指针的区别。其实区别这些比较绕口的东西,只需要按照命名顺讯来读就行。
- 常量指针:指针的指向不可以修改,指针指向的值也不可以修改。例如int * const p =&a;首先是一个指针int * , 然后一个const常量 那么p就是指针常量。
- 常量指针:指针的指向可以修改,但是指针指向的值不可以修改。例如:const int *p=&a;首先是一个const常量, 然后一个指针int * 那么p就是常量指针。
- 指向常量的常指针:指针的指向不可以修改,指针指向的值也不可以修改。例如:const int const *p=&a。