深圳南山做网站,网站安全 扫描,海宁高端高端网站设计,如何外贸网络推广const的基本概念
const名叫常量限定符#xff0c;用来限定特定变量#xff0c;以通知编译器该变量是不可修改的。
习惯性的使用const#xff0c;可以避免在函数中对某些不应修改的变量造成可能的改动。
const修饰基本数据类型
2.1 const修饰一般常量及数组
int const a… const的基本概念
const名叫常量限定符用来限定特定变量以通知编译器该变量是不可修改的。
习惯性的使用const可以避免在函数中对某些不应修改的变量造成可能的改动。
const修饰基本数据类型
2.1 const修饰一般常量及数组
int const a 100;
const int a 100; //与上面等价
int const arr [3] {1,2,3};
const int arr [3] {1,2,3};//与上面等价
对于这些基本的数据类型修饰符const可以用在类型说明符前也可以用在类型说明符后其结果是一样的。
2.2 const修饰指针(*)
主要有以下几种类型
char *p hello; // 非const指针,// 非const数据const char *p hello; // 非const指针,// const数据char * const p hello; // const指针,// 非const数据const char * const p hello; // const指针,// const数据 2.2.1 常量指针
当为常量指针时不可以通过修改所指向的变量的值但是指针可以指向别的变量。
int a 5;
const int *p a;
*p 20; //error 不可以通过修改所指向的变量的值int b 20;
p b; //right 指针可以指向别的变量 2.2.2 指向常量的指针(指针常量)
当为指针常量时指针常量的值不可以修改就是不能指向别的变量但是可以通过指针修改它所指向的变量的值。
int a 5;
int *const p a;
*p 20; //right 可以修改所指向变量的值int b 10;
p b; //error 不可以指向别的变量 2.2.3 总结
如果const位于星号*的左侧则const就是用来修饰指针所指向的变量即指针指向为常量
如果const位于星号*的右侧const就是修饰指针本身即指针本身是常量。
2.2.4具体举例 代码如下
#includestdio.h
int main()
{int a 10, b 20;int* p1 a; //可以修改值 也可以修改方向*p1 100;p1 b;const int* p2 a; //指向//int x2*p2;//*P2100;//error//p2b;int const* p3 a;//const 在指针前 修饰指向方向可以读取值 自身值可以改变int* const p4 a;//int x*p4;// *p4100;//p4b;//error//const 在指针后 修饰值本身 p4的值不可以改变 但是后面修饰的值可以const int* const p5 a;//指针前有指针后也有 均不可以改变return 0;
} const修饰函数 const 在函数中根据修饰的位置分为三种函数参数、函数返回值、成员函数。
const int fun (const int a) const; 3.1 const修饰函数参数
修饰函数形参;函数体内不能修改形参a的值。
如果函数作为输出用不论是什么数据类型也不论采用指针传递还是引用传递都不能加const 修饰否则参数会失去输出功能。
所以const 只能修饰输入作用的参数
3.1.1 如果参数为指针
如果输入参数为指针加上const之后就会起保护指针意外修改的作用。
void StringCopy(char* strDest, const char* strSource);
在这个函数定义中我们的的参数strsource加上const修饰就是为了防止strsource被修改。
可以起到保护作用的原因是实参中指针会指向一段内存地址调用函数之后函数会产生一个临时指针变量这个变量的地址与实参的地址不一样但是这两个指针指向的内存是同一块。形参加上const 修饰之后保护了这一块内存地址不被修改如果刻意修改这一块内存编译器会报错。
3.1.2 如果参数为引用
如果输入参数为引用加上const 之后既起到了保护作用也提高了程序效率。
void func(Y y);//这里的Y类型为用户定义的类型
void func(Y y);//采用引用的方式
调用这个函数我们会产生一个临时对象随后调用拷贝构造函数当函数结束的时候进行析构释放资源。
如果改成引用void func(A a); 只是相当于实参的一个别名不会产生临时变量。
所以如果是自定义类型建议用引用作为函数形参。
3.2 const修饰函数返回值 修饰返回值就是不能修改返回值
3.2.1 值传递
如果是值传递没有必要将返回值用const修饰
const int func(); 对于函数来说它的返回值为一个int类型的值是一个临时的值没有必要用const修饰。
3.2.2 返回值为指针
如果返回值为指针加上const修饰后同样的内容是不可以修改的。
这个时候我们接收的变量也必须是const修饰
const char* func();
char* str func();// error
const char* str func(); //right 3.2.3 返回值为引用
如果返回值为引用也可以提高效率。但是一般返回引用的地方并不是很多一般会出现在类的赋值函数中。而且用const 修饰返回值为引用类型的更少。一般来说不常用。
3.3 const修饰成员函数 const 修饰的成员函数为了保护成员变量要求const 函数不能修改成员变量否则编译会报错。 函数体内不能修改成员变量的值增加程序的健壮性或鲁棒性。只有成员函数才可以在后面加const普通函数后加const无意义。
class MyClass {
public:void func(int x) const;
}; const函数的规则 const 对象只能访问const 成员函数非const 的对象可以访问任何成员函数包括const 成员函数。如果函数名、参数、返回值都相同的const成员函数和非const成员函数是可以构成重载那么const对象调用const成员函数非const对象默认调用非const的成员函数。const成员函数可以访问所有成员变量但是只能访问const的成员函数。非const成员函数可以访问任何成员包括const成员成员函数。const成员函数不能修改任何的成员变量除非变量用mutable修饰。
类中定义变量(const的特殊用法) 在类中实现常量的定义大致有这么几种方式实现使用枚举类型使用const或static
4.1使用枚举类型
class test
{enum { a 10, b 20}; // 枚举常量int array1[a]; int array2[b];
}; 4.2 使用const或static C11仅不允许在类声明中初始化static非const类型的数据成员。
// using c11 standard
class CTest11
{
public:static const int a 3; // Ok in C11static int b 4; // Errorconst int c 5; // Ok in C11int d 6; // Ok in C11
public:CTest11() :c(0) { } // Ok in C11
};int main()
{CTest11 testObj;cout testObj.a testObj.b testObj.c testObj.d endl;return 0;
} 4.3 总结 在不同的标准下 是略微有所不同的
对于static const 类型的成员变量不管是旧的C标准还是C11都是支持在定义时初始化的。对于static 非const类型的成员变量C03和C11的标准都是不支持在定义时初始化的。对于const 非static类型的成员变量C03要求必须在构造函数的初始化列表中来初始化而C11的标准支持这种写法同时允许在定义时进行初始化操作。对于非static 非const成员变量C03标准不允许在成员变量定义时初始化但是C11标准允许在类的定义时对这些非静态变量进行初始化。对于static非const成员变量的初始化方式并未改变就是在相应的cpp文件中写成int CTest11::b 5即可注意要在类定义之后。
五 使用const的好处 可以定义const常量
这样可以避免由于无意间修改数据而导致的编程错误提供了一个保护作用。
便于进行类型检查
const常量有数据类型而宏常量没有数据类型。编译器可以对前者进行类型安全检查而对后者只进行字符替换没有类型安全检查并且在字符替换时可能会产生意料不到的错误。
为函数重载提供了一个参考
const修饰的函数可以看作是对同名函数的重载。
可以节省空间避免不必要的内存分配
const定义常量从汇编的角度来看只是给出了对应的内存地址而不是象宏一样给出的是立即数所以const定义的常量在程序运行过程中只有一份拷贝而宏定义的常量在内存中有若干个拷贝。
提高了效率
编译器通常不为普通const常量分配存储空间而是将它们保存在符号表中这使得它成为一个编译期的常量没有了存储与读内存的操作使得它的效率也很高。 const在C和C中的区别
在C语言中用const修饰的变量其本质上还是个变量只是它不允许作为左值存在也就是不法对该变量进行直接赋值修改该变量但是这不意味着该变量的值就无法修改。
在C中 在编译的时候当碰到用const修饰的变量时编译器是直接将变量的值和变量的符号对应起来一起存到符号表。
例如const int a 5;在符号表中就会将a和5对应起来在编译的过程中当碰到printf(“a %d\n”,a); 时用 5 直接将 a 替换掉。在C中编译器不会为a分配存储空间在C语言中就会为a分配存储空间所以在C编译器中就可以通过指针来改变用const修饰的变量。
其实在C中const修饰的变量在编译的时候如果前面有extern和取地址符 时会为变量分配存储空间是为了兼容C语言但是在C中用const修饰的变量就真的无法修改它的值可以说是常量。
但是在C语言中const修饰的变量本质上还是变量而不是常量。
这在C语言中其实也是矛盾的因为我们想要用const定义一个常量但又可以通过指针来改变该常量的值。
而C为了兼容C语言所以保留了这个特性但是却无法修改它的值这就是const在C语言和C中的区别。