微信网站制作教程,前端开发可以做网站赚钱吗,怎么做网站浏览量分析,安卓 开发const限定符
const对象一旦创建后其数值就不会被再次改变#xff0c;因此const对象必须初始化。const对象只在文件中有效在不同的文件中使用不同的const来定义不同的常量#xff0c;那么每个文件定义的变量只会在自己所属的文件中有效。如果想让多个文件共享同一个const变量… const限定符
const对象一旦创建后其数值就不会被再次改变因此const对象必须初始化。const对象只在文件中有效在不同的文件中使用不同的const来定义不同的常量那么每个文件定义的变量只会在自己所属的文件中有效。如果想让多个文件共享同一个const变量那么使用关键字extern即可
const的引用
把引用绑定到const对象上就像绑定到其他对象上一样称之为对于常量的引用。和普通信用不同对于常量的引用不能被用于修改它所绑定的对象。
const int ci 1024;
const int r1 ci;//正确引用及其对应的对象都是常量
r1 42 //错误r1是对于常量的引用
int r2 ci //错误试图让一个非常量去引用一个常量对象
因为不允许直接为ci赋值当然也不可以通过引用去改变ci因此对于r2的初始化是错误的假设初始化合法就可以通过r2来改变他引用的对象的数值这显然是不正确的。
初始化和对const的引用 引用的类型必须和其所引用对象的类型是一致的但是有两个例外。1初始化常量引用时候允许用任意表达式来作为初始化的数值只要该表达式结果可以转化为引用的类型即可。尤其允许一个常量引用绑定非常量的对象、字面值甚至是一个一般表达式。 int i 42;const int r1 i; //允许将const int 绑定到一个普通int对象上const int r2 42;//r2是一个常量的引用const int r3 r1 * 2;//r3是一个常量的引用int r4 r1 * 2; //错误r4是一个普通的非常量的引用
对const引用可能引用一个并非const的对象 常量的引用仅仅对于可以引用可以参与的操作进行了限定对于引用的对象的本身是不是一个常量未做限定。因为对象也可能是一个非常量所以可以通过其他途径来改变它的值。 int i 42;int r1 i; //引用r1绑定对象iconst int r2 i;//r2也绑定对象i但是不允许通过r2来修改i的数值r1 0; //r1并非常量i的数值修改为0r2 0; //错误r2是一个常量的引用因此不可以修改引用的元素的数值指针和const
与引用一样可以另指针指向常量或者非常量。类似于常量的引用指向常量的指针不能用于改变其所指对象的数值要想存放常量对象的地址只能指向常量的指针。const double pi 3.141592653; //pi是个常量它的值不能改变double *ptr pi; //错误ptr是一个普通的指针const double *cptr pi; //正确cptr可以指向一个双精度的常量*cptr 43;//错误不能给*cptr赋值
指针的类型必须和所指对象类型一致但是有两个例外1允许令一个指向常量的指针指向一个非常量的对象。
double dval 3.14;//dval是一个双精度的浮点数它的数值可以改变
cptr dval; //正确但是不能通过cptr来改变dval的数值
const指针 指针是对象而引用不是因此就像其他对象类型一样允许把指针本身定位常量。常量指针必须初始化而且一旦初始化它的值存放在指针中的那个地址就不可以再改变了。 把*放在const关键字之前用来说明指针是一个常量即不变的是指指针本身的数值而不是指向的那个值 int errNum 0;int *const curErr errNum; //curErr一直指向errNumconst double pi 3.14158;const double *const pip pi; //pip是一个指向常量对象的常量指针遵循从右往左读的思想离curErr最近的符号是const意味着curErr本身是一个常量对象对象的类型由声明符的其余部分决定。声明符的下一个符号是*意思是curErr是一个常量指针。同理pip是一个常量指针指向的对象是一个双精度浮点类型的常量。指针本身是一个常量并不意味着不能通过指针修改其所指向的数值能否这样做完全依赖于所指向的对象的类型。例如如果pip是一个指向常量的常量指针不论是pip所指的对象值还是pip自己存储的那个地址都不能改变。如果curErr指向的是一个一般的非常量整数那么完全可以用curErr来修改errNum的数值。
顶层const
指针本身是一个对象它又可以指向另外一个对象因此指针本身是不是常量以及指针所指的是不是一个常量是两个相互独立的问题。用名词顶层const表示指针本身是一个常量而使用名词底层const来表示指针所指的对象是一个常量。顶层的const可以表示任意的对象是常量这一点适用于任何数据类型如算数类型、类、指针等。底层const则与指针和引用等符合类型的基本类型部分相关。比较特殊的是指针类型既可以是顶层const也可以是底层const这一点和其他类型相比区别比较明显。int i 0;int *const p1 i; //不可以改变p1的数值这是一个顶层的constconst int ci 42; //不可以改变ci的数值这是一个顶层的constconst int *p2 ci; //可以改变p2的数值这是一个底层的constconst int *const p3 p2; //靠右边的是顶层const靠左边的是底层的constconst int r ci; //用于声明的const都是底层const
底层const限制不可以忽视。执行对象的拷贝操作的时候拷入和烤出的对象具有相同的底层const资格或者两个对象的数据类型之间能够相互转化一般来说非常量可以转化为常量反之不可以。
constexper和常量表达式
常量表达式是指不会改变并且在编译的过程中能得到编译结果的表达式。显然字面值属于常量表达式用常量表达式初始化的const对象也是常量表达式。一个对象或者表达式是不是常量表达式是由它的数据类型和初始值共同决定的。const int max_files 20; //max_files是常量表达式const int limit max_files 1; //limit是常量表达式int staff_size 27;//staff_size不是常量表达式const int sz get_size();//sz不是常量表达式
staff_size的初始值是一个字面值常量但是由于他的数据类型只是一个普通的int而不是const int所以他不属于常量表达式。sz本身是一个常量但是他的具体值直到运行的时候才可以获取到因此也不是常量表达式。
constexpr变量
C11允许将变量声明为constexpr类型从而使得编译器来验证变量的数值是否是一个常量的表达式。声明为constexpr的变量一定是一个常量而且需要用常量表达式来初始化。constexpr int mf 20; //20是常量表达式constexpr int limit mf 1 ;// limit是常量表达式constexpr int sz size();// 只有当size是一个constexpr函数的时候才是一条正确的声明语句字面值类型
常量表达式的值需要在编译的时候就得到计算因此对声明constexpr时用到的类型必须有所限制。因为这些类型一般比较简单值也比较明显将其称之为字面值类型。算数类型、引用和指针都是属于字面值类型。自定义的类型、IO库、string则不属于字面值类型即不可以定义为constexpr。指针和引用可以被定义为constexpr类型但是他们的初始值会受到严格的限制constexpr指针的初始值必须是nullptr或者是0或者是存储于某个固定地址中的对象。先前指出函数体内部定义的变量一般来说不会存在到固定的地址中因此constexpr指针不可以指向这种变量。相反因为存储于函数体外的对象其固定的地址不变因此可以用于初始化constexpr指针。其中允许函数定义一类有效范围超出函数本身的变量这类变量和定义在函数体之外的变量一样也有固定的地址因此也可以用于对于constexpr指针的初始化。
指针和constexpr
在constexpr声明中定义了一个指针限定符号constexpr仅仅对于指针有效而对于指针所指向的对象本身无效。const int *p nullptr;//p是一个指向整型常量的指针constexpr int *q nullptr;//q是一个指向整数的常量指针与其他常量指针相类似constexpr指针既可以指向一个常量指针也可以指向一个非常量
const int *np nullptr;//np是一个指向整数的常量指针其值为空
int j 0;
constexpr int i 42;//i的类型是整型常量
//i和j必须定义在函数体之外constexpr const int *p i;//p是常量指针指向整型常量iconstexpr int *p1 j;