C++笔记(1)

来源:互联网 发布:uu加速器for mac 编辑:程序博客网 时间:2024/05/22 14:28

学习C++已经很长时间,最近感觉在细节上对于c++了解还不是很深刻,于是打算读一遍《C++ Primer》,并对一些地方做一些记录

1、endl 的作用:  endl是C++标准库中的操控器(Manipulator),主要作用是换行+刷新缓冲区。

2、char:与其他整型不同,字符型被分为3种:char、unsigned char、signed char。其中char类型是不确定的,根据编译器决定是unsigned、或者是signed类型。

3、有符号型的数尽量不要和无符号类型的数一起运算,因为在这种情况下带符号数会先转换成无符号数进行运算。

4、初始化赋值是不同的,初始化是指创建变量时赋予其一个初始值,而赋值的含义是把当前的值擦除,以一个新值来替代。

5、声明定义的区别和联系:extern int  a; 为声明主要目的是扩展变量的作用域。extern int a = 8; 此处为定义,当有初始化发生时extern就失去意义。

6、const: extern const  int  a = 10; 为定义,extern const int a; 为声明。其中关于常量引用:

int  i = 3;const int &j = i;//这样是允许的j = 2;//非法的int &k = j; //这样是不允许的
7、范围for语句C++11中的标准

string s = "Hello Word!!";for(auto c : s)     if(ispunct(c))            cout<<c<<endl;
范围for语句中改变string内的内容

string s = "Hello Word!!";for(auto &c : s)       if(ispunct(c))               c = '?';

8、当使用vector并且要向vector内添加元素时,不能使用范围for


9、使用迭代器iterator

string s = "Hello Word!!";for(auto it = s.begin(); it != s.end(); it++)       cout<<*it<<endl;

10、左值(lvalue)、右值(rvalue)

在C语言中,我们常常会提起左值(lvalue)、右值(rvalue)这样的称呼。而在编译程序时,编译器有时也会在报出的错误信息中会包含左值、右值的说法。不过左值、右值通常不是通过一个严谨的定义而为人所知的,大多数时候左右值的定义与其判别方法是一体的。一个最为典型的判别方法就是,在赋值表达式中,出现在等号左边的就是“左值”,而在等号右边的,则称为“右值”。比如:

a = b + c;

在这个赋值表达式中,a就是一个左值,而b + c则是一个右值。这种识别左值、右值的方法在C++中依然有效。不过C++中还有一个被广泛认同的说法,那就是可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值。那么这个加法赋值表达式中,&a是允许的操作,但&(b + c)这样的操作则不会通过编译。因此a是一个左值,(b + c)是一个右值。

这些判别方法通常都非常有效。更为细致地,在C++11中,右值是由两个概念构成的,一个是将亡值(xvalue,eXpiring Value),另一个则是纯右值(prvalue,Pure Rvalue)。可以简单的说左值可以被赋值,右值不能被赋值。

11、求值顺序

 C语言跟大多数语言一样,没有规定表达式的求值顺序,除了以下几个顺序点:
        ;(分号,标志一条语句结束)
        ,(逗号操作符,函数参数列表里面的逗号只起分隔作用,不是逗号操作符)
        &&||(逻辑与,逻辑或)
        ? : (条件运算符)
        ()(if,while,for, do..while,以及函数调用)
这些统称为序列点(sequence point),它们的求值顺序有规定。序列点其实就是c/c++对表达式求值顺序唯一的约束,这个约束可以简单理解为:

(1)只有一个序列点前后的代码才能确定求值顺序,两个序列点之间的求值顺序是不定的

(2)在两个相邻的序列点之间,一个对象最多只允许它储存的值被修改一次

并且访问这个对象的初始值的唯一目的只能是确定新值。子表达式的任意执行顺序都必须满足这个要求,否则代码的行为将是未定义的。

下面结合几个例子说明
n = n++;                         //两个序列点(分号)之间两次修改n
a[i] = i++;                       //求值顺序是不确定的《C programming Language 2nd》上的一个例子
n = f1() + f2() + f3();       //f1,f2,f3谁先被调用,谁后被调用,这是不一定的,C语言标准没有对此作规定。

int i = 7;  
printf("%d\n", i++ * i++); //第一个自增操作和第二个自增操作以及乘法操作的顺序是不一定的,所以结果根本无法确定

特别说明一下逗号操作符,函数参数列表里面的逗号只起分隔作用,不是逗号操作符。
逗号操作符一般形式exp1, exp2...。C语言保证exp1在exp2之前求值,并且exp1求值的副作用保证在逗号之前生成。所以象下面这个逗号表达式:
int i = 1;
i++, (i == 2);
最后的值就是1,因为逗号表达式的前半部分i++的副作用(i自增1)在逗号之前已经生成,所以当执行到(i == 2)的时候,i的值已经是2了,所以i == 2成立,(i == 2)的值便作为整个逗号表达式的值。

12、算术运算符

(1)算术运算符的运算结果都是右值

(2)算术运算符中一元负号运算符取负后,返回(提升后的)副本

int i = 1; int k = -i;  k--> -1               k是-1

bool b = ture; bool b2 = -b; b--->1 ---> -1 ---> b2   b2是true

13、类型转换



实线为必须转换的情况

0 0
原创粉丝点击