2-10 汇总前面的学习经验(第四章、第五章)(贰)

第五章   表达式(C++语言定义的操作符,使用内置类型的操作数)

一元操作符unary,如取地址操作符&,解引用操作符*

二元操作符binary,如加法操作符+,减法操作符-

5.1&5.2算数操作符、关系操作符、逻辑操作符

溢出:表达式的求值结果超出了其类型的表示范围。

关系操作符和逻辑操作符使用算术或指针类型的操作数,并返回bool类型的值:&&与,||或

string s("Expression in c++ are composed by some data and control symbols");
string::iterator it = s.begin();
while(it != s.end() && !isspace(*it)){
      *it = toupper(*it);
      ++it;
}
cout << "convert the string to" << endl;

if(i < j < k)语句中的k与0、1相比较,关系操作符是从左开始进行计算

bool值本身可以进行if()语句的判断,bool值为真是1,为假是0.

5.3位操作符bitwise operator

char是C/C++整型数据中比较古怪的一个,其它的如int/long/short等不指定signed/unsigned时都默认是signed,但char在标准中是unsigned

0UL  表示  无符号长整型0    unsigned long

1UL   表示   无符号长整型 1   unsigned long

如果不写UL后缀,系统默认为:int, 即,有符号整数。

1.数值常数有:整型常数、浮点常数;
2.只有数值常数才有后缀说明;
3.数值常数后缀不区分字母大小写。
(1)整型常数的表示形式有:十进制形式、以0开头的八进制形式、以0x开头的十六进制形式,无二进制形式。
整型常数默认是signed int的。
对整型常数进行类型转换的后缀只有:u或U(unsigned)、l或L(long)、u/U与l/L的组合(如:ul、lu、Lu等)。例:100u; -123u; 0x123l;
(2)浮点常数的表示形式有:科学计数形式和小数点形式。
浮点常数默认是double的。
对浮点常数进行类型转换的后缀只有:f或F(单精度浮点数)、l或L(长双精度浮点数)。(注:因浮点型常数总是有符号的,故没有u或U后缀)。例:1.23e5f; 1.23l; -123.45f;

位操作符:~ 位求反      << 左移    >>  右移   & 位与   ^ 位异或    | 位或

bitset<30>  bitset_quizl;

unsigned long int_quizl = 0;

bitset_quizl.set(27);使用bitset来进行赋值计算

逻辑与、逻辑或操作符采用成为“短路求值”(short-circuit evaluation)的求值策略

输入输出标准库(IO library)分别重载了位操作符 >> 和 << 用于输入和输出。

移位操作符具有中等优先级:其优先级比算术操作符低,高于关系操作符、赋值操作符、条件操作符

5.4赋值操作符

数组名是不可修改的左值,而下标和解引用操作符都返回左值。

赋值操作符的优先级低于  不等操作符      赋值操作符具有“右结合性”

5.5、5.6自增和自减操作符

尽量使用前自增操作:前置操作只需要加1后返回加1后的结果;后置操作符必须先保存操作数原来的值,以便返回未加1的值作为操作结果。

后自增操作优先级 > 解引用操作

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。可以对指针进行四种算术运算:++、--、+、-

#include<iostream>
#include<string>
#include<vector>
using namespace std;

int main()
{
	vector<string*> spevc;

	//读取vector对象
	string pv;
	while (cin >> pv) {
		string *tr = new string;    //指向string 的指针
		*tr = pv;
		spevc.push_back(tr);    //push_back必须两个的类型相同  spevc为指向string的指针,而tr也必须是指针
	}

	//输出每个string 的内容及大小
	vector<string*>::iterator iter = spevc.begin();
	while (iter != spevc.end()) {
		cout << "every string is " << **iter << (**iter).size() << endl;    //第一个*解释的是迭代器iterator的地址,第二个*解释的是迭代器中元素的地址
		cout << "every string is " << *iter << endl;    //*iter的类型为std::vector<string>::iterator类型
		iter++;
	}

	//释放各个动态分配的string对象
	iter = spevc.begin();
	while (iter != spevc.end()) {
		delete *iter;
		iter++;
	}
	return 0;
}

iter -> empty()调用iter所指向的string对象的成员函数empty

iter++ -> empty()调用iter所指向的string对象的成员函数empty,并使iter加1

5.7、条件操作符

语法格式:cond ?expr1:expr2;cond为条件判断表达式,为真时计算expr1。为假时计算expr2。    二元判断的最优选择

int max = i > j

                    ?  i > k ? i : k

                    :  j > k ? j : k;

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int T;
	vector<int> s;
	while (cin >> T) {
		s.push_back(T);
	}

	for (vector<int>::iterator iter = s.begin(); iter != s.end(); iter++) {
		*(iter+1) = ((*iter > *(iter + 1)) ? *iter : *(iter + 1));
		cout << *(iter + 1) << endl;
	}
    return 0;
}

 

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	vector<int> ivec(20, 1);
	;
	size_t a = 0;
	
	for (; a != ivec.size(); ++a) { //for语句中必须要有两个分隔符,隔开三个语句
		
		if (a % 2 == 0) {
			ivec[a] = ivec[a] * 2;
			cout << ivec[a] << endl;
		}
		else
		{
			cout << ivec[a] << endl;
		}
		  
	}	
	return 0;
}
//  int iv, a = 0;
//  while (cin >> iv)
//		ivec.push_back(iv)
//  for (vector<int>::iterator i = ivec.begin(); i != ivec.end(); i++) {
//  if ((*i % 2) == 0) {
		//		*i = *i * 2;

5.8 sizeof () 操作符

      返回一个对象或类型名的长度,类型为size_t  表达式的结果为编译时常量

      1、对 char 类型或值为 char 类型的表达式做 sizeof 操作保证得 1。

      2、对引用类型做 sizeof 操作将返回存放此引用类型对象所需的内在空间大小。

      3、对指针做 sizeof 操作将返回存放指针所需的内在大小;注意,如果要获取该指针所指向对象的大小,则必须对指针进行引用。 

      4、操作等效于将对其元素类型做 sizeof 操作的结果乘上数组元素的个数。

5.9 逗号操作符

      逗号表达式是一组由逗号分隔的表达式,这些表达式从左向右计算。逗号表达式的结果是其最右边表达式的值。

5.10 优先级

       ++ 的优先级高于 * 操作符

       第二个规则有一个重要的例外:如果一个子表达式修改操作数的值,然后将该子表达式的结果用于另一个子表达式,这样则是安全的。例如,*++iter 表达式的自增操作修改了 iter 的值,然后将 iter(修改后)的值用作 * 操作符的操作数。对于这个表达式或其他类似的表达式,其操作数的计算次序无关紧要。而为了计算更复杂的表达式,改变操作数值的子表达式必须首先计算。这种方法很常用,不会产生什么问题。

5.11 new 和 delete 表达式

        动态创建和释放数组、单个对象等。

        定义变量时,必须指定其数据类型和名字。而动态创建对象时,只需指定其数据类型,而不必为该对象命名。取而代之的是,new 表达式返回指向新创建对象的指针,

        对于类类型的对象,用该类的默认构造函数初始化,string类型等提供了默认构造函数;而内置类型的对象则无初始化。

         int *pi = new int();

         delete p;删除语句后,p没有定义,但是仍然存放了之前所指对象的地址。p所指向的内存已释放,p不再有效,变为悬垂指针。悬垂指针指向曾经存放对象的内存,但该对象已不存在。delete语句需要指向指针的对象。

         const int *pci = new const int(1024);

5.12 类型转换

        隐式类型转换:混合类型转换相同类型;用作条件的表达式被转换为bool类型。

        最简单的转换为整型提升:对于所有比 int 小的整型,包括 char、signed char、unsigned char、short 和 unsigned short,如果该类型的所有可能的值都能包容在 int 内,它们就会被提升为 int 型,否则,它们将被提升为 unsigned int。如果将 bool 值提升为 int ,则 false 转换为 0,而 true 则转换为 1。

         在使用数组时,大多数情况下数组都会自动转换为指向第一个元素的指针;

         不将数组转换为指针的例外情况有:数组用作取地址(&)操作符的操作数或 sizeof 操作符的操作数时,或用数组对数组的引用进行初始化时,不会将数组转换为指针。

         指向任意数据类型的指针都可转换为 void* 类型;整型数值常量 0 可转换为任意指针类型

         while(cin >> s)其中,while循环条件为bool类型的值,此时给出的却是istream类类型的值,istream类型的值应该转换为bool类型。将istream类型转换为bool类型需要检验流的状态。

          显式转换:强制类型转换cast,static cast、dynamic cast、const cast、reinterpret cast

         dynamic_cast支持运行时识别指针或引用所指向的对象

         const_cast 将转换掉表达式的 const 性质

                            const char *pc_str;

                             char *pc = string_copy(const_cast<char*>(pc_str)); 

         static_cast 编译器隐式执行的任何类型转换都可以显式完成

         reinterpret_cast 通常为操作数的位模式提供较低层次的重新解释。

          旧式强制转换符号有下列两种形式:

           type (expr);     // Function-style cast notation

          (type) expr;      // C-language-style cast notation

           

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章