1.算术类型中,char 在某些机器上是定义为无符号的,有些是定义为有符号的
2.执行浮点数运算选用doulble类型,因为精度足够又与float的计算代价相差无几
3.赋值给无符号类型一个超出它表示范围的值时,将超出的最高位截断。
4.赋值给有符号类型一个超出它表示范围的值,结果是未定义的
5.有符号数和无符号数运算时会自动转换为**无符号**数
6.c++11中新标准:
变量初始化:
int a={0};
int a{0};//11标准,但是若是有丢失风险,则会报错
int a(0); (有丢失风险会强制转换)
7.声明与定义分离开
extern int a; //声明并不定义a,不能显式的初始化,否则不再是声明变成定义
定义只能一次,声明可以多次
8.名字的作用域一旦定义于{}之中,则只有块作用域,否则有全局作用域
9.作用域可以嵌套,内层的可以访问外层的名字,并允许内层作用域重新定义外层已有的名字
同时默认为内层独立的名字,可以使用域操作符::来覆盖默认的作用域规则
如:
int a=10;
{
int a=7;
::a==10; //全局作用域本身并没有名字
a==7;
}
10.引用(类似别名)
1.必须被初始化,并且一直绑定在一起
2.不能定义引用的引用
3.引用只能绑定在对象上,不能与某个字面值或者表达式常量绑定
加上const 就是另外一个说法
4.一般情况,必须引用类型与与之绑定的对象类型相同
11.c++11中空指针的另外一个名字叫nullptr
12.指向指针的引用
int *p; int *&r=p;
int *p, *&r=p;
12.5. using a=int ;
类型别名a作为int的别名
-
const 引用
正确 T 错误 F F int &r; //未初始化 F int &r=4; //引用不可以为常量或者字面值 F int &r=i+4; //引用不可以为表达式 F int &r=f; //(f为float) //类型不同 T const int i=get_size(); //运行时初始化 T const int j=42; //编译时初始化 F const int k; //const需要初始化 T extern const int k; extern const int k=1; //多文件中,一个是声明 T const int ci=1; const int &r1=ci; // F int i=ci; //const不可强制转换为非const类型 F int &r=ci; //被引用的类型与引用类型需要一致 T int i=42; const int &r1=i; //类型不一样但是多加const没关系 const int &r3=r1*2; //const表达式返回常量 F int &r4=r1*2; //&不可以指定表达式常量 F int &r=5; //不可以引用常量 T const int &r=5; //const int &可以引用常量 float f=3.14; T const int &r=f; //const &可以类型不同,可以为常量和变量 //以上可以解释为 const int t=f; const int &r=t; T const int *p; //底层const,指向常量的指针 = int const *P; double d=3.14; //指针的类型不与其指向对象一致的例子之一 p=&d; //一个指向常量的指针指向一个非常量对象 T int i=0; int *const p=&i; //顶层const,指针本身是常量 *p=2; int A[5]={1,2,3,4,5}; const int *a=A; //const指向数组 F A[1]=3; //底层const,不允许修改,再怎么试都没用 T typedef char *pstring; const pstring cstr=0; //常量指针 顶层const const char *cstr=0; //底层const //注意const不可以简单的代换,typedef!=#define T decltype() //返回操作数数据类型 int i=42,*p=&i,&r=i; decltype(r+0) b; //int类型 F decltype(r) b; //int & 类型,未初始化 F decltype(*p) c; //int &类型,未初始化,解引用将得到引用类型 F decltype((i)) d; //int &类型,未初始化,编译器将()内的当作表达式 变量是可以作为复制语句左值的特殊表达式 F decltype(i=x) d; //赋值产生引用,是表达式,为int &,需要初始化
预处理器
当预处理器看到#include标记的时候会将指定的文件的内容替换#include
**#ifdef** 当且仅当变量已定义时为真
**#ifndef** 当且仅当变量未定义时为真
一旦检查的结果为真,则一直执行到**#endif**为止
注意:预处理器中无视c++中关于作用域的规则
## 2. 字符串,向量和数组
### 2.1 字符串
初始化字符串对象的几种方式有
```c++
string s1; //默认初始化,s1是一个空串
string s2(s1); //s2是s1的副本
string s2=s1; //s2是s1的副本
string s3("value"); //
string s3="value";
string s4(n,'c'); //初始化为n个‘c’
拷贝初始化: 使用等于号
直接初始化: 不使用等于号
string的操作
os<<s //将s写出到输出流os中,返回os
is>>s //从is中读取字符串赋给s,字符串以空白分隔,返回is
getline(is,s) //从is中读取一行赋值给s,返回is
s.empty() //s为空则为真,否则为false
s.size() //返回s中字符的个数
s[n] //返回s中第n个字符的引用,位置n从0算起
s1+s2 //返回s1+s2的结果
s1=s2 //赋值
s1==s2 //判断是否相同
s1!=s2 //等性判断,注意对大小写敏感
<,<=,>,>= //字典序判别大小
字面值与string类型相加,允许把字符字面值和字符串字面值转换成string对象
注意当这些混在一起使用的时候,必须确保每个加法运算符的两侧至少有一个是string
//注意,字符串字面值与string是不同的类型
T string s4=s1+',';
F string s5="hello"+","; //两个对象没有一个是string
T string s6=s1+","+"world"; //从左往右计算,正确
F string s7="hello"+","+s2; //错误,不能将字符值直接相加
cctype文件中有一些实用的函数来判断字符
isalpha(c) //当c是字母时为真
isdigit(c) //当c为数字时为真
islower(c) //当c是小写字母时为真
isupper(c) //当c是大写字母时为真
tolower(c) //如果c是大写字母,输出对应的小写字母,否则输出小写
toupper(c)
使用基于范围的for语句
这种语句遍历给定序列中的每个元素并对序列中的每个值执行某种操作
for(declaration : expression)
statment
exp是一个对象,用于表示一个序列,dec是一个变量,该变量用于访问序列中的基础元素,注意此操作是赋值,修改的话必须要对它采用引用的操作
亦可以采用经典的下标访问的方式来修改字符
如:
string str("hello");
for(auto c : str)
cout<<c<<endl;
//如果想要改变string对象中字符的值,必须把循环变量定义成引用类型
for(auto &c: str)
c=toupper(c);
使用string对象和c风格的字符串
//c赋值到c++都是兼容的
//c++字符串转换为c风格的字符串的使用方式如下
s.c_str();
//返回的是一个const char*类型,即为不可更改的常量
//无法保证函数返回的数组一直有效,若是后序的s更改后可能会是无效的!