c++ primer(第五版)学习笔记及习题答案代码版(第四章)表达式

本文深入探讨了C++中的表达式和运算符,包括它们的基本概念、使用技巧及注意事项。文章覆盖了从简单算术运算到复杂逻辑运算的各种场景,并提供了丰富的示例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笔记较为零散,都是自己不熟悉的知识点。
习题答案至于一个.cc 中,需要演示某一题直接修改 #define NUM**, 如运行4.23题为#define NUM423;
chapter 4
1、表达式:
当一个对象呗用作右值时,用的是对象的值(内容);当对象被用作左值时,用的是对象的身份(在内存中的位置)。
int i = 0;
cout << i <<" "<< ++i <<endl;     //未定义的,<<运算符没有明确规定何时以及如何对运算对象求值
2、
如果某机器short类型占16位,则最大的short数值是32767.
short short_value = 32767;     //16位最大数值
short_value += 1;               //该计算导致溢出
cout<< short_value <<endl;      //输出可能是 -32768,该值发生了“环绕” 
3、
短路求值:当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧对象的值,这种策略为短路求值。
因为赋值运算符的优先级低于关系运算符的优先级, 所以在条件语句中,赋值部分通常加上括号。
4、解引用和递增运算符
auto pbeg  = v.begin();
while(pbeg != v.end()&& *beg >= 0)    //输出元素直到第一个负值为止
     cout<< *pbeq++ <<endl;     //输出当前值并将pbeg向前移动一个元素
因为后置递增运算符优先级高于解引用运算符,因此,*pbeg++等价于*(pbeg++)。
最终这条语句输出pbeg开始时指向的那个元素,并将指针向前移动一个位置。
等价于:
cout << *iter <<endl;
++iter;
5、
for(auto it = s.begin(); it!= s.end() && !isspace(*it); ++it)
  *it = toupper(*it);               //将当前字符改成大写
while(beg != s.end() && !isspace(*beg))
  *beg = toupper(*beg++);         //错误:赋值语句未定义,编译器不知道先执行左侧的值还是右侧的值
6、

强制类型转换:cast-name<type>(expression), type是要转换的目标,expression是要转换的值。如果type是引用类型,则结果时左值。const-name有static_cast/dynamic_cast/const_cast/reinterpret_cast。

const_cast只能改变原酸对象的底层const。

#include<iostream>
#include<vector>
#define NUM433

using namespace std;

int main(){
/*4.1*/
#ifdef NUM41
	cout<< 5 + 10*20/2<<endl;
#endif
/*4.2*/
#ifdef NUM42
	vector<int> vec(10);
	*vec.begin();  *(vec.begin());
	*vec.begin()+1;  (*(vec.begin()))+1;
#endif
/*4.3*/
#ifdef NUM43
	cout<<"这种权衡是有益的,c++的最大优势是运行速度,所以我们更需要编译去更高效的工作。因为作为使用者,要避免未定义的行为出现。"<<endl;
#endif
/*4.4*/
#ifdef NUM44
	cout<< 12 / 3 * 4 + 5 * 15 + 24 % 4 / 2 <<endl;
	cout<< ((12 / 3) * 4) + (5 * 15) + ((24 % 4) / 2) <<endl;
#endif
/*4.5*/
#ifdef NUM45
	cout<< "(a) " << -30 * 3 + 21 / 5 <<endl;
	cout<< "(b) " << -30 + 3 * 21 / 5 <<endl;
	cout<< "(c) " << 30 / 3 * 21 % 5 <<endl;
	cout << "(d) " << -30 / 3 * 21 % 4 <<endl;
#endif
/*4.6*/
#ifdef NUM46
	int val;
	val % 2 == 0 ? "even" : "odd";
#endif
/*4.7*/
#ifdef NUM47
	cout<< "表达式的求值结果超出了其类型的表示范围."<<endl;
	int val1 = 32767;	cout << ++val1<< endl;  //(int类型为16位)
	unsigned val2 = 0;  cout<< --val2 <<endl;
	unsigned short val3 = 65535;  cout << ++val3 <<endl;
#endif
/*4.8*/
#ifdef NUM48
	cout<<"采用'短路求值'的策略,即先计算左操作数,再计算又操作数,仅当左操作数无法确定逻辑运算结果时,才会计算右操作数. == 运算符优先级高于其他运算符. "<<endl;
#endif
/*4.9*/
#ifdef NUM49
	const char *cp = "Hello World ";
	if(cp && *cp)
		cout << *cp <<endl;
	cout<<"cp 是指向const char* 的指针,不是空指针,cp为true;*cp是const char'H',也为true,所以逻辑判断为真。" <<endl;
#endif
/*4.10*/
#ifdef NUM410
	int val(0);
	while(cin >> val){
		if(val == 42)
			return 0;
	}
#endif
/*4.11*/
#ifdef NUM411
	cout<<" a > b && b > c && c > d "<<endl;
#endif
/*4.12*/
#ifdef NUM412
	cout<< " i != j < k, 等于 i != (j < k), 为满足表达式的意图可以转换为 i != j && j < k."<<endl;
#endif
/*4.13*/
#ifdef NUM413
	int i; double d;
	d = i = 3.5;
	cout <<"(a) " << i << " " << d <<endl;
	i  = d = 3.5;
	cout <<"(b) " << i << " " << d <<endl;
#endif
/*4.14*/
#ifdef NUM414
	cout << "第一行,左值不是变量,无法赋值,报错;第二行,if条件为真. "<<endl;
#endif
/*4.15*/
#ifdef NUM415
	cout<<"pi是指向int型的指针,不能将int* 型指定为int类型; "
		" dval = ival =0;  pi = 0; "<<endl;
	double dval; int ival; int *pi;
	dval = ival = pi = 0;
#endif
/*4.16*/
#ifdef NUM416
	cout<<"(a) = 的优先级比!=的优先级低,将getPtr()是否为0的值赋给p,结果不是真就是假.改为:if((p == getPtr()) != 0)"
		"(b) 表达式想要得到 i 是否等于1024,而非赋值操作, 改为if(i==1024)"<<endl;
#endif
/*4.17*/
#ifdef NUM417
	cout<<"前置递增是将修改后的操作数的值作为表达式的值;而后置递增试将操作数原来的,未经修改的值作为表达式的值。"<<<endl;
#endif
/*4.18*/
#ifdef NUM418
		int i = 0;
		cout << i <<" "<< i++<<endl;
		vector<int> v ={1,2,3,-1};
		auto pbeg  = v.begin();
		while(pbeg != v.end()&& *pbeg >= 0)
			cout<< *++pbeg<<" ";
	cout<<"会导致v的第一个元素没有输出,并且企图对一个多余的元素进行解引用,操作很危险. "<<endl;
#endif
/*4.19*/
#ifdef NUM419
	cout<<"(a) 检查ptr是否为空指针,并且检查ptr所指的值是否为0. "
		"(b) 检查ival 以及ival+1是否为0. "
		"(c) 不合法,未定义的表达式。改为vec[ival] <= vec[ival+1]"
#endif
/*4.20*/
#ifdef NUM420
	cout<<" (a) 返回*iter, 然后 ++iter; (b)不合法,*iter为string类型,不能做加操作."
	"(c) 不合法,迭代器iter必须用->表示是否为空. "
	"(d) 表示iter的值是否为空;  (e) 不合法,string类型不能做加操作;(f)先返回iter->empty(),再进行++iter." <<endl;
#endif
/*4.21*/
#ifdef NUM421
	vector<int> vec = {1,2,3,4,5,6,7,8};
	cout<<"奇数翻倍得到:  ";
	for(vector<int>::iterator c = vec.begin(); c != vec.end(); ++c)
		if(*c % 2){
			*c = *c *2;
			cout<< *c <<" ";
		}
	cout<<endl;
#endif
/*4.22*/
#ifdef NUM422
	double grade;  string finalgrade;
/*条件运算符*/
	cout << "Enter the finalgrade: "<<endl;
	cin >> grade;
	finalgrade = (grade > 90) ? "high pass" : (60 < grade < 75) ? "low pass" :(grade < 60) ? "fail" : "pass";
	cout << finalgrade<<endl;
/*if条件句*/
	cout << "Enter the finalgrade: "<<endl;
	cin >> grade;
	if(grade > 90){  
		finalgrade = "high pass"; 
		cout<< finalgrade<<endl;
	}
	else if (60 < grade < 75){
		finalgrade = "low pass"; 
		cout<< finalgrade<<endl;
	}	
	else if(grade < 60 ){
		finalgrade = "fail";
		cout<< finalgrade<<endl;
	}
#endif
/*4.23*/
#ifdef NUM423
	cout <<"根据优先级,条件运算符?:要低于+,修改为:string p1 =s + (s[s.size()-1] == 's' ? '' : 's' "<<endl;
#endif
/*4.24*/
#ifdef NUM424
	cout<<"当条件运算符,满足左结合律,该语句相等于"
	"finalgrade = ((grade > 90) ? 'high pass' : (grade < 60)) ? 'fail' : 'pass' ; 当grade总是大于90时,finalgrade总是fail" <<endl;
#endif
/*4.25*/
#ifdef NUM425
	cout<< (~'q' << 6) <<endl;
	cout<< "最终值为-7296,"<<endl;
#endif
/*4.26*/
#ifdef NUM426
	cout<< "大部分情况没有差别,unsigned int 与unsigned long一样大小,但是unsigned long可以确保变量占有至少32位. "<<endl;
#endif
/*4.27*/
#ifdef NUM427
	cout<<"(a) 3 ; (b) 7 ; (c) true ; (d) true ; "<<endl;
#endif
/*4.28*/
#ifdef NUM428
	cout <<"char " << sizeof(char)<<endl;
	cout << "short " << sizeof(short)<<endl;
	cout << "unsigned " << sizeof(unsigned)<<endl;
	cout << "int "<< sizeof(int)<<endl;
	cout << "unsigned int "<< sizeof(unsigned int)<<endl;
	cout << "long "<< sizeof(long)<<endl;
	cout << "unsigned long "<< sizeof(unsigned long)<<endl;
	cout << "float " << sizeof(float)<<endl;
	cout << "double "<< sizeof(double)<<endl;
	cout << "void* " << sizeof(void*)<<endl;
#endif
/*4.29*/
#ifdef NUM429
	int x[10]; int *p = x;
	cout << sizeof(x) / sizeof(*x) <<endl;
	cout <<sizeof(p) / sizeof(*p) <<endl;
#endif
/*4.30*/
#ifdef NUM430
	cout<< "(a) sizeof(x)+y; (b)sizeof(p->mem[i]); (c)sizeof(a) < b; (d)sizeof(f());"
#endif
/*4.31*/
#ifdef NUM426
	cout << "前置递增更为方便,但是在必要的时候也需要用后置版本."<<endl;
	for(vector<int>::size_type ix = 0; ix !=ivec.size(); ix++, cnt--)
		ivec[ix] = cnt;
#endif
/*4.32*/
#ifdef NUM432
	cout<<"ptr代表指向ia数组的指针,ix是ia数组的下标,两者的作用都是用来遍历数组元素。"<<endl;
#endif
/*4.33*/
#ifdef NUM433
	int someValue = 0, result(0);  //改变值的真假看看x和y的值有何不同
	int x(3), y(3);
	result  = someValue ? ++x, ++y : --x, --y;
	cout<< "x: "<<x <<" y: " <<y <<" result: " <<result <<endl;
	cout<<"因为,的优先级最低,++ --的优先级最高,所以表达式等同于:  "
	"(someValue ? (++x)), ((++y) : (--x)), (--y),即someValue为真,那么++x,结果为++x;如果为假,--x,结果为--x. "<<endl;
#endif
/*4.34*/
#ifdef NUM434
	cout<<"(a)fval转换成bool类型; (b)ival转换成float,fval的结果加上ival转换成double. "
		"(c)cval转换成int,int和ival转换成double. "<<endl;
#endif
/*4.35*/
#ifdef NUM435
	cout<< "(a)'a'转换成int,int和3相加的结果转换成cval. (b)ival钻换成double,ui转换成double,double转换成flaot; (c)ui提升为float,float转换为double; (d)ival转换成float,两个float的和转换成double,double转换成char。"<<endl;
#endif
/*4.36*/
#ifdef NUM436
	int i =2 ; double d = 2.3;
	i *= static_cast<int>(d);
	cout<< i<<endl;
#endif
/*4.37*/
#ifdef NUM437
	int i; double d; const string *ps; char *pc; void *pv;
	pv = const_cast<string*>(ps);
	i = static_cast<int>(*pc);
	pv = static_cast<void*>(&d);
	pc = reinterpret_cast<char*>pv;
#endif
/*4.38*/
#ifdef NUM438
	cout<<"将j/i的值转换成double赋给slope"<<endl;
#endif
	return 0;
}
参考资料:
c++ primer中文版第五版,电子工业出版社。
c++ primer第四版习题解答,人民邮电出版社。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值