C 11学习笔记 1

发布 2022-06-17 16:14:28 阅读 4924

当赋给带符号型一个超出它表示范围的值时,结果是未定义。

当赋给无符号型一个超出它范围的值,结果是初始值对无符号型表示总数取模后的余数。把-1赋给8比特(0~255)的unsigned char结果255

切勿混用带符号类型和无符号类型。

如果一个字面值连与之关联的最大的数据类型都放不下,将产生错误。

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

int i =0 ; int i = int i (0); int i; 初始化。

花括号是列表初始化。当用于内置类型的变量时,这种初始化形式有一个重要的特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编辑器将报错:

long double ld=3.1415926536;

int a,b=; 错误。

int c(ld),d=ld; /数据丢失。

如果定义内置变量类型未被显示初始化,他的值由定义位置决定:定义于任何函数之外的变量被初始化为0;定义在函数体内的内置类型将不被初始化。

如果想声明一个变量而不定义,就柱塞变量名前加extern,而且不要显示的初始化。

extern int i;//声明不定义。

int j ; 声明并定义。

extern double pi=3.14 ;/定义。

在函数内部,如果试图初始化一个由extern标记的变量,将引发错误。

标识符以字母或下划线开始,c++中标识符中不能连续出现两个下划线,也不能以下划线紧连大写字母开头。定义在函数体外的标识符不能以下划线开始。

引用一定要在定义是初始化,绑定。

因为引用不是对象,所以不能定义引用的引用。

引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

指针的值(4种):对象,指向紧邻对象所占空间的下一个位置,空指针,无效指针。

void*指针能做的事有限:和其他指针比较、作为函数的输入输出。或赋给另一个void*指针不能直接操作void*所指的对象,,不知道这个对象时什么类型。

int *&i=p;指向指针的引用(从右向左读)

利用一个对象去初始化另一个对象,则它们是不是const无关紧要:

int i = 43;

const int ci=i;

int j =ci;

如果想要在多个文件之间共享const对象,必须在变量的定义之前添加extern,来指明变量的定义在别处出现。定义时,加extern说明可以使其被其他文件使用。

extern const int bufsize=fcn();

extern const int bufsize;

对常量的引用(常量引用):

const int ci=123;

const int &r=ci;

r=24; /错。

int &r2=ci //错,试图让一个非常量引用指向一个常量对象。

引用的类型必须与所引用的对象的类型一致,但是有两个例外:

在初始化常量引用时允许用在任意表达式作为初始值,只要可转换,int i=3;

const int &r1 = i; /允许将const int&绑定到一个普通 int对象上。

const int &r2 = 34; /正确,r2是一个常量引用。

const int &r3 = r1 * 2; /正确,r3是一个常量引用。

int &r4=r1*2错,r4是一个普通的非常量引用。

在绑定应用时,double dval = 2;

const int&ri = dval;

此处将生成临时量(临时对象);

const int temp = dval;

const int &ri = temp;

对const的引用可能引用一个非const的对象。

常量引用仅是对引用可参与的操作做出了限制,对引用的对象本身并么有限定。所以可以通过其他途径改变。

const int* i;//指向常量的指针。

int*const i=j; /常量指针必须初始化。

顶层const(指针是一个const):

int i = 0;

int * const p1=&i; /不能改变p1的值,这是一个顶层const

const int ci= 42; /不能改变ci的值,这是一个顶层const

const int *p2=&ci; /允许改变p2的值,这是一个底层const

const int *const p3=p2;

const int &r = ci;//用于声明引用的const 都是底层const

i = ci;//正确,拷贝ci的值,ci是一个顶层const,对此操作无影响。

p2 = p3; /正确,p2和p3指向的对象相同,p3顶层const的部分不受影响。

int *p = p3;//错,p3包含底层const的定义,而p没有。

p2 = p3; /正确,p2和p3都是底层const

p2 = i; /正确,int*能转换成 const int *

int &r = ci; /错,普通int& 不能绑定到int常量上。

const int &r2 = i; /正确,const int& 可以绑定到一个普通 int 上。

用常量表达式初始化的const对象也是常量表达式。

constexpr声明,以便由编译器来验证变量的是否是一个常量表达式,声明为constexpr的变量一定是常量,而且必须使用常量表达式初始化。

一般来说,如果你认定变量是一个常量表达式,那就把它声明成constexpr类型。

常量表达式的值要在编译时计算,字面值类型,比较简单。

一个constexpr指针的初始值必须是nullptr或0,或是存储于某个固定地址中的对象。

函数体内定义的变量一般不是存放在固定地址中,不能用constexpr指针。

而在所有函数体之外的对象其地址不变,能用来初始化constexpr指针。

还有允许函数定义一类有效范围超出函数本身的变量,这类变量也有固定的地址。

constexpr引用也能绑定到这类变量上。

constexpr限定符仅对指针有效,与指针的对象无关:

constexpr int* q=nullptr; /q是一个指向整数的常量指针。

constexpr const int *p = i;//p是常量指针,指向整型常量。

别名声明。typedef double wages;

using si=int;

将表达式赋值给变量时,无法知道表达式类型,可以用auto,编译器会自己推算。

使用auto时如果一条一句中声明两个变量,俩个类型必须一样。

对于引用类型,auto出的是被引用的对象。

auto 一般不会保留顶层const,底层的会保留底层const

int i=0;

const int ci = i, &cr = ci;

auto b=ci; /b是一个整数。

auto c=cr;//c是一个整数,对于引用类型,auto出的是被引用的对象。

auto d=&i;//d是一个整型指针。

auto e=&cr;//e是一个指向整数常量的指针,对常量取地址是一种底层const

如果希望auto出的是顶层const就要明确指出。

const auto f = ci;//f是const int

也可以为引用设置auto

auto &g = ci;//g是一个整型常量引用。

auto &h = 42;//错,不可以为非常量引用绑定字母值。

const auto & j = 42; /正确,可以为常量引用绑定字面值。

设置一个类型为auto的引用时,初始值中的顶层const会保留。如果我们给初始值绑定一个引用,则常量就不是顶层常量了?

对于一条语句定义多个变量,切记,*和&只从属于某个声明符。

decltype ,选择并返回操数的类型。只分析其类型,不计算。

特别注意引用从来都作为其所引用对象的同义词出现,但decltype是个例外。

decltype((i))双层括号,的结果永远是引用,而decltype(i)的结果只有当i本身是引用时才是引用。

预处理变量无视c++语言总关于作用域的规则。

C11学习笔记 5

参数传递时,如果是引用类型,它将绑定到对应的实参上,否者,将实参的值拷贝后赋给形参。引用可避免拷贝,如果不需要改变参数,最好定义成常量引用。和其他初始化一样,当用实参初始化时会忽略顶层const,当形参有顶层const时,传给它常量对象或非常量对象都可以。我们可以用非常量初始化一个底层const对象...

C 11学习笔记 11

动态分配的内存,只有在显式释放是,这些对象才会销毁。但是标准库中的两智能指针可以确保自动释放。除了静态内存和栈内存,每个程序还拥有一个内存池。这部分内存被称作自由空间或堆。静态内存用来保存局部static对象 类static数据成员以及定义在任何函数之外的变量。栈内存用来保存定义在函数没得非stat...

C 11学习笔记 16

tuple是类型pair的模板。不同tuple类型的成员类型也不同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的。当我们希望将一些数据组合成单一对象,但有不想麻烦地定义一个新数据结构来表示时,tuple是非常有用的。快速而随意 的数据结构 tuple类型及其伴随类...