day1:
- 注释:
//单行注释忽略所有内容
/**/中间不能嵌套
/*碰见*/就会结束
/*sdadasd/**/这一句就不会被注释*/
字符型会分为char 、signed char、unsigned cahr三种,其实只会表现为有符号和无符号两种,char是会表现为其他两种中的一种,但是具体表现为哪一种,根据编译器决定。
day2:
赋值给无符号类型超出范围的数,会对整数取模,比如。8bit的unsigned char 可以表示范围为0-255,赋值257的时候会取257%256=1
赋值给有符号类型超出范围的数,结果是未定义的,什么都有可能。
赋值给无符号类型超出范围的数,会对整数取模,比如。8bit的unsigned char 可以表示范围为0-255,赋值257的时候会取257%256=1
赋值给有符号类型超出范围的数,结果是未定义的,什么都有可能。
一个字符串太长可以这样输出:
std::cout<< “a really, really long string literal”
“that spans two lines”<< std::endl;
有符号和无符号计算,结果转换成无符号;无符号结果为负数,会取模
虽然有时候创建变量用=号进行初始化,但初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。
声明如果赋值了就变成了定义,
变量只能被定义一次,但是可以声明多次。
extern in i;//声明i
int j;//定义j
extern int a=0;//定义a
day3:
-
引用
引用必须初始化,引用的初始值必须是一个对象,不能是表达式或者字面值(比如返回函数int但是结果是int &a=func(),这就不行,必须确定:例如全区变量,并且函数返回值是int &)。 -
指针
不能直接操作void指针所指的对象,应为不知道是什么类型,但是可以以转换乘任何类型的指针
创建两个指针时候 int *p1,*p2; int *p1,p2是一个int 指针和一个int -
不管是指针还是变量或者其它标识符,从右往左看,离变量名最近的优先,利于弄清楚定义的真是含义
-
const
- const对象也必须初始化
- 利用一个对象A去初始化另外以一个对象时,A是不是const都无所谓,因为就相当于一个拷贝工作。
-
double i=0.222;
const int &j=i;
//上面的是可行的,类似于下面的过程
const int tmp = i; //生成临时变量
const int &j = tmp; //绑定临时变量
当发生类型转化的时候,都会产生一个临时变量(传值返回也是),临时变量具有常性,不能修改,这就导致j在引用i的时候并不是引用i本身,而是i的临时变量,所以要加上const。
对const的引用可能引用一个并非const的对象
int a=10,b=20;
const int* p1=&a;//可以修改p1,但是不能修改*p1,const修饰的*p1
int * const p2=&a;//const修饰的是p2的指向能力,
//所以可以通过解引用来修改值,但是不能让p2重新指向其他地址。
const int * const p3=&a;
- 顶层const和底层const(都是在是指针的情况下)
顶层const修饰的是*,表示对象本身是常量,指针本身不能变,但它指向的内容可以改变。比如说int * const p,可以改变 * p,但不能改变p本身。
底层const修饰的是类型,表示指针/引用所指的对象是常量,指针可以改,它变量本身不能改变,比如说const int* p,p是可以改变的,但是p所指向的内容*p不能改变。 - 引用+const
//赋值的时候其实可以从权限角度考虑
int a = 0;
// 权限平移
int& ra = a;
// 指针和引用赋值中,权限可以缩小,但是不能放大
const int b = 1;
// rb引用b,b只有可读权限,rb可读可写,权限放大,不允许
//int& rb = b;
// 权限平移
const int& rb = b;
// rra引用a,权限缩小了,允许
const int& rra = a;
//函数传参同理
//修改前
//void Count(int& s)
//{
//}
//修改后
void Count(const int& s)
{
}
int main{
//...上述代码
Count(a);//可以
Count(b);//不可以,传参时候b的权限扩大了
Count(rra);//不可以,同上
}
//函数形参为const的好处
1. 当实参的类型比较大时,复制开销很大(形参初始化时),引用会“避免复制”。(这在传递类对象时比较常用)
2. “避免修改实参”,当使用引用时,如果调用者希望只使用实参并不修改实参,则const可以避免使用该引用修改实参
3. 相比非const引用形参,更具实用性:形参可以使用const对象初始化,可使用字面值或右值表达式的实参来初始化
1. void search( const vector< int > & vec) 避免了实参的复制开销
2. 同a例,可避免对实参做出修改
3. 如下函数,调用时
void search(string & s);
search( "hello" ); // Error 实参为字面值常量
void search(const string & s);
search("hello"); // OK
//再如
void search( int & v);
search(v1+v2); // Error 实参是一个右值,无法给引用赋值(需要左值)
void search( const int & v);
search(v1+v2); // OK
- const+指针
int a = 10;
const int * p1 = &a;//p1不是常量 *p1是常量
int const * p2 = &a;//p2不是常量 *p2是常量
int * const p3 = &a;//p3是常量 *p3不是常量
const int * const p4 = &a;//p4、 *p4是常量
int const * const p5 = &a;//p5、 *p5是常量
day4:
-
constexpr类型,即常量类型。给编译器识别的,在编译时候就能验证变量是否为常量
eg:constexpr int a=0; -
类型别名
-typedef double wages;//wages是double的别名
-使用using也行using SI=double//SI是double的别名
-这里要注意,
typedef char *pstring;
const pstring cstr=0; //cstr是指向char的常量指针
const pstring *ps;//ps是一个指针,指向的对象是指向char的常量指针
虽然类似于const char *cstr=0,这是是一个指向char常量的普通指针,但是不一样。这里使用别名后,char *和pstring是一个整体,直接就是一个char指针,const就是就是修饰的指针。 -
auto
-auto定义的变量必须有初始值,并且auto i=0,j=1;是可以的,因为i和j属于同一类型。auto i=0,j=1.1313;则不行,i和j不属于同一类型。
-auto一般会忽略掉顶层指针,保留底层,即一般初始化时,结果是指向常量的指针,不会是指针常量, -
decltype
decltype(f()) sum;//定义变量sum,sum的类型有f()的返回值类型决定
const in ci=0,&cj=ci;
decltype(ci) x=0;//x的类型是const int
decltype(cj) y=x;//y的类型是const int &,y绑定到x
decltype(cj) z;//错误,引用必须初始化
int i=0;
decltype(i) x;//x的类型是int
decltype((i)) y;//错误,y的类型是 int&必须初始化
decltype((variable))的结果永远是引用
day5:待更新
- 引用
- 啥都
- 啥都